串口字节超时处理(一)

2019-07-20 23:17发布

 
       应此贴http://www.openedv.com/posts/list/6917.htm,给我发邮件的人有好几个,我不一一回了,发在这儿。


      大部分串口都是基于一字节、一字节传输,检测到特定的字符(比如换行或者空格)才判定一帧数据结束,这样的传输机制在自己调试时可以用,但实际运用其实用的很少,最大的坏处是cpu会“死等”特定字符,另外,若是由总线干扰出现的特定的字符,若程序同样判定帧起始(或停止)符,这明显是错误的。我们需要一帧一帧的传输,这样,就需要字节超时处理了,即只要字符与字符之间间隔超过一定的时间,那么就判定字符是一帧的结束。
      大部分教程没有提到可能是为了降低大家的学习难度,这里提供一份参考代码,STM32的所有串口都加进去了,全部测试通过,也经过实际项目(非精确严格要求)的检验。若不需要用到某些串口,只需要把app_conf.h,文件里的相关宏关闭即可。比如,不需要用到串口3、4、5,那么只需要注释掉app_conf.h里的USING_USART3、USING_USART4、USING_USART5即可。同时,串口相关配置波特率、缓冲区大小等等也在此文件,大家看看注释就明白了。默认全部开启,字节超时时间可设,例如USART1_RECEIVE_OVERTIME这类名字的宏。最后一个配置是printf 输出串口的选择,默认为串口一。

      这个实现五个串口公用一个systick,不需要每个串口需要单独的硬件定时器;二级缓冲区以加大吞吐量,一个接受缓冲区,接受缓冲区负责接收;一个帧准备缓冲区,帧准备缓冲区有一个准备好的标志USART_ready_buf_ok,应用程序可检测这个标志看是否有一帧数据存进来。还有一个帧长度USART_ready_buf_len以指示准备好的缓冲区的帧长度。代码先发放出去,大家先试试,稍后有时间在说说具体事怎么实现的,年底比较事多,大家见谅。

    对了,测试代码是简单地回发,即5个串口回发自己收到的数据帧,你可以做个测试,若字节超时时间设的比较长(在app_conf.h文件的USART1_RECEIVE_OVERTIME宏),那么你在串口调试助手里不停地点发送,等到你停下来,才会回发你刚发的内容。

     还有,这个工程LED灯部分也有些意思,除了亮状态和灭状态,还有第三种状态————闪烁,而且闪烁的次数与闪烁的间隔软件可配置。若有兴趣大家也可以试试,配置也在app_conf.h里,当然,你的板子与我的板子肯定不一样,那么"AunonBoard_led.h"里的各个LED_PORT和LED_PIN宏定义也要修改。 

     有问题跟贴回复,我就不一一邮件回了。


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
46条回答
我是哈哈
1楼-- · 2019-07-24 16:11
回复【32楼】我是哈哈:
---------------------------------
这个时候 就不需要它执行了。
条件一成立,主函数根据rcOK标志 开始解析 ,后面就不执行了 
解析完,rcOK =false; rcS=0 ;  重新开始
aleda303
2楼-- · 2019-07-24 21:19
 精彩回答 2  元偷偷看……
yuanzia
3楼-- · 2019-07-25 01:57
 精彩回答 2  元偷偷看……
Glacier
4楼-- · 2019-07-25 05:47
  *     @arg USART_IT_RXNE: Receive Data register not empty interrupt
  *     @arg USART_IT_IDLE: Idle line detection interrupt
  *     @arg USART_IT_ORE:  OverRun Error interrupt
  *     @arg USART_IT_NE:   Noise Error interrupt
  *     @arg USART_IT_FE:   Framing Error interrupt
  *     @arg USART_IT_PE:   Parity Error interrupt

超时可不可以这么理解,就是在接收一帧数据时可能是由于以上原因没有完整的接收或已经接收完一帧数据,超时时间范围内没有接收到下一个字节数据,于是就将接收缓冲区的数据转移到准备缓冲区,再对准备缓冲区的数据进行解析,比如帧头帧尾特定字节判断,如果和用户定义的字节不一致,就将这一帧数据丢弃,重新开始接收下一帧
不知道我的理解有没有问题,欢迎指正


Glacier
5楼-- · 2019-07-25 11:43
MARK,貌似要用到
带我足够强大
6楼-- · 2019-07-25 11:57
我一直使用一个硬件定时器去判断帧是否结束的,,借鉴了modbus的原理 ,,因为帧长度不知,结束符可能会被帧里面的数据干扰,,所以先是整一帧收下来,,再去解析,,而且这些全在中断里完成,亲测51 msp430  stm32 f0 f1 都完美运行  

一周热门 更多>