STM32单片机串口中断接收异常处理——上电首帧数据为0x00的解决策略
uint8_t USART1_NewData; //当前串口中断接收的1个字节数据的缓存
HAL_UART_Receive_IT(&huart1, (uint8_t*) &USART1_NewData, 1);
//这里的USART1_NewData 要与接收中断中的一致,不然就会上电第一位收到是0x00
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //串口中断回调函数
{
if (huart == &huart1) //判断中断来源(串口1:USB转串口)
{
// printf("%c", USART1_NewData); //把收到的数据以 a符号变量 发送回电脑
if ((USART1_RX_STA & 0x8000) == 0)
{ //接收未完成
if (USART1_RX_STA & 0x4000)
{ //接收到了0x0d
if (USART1_NewData != 0x0a)
USART1_RX_STA = 0; //接收错误,重新开始
else
USART1_RX_STA |= 0x8000; //接收完成了
}
else
{ //还没收到0X0D
if (USART1_NewData == 0x0d)
USART1_RX_STA |= 0x4000;
else
{
USART1_RX_BUF[USART1_RX_STA & 0X3FFF] = USART1_NewData; //将收到的数据放入数组
USART1_RX_STA++; //数据长度计数加1
if (USART1_RX_STA > (USART1_REC_LEN - 1))
USART1_RX_STA = 0; //接收数据错误,重新开始接收
}
}
}
if ((USART1_RX_STA & 0x8000))
{
if ((USART1_RX_STA & 0x4000))
{
uint16_t mask = (uint16_t) ~(3 << 14); // 创建掩码,将最高2位清零 3: 0011/ 0011 1111 1111 1111 =0x03ff
uint16_t result = USART1_RX_STA & mask; // 使用位与操作去掉高2位
printf("%d\r\n", result);
HAL_UART_Transmit(&huart1, (uint8_t*) &USART1_RX_BUF, result, 100);
USART1_RX_STA = 0;
memset(USART1_RX_BUF, 0, sizeof(USART1_RX_BUF));
// HAL_UART_Transmit(&huart1, (uint8_t*) &USART1_RX_BUF, result, 100);
}
}
HAL_UART_Receive_IT(&huart1, (uint8_t*) &USART1_NewData, 1); //再开启接收中断
}
}
如果初始化打开中断的时候设置的缓冲区与串口接收中设置的缓冲区不是同一个,则会出现上电(初始化)接收到第一个字节为0x00,但是之后都正常的情况
参考文章地址:STM32单片机串口中断接收,上电第一帧数据为0x00的问题解决_stm32串口上电自动发00-CSDN博客
作者:灯琰1