利用定时器进行串口不定长数据接收

1.在cube中将USAR的波特率设置为9600,打开定时器x,设置定时器x时钟来源为内部时钟(Internal Clock),设置PSC为8000-1

2.在main函数中使能定时器x和uart( HAL_TIM_Base_Start(&htimx);(HAL_UART_Receive_IT(&huart1,&rec_data,1) ) )

用户代码中HAL_UART_Receive_IT在MX_USART1_UART_Init之前被调用,这可能导致UART模块尚未初始化完成就开始接收,导致错误

3.设一系列接收和发送数据相关变量

( char send_buff[20];//用于存储要发送的串口数据

uint8_t rec_data;//存储从UART接收到的一个字节数据(需要设置全局变量)

uint8_t count; //用来记录接收到的数据字节数量

uint8_t rec_flag;//接收到数据标志位

uint8_t rec_buff[20]; //用于存储接收到的字节数据)

4.调用中断回调函数接收数据

( void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){

if(huart->Instance==USART1){

TIM4->CNT=0;//重置定时器,判断接收过程中的超时(超过一定时间表示数据接收完毕)

rec_flag=1;//标志位被设置,表示接收到了数据,可以处理数据

rec_buff[count]=rec_data;// 存储接收到的数据

count++;// 数据接收计数加1

HAL_UART_Receive_IT(huart,&rec_data,1);// 重新开启UART接收中断

}

} )

5.编写判断是否接受正确并且发送数据函数

( void uart_data_rec( ){

if(rec_flag){// 如果接收到数据

if(TIM4->CNT>15){// 如果定时器计数大于15,表示接收完成

if(rec_buff[0]=='l'&&rec_buff[1]=='a'&&rec_buff[2]=='n'){

sprintf(send_buff,"lan\r\n");

HAL_UART_Transmit(&huart1,(uint8_t*)send_buff,sizeof(sendbuff),50);

}

else if(rec_buff[0]=='q'&&rec_buff[1]=='i'&&rec_buff[2]=='a'&&rec_buff[3]=='o'){

sprintf(send_buff,"qiao\r\n");

HAL_UART_Transmit(&huart1,(uint8_t*)send_buff,sizeof(sendbuff),50);

}

else if(rec_buff[0]=='b'&&rec_buff[1]=='e'&&rec_buff[2]=='i'){

sprintf(send_buff,"bei\r\n");

HAL_UART_Transmit(&huart1,(uint8_t*)send_buff,sizeof(sendbuff),50);

}

else{

sprintf(send_buff,"error\r\n");

HAL_UART_Transmit(&huart1,(uint8_t*)send_buff,sizeof(sendbuff),50);

}

rec_flag=0;// 处理完数据后,重置标志位

for(int i=0;i<count;i++){// 清空接收到的缓存

rec_buff[i]=0

}

count=0;// 重置接收到的字节数

}

}

} )

6.在.h文件中声明函数,并且在main函数的循环中调用该函数

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐