91
4146
1万
资深工程师
在阅读本文前,你需要先做到串口成功接收一个数据(相信这一点是很简单的) 这几天简单总结了一下用串口怎么接收一帧数据的办法,个人使用的有三种,下面逐一介绍:
这种在数据接收不频繁状态下使用。简单易实现。既然是使用中断,所以自然需要硬件的支持,比如stm32就可以这么做。
8位单片机估计是没有的,嵌入式32位的处理器应该会有,可以依据自己使用的芯片查一下对应的寄存器手册,重点关注一下中断寄存器和uart寄存器的介绍部分。
使用特权
这种也是很高效的,具体的做法是,在一帧数据尾部添加一个小尾巴 ~ ~ 拿我的做法举例,因为我传输的内容里面不会出现特殊字符,所以我选择特殊字符 ‘#’标识一帧数据接收完成,然后立一个flag,交由通讯处理函数去处理。 这里结束符的选取,不可以是通讯中可能传输的字符,尽量使用一个字符,简化逻辑判断。 这种方式缺点也是很明显的,即只适用于自定义的通讯格式,或者尾部结束符唯一确定的情况。代码如下:
14735f2a7d0b1f9ee.png (302.36 KB ) 下载附件 2020-8-5 17:34 上传
14735f2a7d0b1f9ee.png (302.36 KB )
下载附件
2020-8-5 17:34 上传
424165f2a7d12e5301.png (25.98 KB ) 下载附件 2020-8-5 17:34 上传
424165f2a7d12e5301.png (25.98 KB )
这种方式相对来说延时自己计算,具体做法是在串口接收数据时启动定时器,每接收一帧数据要复位定时值以保证定时器不会溢出。亲测在高频率接收不会乱码等。定时器的超时值设置为1.5倍接收一个数据的时间,这样一来,当定时器超时时候,就意味着串口接收数据停止了。此时同样立一个flag,然后交由通讯处理函数处理。 这里的定时器大可不必单独再用一个定时器,可以使用系统滴答定时器,让滴答一次计数加一。超时的值设置要根据波特率调整,例如9600的波特率下,接收数据速率为9600bit/s = 1200B/s 也就是 0.83ms/B 那么我们的超时值可以设置为0.84*1.5 = 1.26ms 取个整1.3ms。其他波特率以此类推…… 如果数据过去频繁,这种方式可能会产生粘包的情况(没测,如果有这方面使用需求一定要自己测试一下)。关于粘包处理,如果每个包数据长度基本相等的话,可以简单做一个根据包长度判断是否发生粘包。
483525f2a7d59130ed.png (40.94 KB ) 下载附件 2020-8-5 17:35 上传
483525f2a7d59130ed.png (40.94 KB )
2020-8-5 17:35 上传
361615f2a7d6214441.png (22.11 KB ) 下载附件 2020-8-5 17:35 上传
361615f2a7d6214441.png (22.11 KB )
72755f2a7d6f4ede0.png (19.82 KB ) 下载附件 2020-8-5 17:35 上传
72755f2a7d6f4ede0.png (19.82 KB )
这就是我目前所能想到和已经实践过的三种串口接收一帧数据的方式了,如果觉得有用就顶一下吧
发表回复 本版积分规则 回帖后跳转到最后一页
2
扫码关注 21ic 官方微信
扫码关注嵌入式微处理器
扫码关注21ic项目外包
扫码关注21ic视频号
扫码关注21ic抖音号
本站介绍 | 申请友情链接 | 欢迎投稿 | 隐私声明 | 广告业务 | 网站地图 | 联系我们 | 诚聘英才 | 论坛帮助
京公网安备 11010802024343号