HAL库教程9:串口接收不定长数据

编程入门 行业动态 更新时间:2024-10-10 12:23:24

HAL库教程9:串口接收不<a href=https://www.elefans.com/category/jswz/34/1768092.html style=定长数据"/>

HAL库教程9:串口接收不定长数据

  串口收到的两组数据之间,往往会有一定的时间间隔。可以判断这个间隔,来实现无需结束符,无需指定长度,串口可接收不定长数据的功能。如果串口在一定的时间内没有收到新的数据,可以认为一组数据已经接收完毕了。思路是用定时器来设置一个“闹钟”,连续的一段时间没有收到新的数据,闹钟响起,就把已经收到的数据打包,做相应处理。

定时器溢出时间配置

  首先修改定时器的溢出时间。本文规定使用5ms的间隔。在某些通信协议中,会规定间隔时间。例如Modbus规定两组数据之间要间隔3.5字符。
  实际上,间隔的时间常常与通信的波特率是相关的。在9600波特率下,一个字节的数据共 起始+8数据+结束=10位,一位是104us,所以一个字节的数据是1.04ms,3.5个字节,我们就认为是4ms。有时可能有校验位,稍微保险一点,5ms吧。假如使用115200的波特率,5ms已经算是非常“奢侈”了。
  本文使用定时器3来计时,配置的PSC为8399,ARR为49,可得5ms的溢出时间,配置过程可以参考通用定时器章节。

串口接收中断服务函数

  我们在串口接收中断服务中,把收到的所有数据都放到数组中去,判断收到的是否是第一个字符,如果是则开启定时器。

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){if(huart->Instance==USART1){__HAL_TIM_SET_COUNTER(&htim3,0);if(0 == UART1_Rx_cnt)//如果是第一个字符,则开启定时器{__HAL_TIM_CLEAR_FLAG(&htim3,TIM_FLAG_UPDATE);HAL_TIM_Base_Start_IT(&htim3);}UART1_Rx_Buf[UART1_Rx_cnt] = UART1_temp[0];UART1_Rx_cnt++;HAL_UART_Receive_IT(&huart1,(uint8_t *)UART1_temp,REC_LENGTH);}
}

  其中__HAL_TIM_SET_COUNTER是HAL提供的一个宏定义,类似于函数,功能是通过宏来直接修改寄存器的值。
  由于HAL库的串口接收中断在每次执行后都会关闭,所有在串口的中断里要重新手动开启串口接收中断。
  另外,由于定时器中断在开启定时器的时候就会执行,所以需要开启定时器之前就把中断标记位清除。

定时器中断服务

  一旦定时器发生溢出中断,说明已经到了5ms的时间间隔,可以把数据截断,根据业务需求来做相应处理,我的做法是设着一个标志位,然后在主函数的死循环内不断检测标志位,如果标志位被置1,则把收到的数据发送出去。

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim==(&htim3)){LED1 = !LED1;UART1_Rx_flg = 1;HAL_TIM_Base_Stop_IT(&htim3);//关闭定时器}
}
//main() while(1)if(UART1_Rx_flg){HAL_UART_Transmit(&huart1,UART1_Rx_Buf,UART1_Rx_cnt,0xffff);    //发送接收到的数据for(int i = 0;i<UART1_Rx_cnt;i++)UART1_Rx_Buf[i] = 0;UART1_Rx_cnt = 0;UART1_Rx_flg = 0;}   

  功能是串口接收什么就回复什么,但无需结束符,也不用指定长度。当然最长不能超过UART1_Rx_Buf数据的大小。
附上源码

更多推荐

HAL库教程9:串口接收不定长数据

本文发布于:2024-02-13 17:17:23,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1759440.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:定长   串口   教程   数据   HAL

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!