附上我的工程链接
链接:https://pan.baidu.com/s/1-WNduviH-wgYQeL-dgM4wA?pwd=f0uh
提取码:f0uh
2024.1.30补充:如果有判断非法字符的话,那么只能接收一个字符
且
if (rx_pointer > 0) {
HAL_Delay(10);
if (rx_pointer == 2) {
}
rx_pointer = 0;
memset(rxdata,0,20);
这里的HAL_Delay非常重要;
2024,1,26 补充:下文是发送一个字符,一个一个判断,但是串口发送快的时候,会出现错误。
因此,我改变了具体要接收的数据位数为7:如下
HAL_UART_Receive_IT(&huart1,rxdat,7);
在main函数里插入这一条代码,7表示接收的位数。
同时,将rxdat由uint8_t rxdat 改为uint8-t rxdat[10]
char rxdata[30];
uint8_t rxdat[10];
unsigned char rx_pointer;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
for(int i=0;i<7;i++){
rx_pointer++;
rxdata[i] = rxdat[i];
}
HAL_UART_Receive_IT(&huart1,rxdat,7);
}
还有将里面的rxdata[rx_pointer++] = radat改为了
for(int i=0;i<7;i++){
rx_pointer++;
rxdata[i] = rxdat[i];
}
这样子,一接收到数据,就会把rx_pointer➕为7,那么这个回调函数写完了。我的调用串口接收数据修改如下:
if (rx_pointer>0){
HAL_Delay(1);
if (rx_pointer == 7){
HAL_UART_Transmit(&huart1,(uint8_t *)"yes\r\n",sizeof("yes "),100);
}
else
HAL_UART_Transmit(&huart1,(uint8_t *)"Error\r\n",sizeof("Error "),100);
}
rx_pointer = 0;
我这里将memset删除了,因为每次接收到数据,数据会把rx_pointer重新置为0,覆盖之前的数据,这样子,就可以读取radata里面的数据了,这样子接收的再快,不容易出现错误,比起之前接收一位,然后不停判断好多了。
正文:
1. 配置stm32cubemx
1.1rcc时钟配置
1.2 下载器配置
1.3 USART1配置
1.3 时钟树配置
要选择外部晶振的话,切记一定要是24Mhz的晶振,要不然串口打印的时候会乱码!!!
1.4 其他项配置
配置完电机generate code,之后打开keil工程。
2. keil代码
2.1 首先找到stm32g4xx_it.c,在最后面编写
char rxdata[30];
uint8_t rxdat;
unsigned char rx_pointer;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *hurat){
rxdata[rx_pointer++] = rxdat;
HAL_UART_Receive_IT(&huart1,&rxdat,1);
}
2.2 在main函数里声明外部变量
这里的car_xxxx是存放我们串口一次性要发送的数据
uint8_t ucLcd[21];
char car_type[5];
char car_data[5];
char car_time[13];
extern char rxdata[30];
extern uint8_t rxdat;
extern unsigned char rx_pointer;
2.3 定义一个函数
这个函数是接收函数。
void UART_Receice_Proc(void){
if (rx_pointer > 0){
HAL_Delay(10); //延时一会,而且NVIC里的basetim优先级要设置高一点
if (rx_pointer == 6){
sscanf(rxdata,"%2s:%1s:%1s",car_type,car_data,car_time);
printf("yes");
}
else{
HAL_UART_Transmit(&htim1,(uint8_t *)"Error\r\n",sizeof("Error\r\n"),50);
}
}
rx_pointer = 0;
memset(rxdata,0,30);
}
2.4 在while(1)中调用你这个函数、
这些判断是为了更加精确的判断是否接收到了数据,最好加上,因为我没这些代码的时候,串口接受十分的不灵敏。估计是串口接收的太快,毕竟是异步通信,没有统一的时序。
if(rx_pointer > 0)
{
int temp = rx_pointer;
HAL_Delay(1);
if(temp == rx_pointer)
UART_Receice_Proc();
}
2.5 开启中断
之后配置好后,你也可以配置lcd显示在屏幕上,但是注意一点,LCD初始化一定要在一大堆的初始化后面。要不然会出现接受不到的现象。
HAL_UART_Receive_IT(&huart1,&rxdat,1);
3. 效果