尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

STM32CubeMX+HAL库+USART接收不定长数据(定时器+串口接收中断)

STM32CubeMX+HAL库+USART接收不定长数据(定时器+串口接收中断) 概述在实际项目设计中程序常常会收发不定长的数据帧一般我们会约定一个帧协议帧协议中包含有帧头、帧尾、帧长度、校验一般接收时会判断帧头帧头有效后根据帧长度去接收不定长度的帧总体思路是通过拟定帧协议将不定长的数据帧转为已知长度的帧从而方便接收。但在没有拟定帧协议的情况下如何去接收不定长的数据呢本文提供自己的一些拙见欢迎批评指正如果有更好的方法也请不吝赐教非常感谢实现思路使用串口Recivice_IT或Recivice_DMA接收数据、使用定时器判断一帧是否接收完毕接收到最后一个字节后一段时间内未收到数据此工程以数据间隔大于1ms判断一帧接收完成时间可以修改记录接收到的数据。如果是仅仅需要存储数据而不需要解析的话如数据记录设备完全可以仅用Recivice_IT每次只接收一个数无限重复调用即可注好像可以使用看门狗替代定时器程序思路开启Recivice_IT接收第一个字节—接收完成回调函数中开启定时器同时重新打开Recivice_IT—如果定时器倒计时结束则为一帧接收完成如果未结束又进入接收完成回调函数则定时器重新计时并把接收到的数据转移硬件使用STM32F429IGT6正点原子阿波罗开发板方案验证通过USART1接收不定长数据接收完成后通过USART1原样发出操作步骤打开STM32CubeMX选择对应芯片选择SW调试模式选择外部高速时钟这块开发板使用的是无源晶振所以选择“Crystal/····”模式晶振时钟配置开启USART1选择异步模式波特率与长度校验等保持默认开启串口的中断开启TIM1、选择定时器时钟、我配置的主时钟是180M根据计算公式配置PSC和ARR最后得出的结果是1ms勾选TIM的溢出中断勾选生成独立.c/.h文件输入文件名、存储路径、选择IDE生成工程生成完毕打开工程12.开始编写代码为了方便就直接写在main.c/main.h中了/* main.c中定义一些数组 */uint8_tRxBuff;//接收缓冲区uint16_tRx_Len;//已接收长度uint8_tDataBuff[1000];//数据暂存至数组内/* 主函数while1之前添加这一行函数 */HAL_UART_Receive_IT(huart1,RxBuff,1);HAL库已经帮我们完成了串口接收中断的一系列处理过程我们只需要调用接收完成回调函数即可/* 在main.c中重写接收完成回调函数 */voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart){DataBuff[Rx_Len]RxBuff;//转移接收数据Rx_Len;//计算当下这一帧接收的长度HAL_TIM_Base_Start_IT(htim1);//开启1ms倒计时HAL_UART_Receive_IT(huart1,RxBuff,1);//继续接收}同样HAL库已经帮我们完成了定时器溢出中断的一系列处理过程我们只需要调用、回调函数即可/* 在main.c中重写定时器溢出中断回调函数 */voidHAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef*htim){if(htim-InstanceTIM1){HAL_UART_Transmit(huart1,DataBuff,Rx_Len,10);//验证是否成功接收Rx_Len0;}}实验现象不足之处虽然在编写代码的时候定义了DataBuff[1000]看起来好像是最大接收1000字节实际不然根据实际项目去定义数组大小数据接收后进行处理使用之后数组可以清除之后重新利用使用这种方式好像弥补了方案一的缺点省去人工定义最大长度的步骤但是这种方案也存在较大的缺点每接收一个字节都中断一次非常消耗系统资源尤其是HAL库中从中断到回调函数运行了不少的程序频繁的中断很可能造成数据溢出。在项目复杂度较小的情况下还行如果项目复杂度较大可能会导致系统运行异常。是否还有其他更好的办法我暂时还没有思路但是我又想到另一种接收不定长数据的方案
返回列表