发新帖我要提问
12
返回列表
打印

请教一下 串口协议数据的几种处理方法

[复制链接]
楼主: sfesdm
手机看帖
扫描二维码
随时随地手机跟帖
21
bhj2020| | 2012-5-15 14:04 | 只看该作者 回帖奖励 |倒序浏览
其实3种方法均可用,看用在什么场合:
    正常的串口通信,速度不快。对于实时性要求不高的场合,第一种方法也无什么缺点,其中应用了帧超时类似概念。
   对于第二种方法,数据缓冲至少应该一帧(一般硬件缓冲不会太大),既然可用一帧缓冲方法,改成多帧缓冲也不会有什么问题,可以解决此问题;另外如果实时性不高,只用一帧缓冲即可。
   对于第三种方法,用了循环队列的概念,每次处理只用从队头处开始处理即可,并不消耗多少CPU资源。对于来不及处理的数据,要么丢弃,要么覆盖最老的数据;当然队列越大,队列满的概率越小,但总归有个限度。如果处理得高级一些,可以动态申请内存,就更复杂一些,只有大批量数据处理才会用到,但也有内存不足申请失败的时候,这时对于内存不够的处理也应该有个了断(丢弃、覆盖...),类似队列处理,类似一帧或多帧缓存。
应用场合、概率评估好,够用了就可取。

使用特权

评论回复
22
icecut| | 2012-5-16 14:04 | 只看该作者
建议学习kermit协议....
lz的三种都很初级

使用特权

评论回复
23
sfesdm|  楼主 | 2012-5-16 19:51 | 只看该作者
22# icecut 本人菜鸟蛋一个:lol

使用特权

评论回复
24
icecut| | 2012-5-17 09:29 | 只看该作者
通信包括三部分:第一部分叫同步码.第二部分叫数据包,第三部分叫校验码....缺1不可.
没有第一部分,发错一个字节有可能导致后续很多包全部错误.
没有第三部分就不知对错了

使用特权

评论回复
25
zd420325| | 2012-5-18 11:16 | 只看该作者
用双核的MCU吧,一个核就负责通信,一个核负责其它的运算,最多有8核滴。我家做台湾应广滴代理,有需要Q一下 191394197

使用特权

评论回复
26
szyijitong| | 2012-5-18 20:33 | 只看该作者
很多应用还是要开BUFFER然后在主程序中处理的的,主要原因有:
1、通讯协议未必你说了算,很多时候是要与别人通讯的,而人家的协议可能就是没有协议,就像AT命令,实际上无格式可言;
2、在中断中处理数据是不可能的,哪怕你除了干这事啥也不干,如果协议复杂,你在里面处理的话,恐怕连收数都成问题;
3、在主程序中处理的话,方显从容不迫,开BUFFER处理,可采用超时处理,处理完毕清除的方式,也可以不采用超时,采取截取协议帧的方式,处理完毕不完全清0,而是标识成已处理的标识;这两种方式各有优缺点,前一种对系统的消耗小,但可能存在因处理时点异常导致漏处理数据的存在;而第二种,基本上不会有漏网之鱼,但对系统的消耗会大不少,但如MIPS够高的话,也无所谓。
比较完美的处理方法是第三种。

使用特权

评论回复
27
234641497| | 2012-5-18 23:59 | 只看该作者
高诉你我的方法 应该算第二种加第三种吧;
我一般一组数据是这么定义的%01#WD0000+异或和校验+回车
%是起始附说明一组数据开始
01是站号;就是比如你用485多机通信时可以用
WD是命令;执行什么命令;
异或和:校验,防止传错;
回车:结束符,一组数据结束;
1.就是先建一个缓冲器Buffer[];多大看你接受的一组数据最大多大;
2.在串口中断中一帧一帧的接受;Buffer[i++]=SBUF;
3.如果Buffer[0]='%',则接着往下收;否则i清零;
4.如果Buffer[i]=回车,说明结束了;把Buffer[]拷贝给INBuffer[];
5.这里一定要清空Buffer,不然会溢出;
6.给个接收一组数据完成标志;当外面的UART接收处理子程序收到,则进行分割处理
7.千万别把分割处理回复放在中断中,不然可能会影响你的发送和接收,中断要短小精悍!!!

用我的方法去做吧,肯定对,做过很多次了

至于发送一组会的吧,不多说了

记住还要加输入数据异或和检验,错误则丢弃那组数据!
输出数据加异或和;切记
做工控要想到方方面面,不能认为单片机不会出错···

就这样吧,希望对你有帮组,不懂留言

使用特权

评论回复
28
sfesdm|  楼主 | 2012-5-20 20:33 | 只看该作者
结帖啦,谢谢大家的讨论!!!

使用特权

评论回复
29
ranqingfa| | 2013-11-13 16:07 | 只看该作者
讨论的还是挺有深度的,我用的貌似是第三种

使用特权

评论回复
30
yuanquan12345| | 2013-11-13 22:58 | 只看该作者
学习了。

使用特权

评论回复
31
lklhzu| | 2014-1-22 13:27 | 只看该作者
本帖最后由 lklhzu 于 2014-1-22 13:32 编辑
234641497 发表于 2012-5-18 23:59
高诉你我的方法 应该算第二种加第三种吧;
我一般一组数据是这么定义的%01#WD0000+异或和校验+回车
%是起始 ...

你这种方法很好,我打算采用,不过如果数据区中出现和帧头%(0X25)或者帧尾回车(0X0D 0X0A)一样的数据时,要怎么处理?

使用特权

评论回复
32
科技猎人| | 2014-1-22 22:00 | 只看该作者
我用的类似第一种方法,都是靠“超时”自然断句的,缓存是动态分配的(自己实现的内存分配方式,能保证确定性),也就不存在漏包的问题了。
方法二和三的前提都是数据包要有特定格式,而实际应用千变万化不一定就有这样的条件。方法二最笨还不可靠,方法三可靠性高,但时间空间消耗都较大,尤其某包出错后还会影响后面的包,而我的方法只丢掉本次校验出错的包即可,对后面没影响。具体分析可看我的帖子
https://bbs.21ic.com/icview-674102-1-2.html

使用特权

评论回复
33
maztower| | 2014-1-23 19:38 | 只看该作者
在操作系统中,底层的数据接收方式一般是第一种或者第二种,第一种因为违背了异步通信的初衷,所以不推荐使用。
第三种方式,实际上和操作系统中的“驱动”与“应用”概念类型,驱动部分只负责接收,数据解析由应用部分完成。这种分离处理的方式,有比较好的扩展性和可维护性。
因此,如何更好的实现第三种接收方式,可以参考一些操作系统的实现

使用特权

评论回复
34
seanwaye| | 2015-6-9 15:59 | 只看该作者
mark

使用特权

评论回复
35
yuanquan12345| | 2015-6-10 16:28 | 只看该作者
学习。

使用特权

评论回复
36
zhn11212023| | 2016-4-26 16:57 | 只看该作者
学习

使用特权

评论回复
37
石子de路| | 2016-4-28 16:03 | 只看该作者
写的很好……谢谢大家的分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则