解决方法:开启中断之前,先清除标志位【1】。
串口清除标志位:
__HAL_UART_CLEAR_PEFLAG(&huart1);
HAL_UART_Receive_IT(&huart1,&RxUart, 1);
定时器清除标志位:
__HAL_TIM_CLEAR_FLAG(&htim3,TIM_FLAG_UPDATE);
HAL_TIM_Base_Start_IT(&htim3);
1、问题描述
编程任务:STM32串口接收上位机不定长数组
思路:使用串口中断接收数据,每接收完一个字节就把计时器清零;计时器每65ms进一次中断,如果计时器进中断说明一帧数据结束了【2】。
1.1、MAIN函数
uint8_t RxData[60]={0},RxUart=0;
uint8_t FLAG_RX_DONE=0;//Serial port receive complete flag, no new data received within 65.5ms(TIM3), this flag will be set
uint8_t RX_DATA_idx=0,RX_DATA_LEN=0;
int main(void)
{
uint8_t projectName[]="a1223_protocol";
uint8_t i=0;
printf("****** %s ******\r\n\r\n",projectName);
HAL_UART_Receive_IT(&huart1,&RxUart, 1);//开启接受中断
while (1)
{
if(FLAG_RX_DONE!=0)//如果接收完成
{
FLAG_RX_DONE=0;
printf("RX_DATA_LEN=%d\r\n",RX_DATA_LEN);
RX_DATA_LEN=0;
printf("RX=");
for(i=0;i<RX_DATA_LEN;i++)
{
printf("%02X ",RxData[i]);
}
printf("\r\n");
memset(RxData,0,sizeof(RxData));//清除接收寄存器
}
HAL_Delay(1000);
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
}
1.2、串口接收中断处理程序
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART1)
{
__HAL_TIM_SET_COUNTER(&htim3,0);//定时器清零
if(RX_DATA_idx==0)//If it is the first character, the timer is started
{
HAL_TIM_Base_Start_IT(&htim3);//开启定时器
}
RxData[RX_DATA_idx++]=RxUart;
HAL_UART_Receive_IT(&huart1,&RxUart,1);//开启接收中断,准备接收下一个字节
}
}
1.3、计时器中断处理程序
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM3)
{
//If no new data is received for 65.5ms, the reception is over
RX_DATA_LEN=RX_DATA_idx;
FLAG_RX_DONE=1;
RX_DATA_idx=0;//Start writing data again
HAL_TIM_Base_Stop_IT(&htim3);//接收完成,关闭定时器中断
}
}
1.4、实验结果
可以看到第一次接收的数据中缺少“01”。
2、解决方法
在开启中断之前,先清除标志位
2.1、串口的处理方法
HAL_UART_Receive_IT(&huart1,&RxUart, 1);
修改成
__HAL_UART_CLEAR_PEFLAG(&huart1);
HAL_UART_Receive_IT(&huart1,&RxUart, 1);
2.2、定时器的处理方法
HAL_TIM_Base_Start_IT(&htim3);
修改成
__HAL_TIM_CLEAR_FLAG(&htim3,TIM_FLAG_UPDATE);
HAL_TIM_Base_Start_IT(&htim3);
2.3、实验结果
3、参考资料
【1】STM32串口第一字节消失或者误码的原因和解决方案_stm32单片机串口通讯 接收的字节错误-CSDN博客https://blog.csdn.net/Backspace110/article/details/52737441
【2】HAL库教程9:串口接收不定长数据_hal库接收串口不定长数据-CSDN博客https://blog.csdn.net/geek_monkey/article/details/89326199