文档介绍:串口成帧协议
串口接收中的问题
在电子系统中,最简单、最广泛的通信方式无疑是串口了,几乎所有与模块相关的产品,差不多都有串口的操作方式,如串口蓝牙模块、串口WIFI模块、串口ZigBee模块、串口语音模块等。不仅是这样,在嵌入式开串口成帧协议
串口接收中的问题
在电子系统中,最简单、最广泛的通信方式无疑是串口了,几乎所有与模块相关的产品,差不多都有串口的操作方式,如串口蓝牙模块、串口WIFI模块、串口ZigBee模块、串口语音模块等。不仅是这样,在嵌入式开发中,很多时侯调试离不开串口,固件升级离不开串口,可见搞电子的人如果不能很好的操作串口,那就真是说不过去了。
串口的应用场合非常多,但是有一个残酷的现实摆在我们面前,那就是通信问题。我们知道串口发送数据时是面向字节的,接收方接收数据时也是面向字节的,而在实际应用中,收发数据往往都是面向帧的,这样往往会对接收方接收数据造成一定的困难。举个例子吧,一个单片机系统通过串口往PC机发送一帧100字节数据,但是PC机在调用系统API来接收数据时,往往不能一次性接收完100字节,可能第一次接收5字节,第二接收10字节……,虽然最后都能收到100字节。如果单片机发送两帧数据,并且这两帧数据之间的时间间隔非常短,那PC就无法区别出两帧数据的边界了。初入行的人或许会想到一些诸如增加标志位、判断时间等方法来解决这个问题,但不够严谨的。所以我们有必要设计一个相对可靠一点的串口成帧的方法来解决接收难题。
也许搞技术的人,或多或少都听说过网络通信的OSI模型,标准的OSI模型有7层之多,像串口这种简单的通信,并不需要这么多层的实现,但是至少要实现链路层,才能解决数据组帧问题。很多人之所以在接收串口数据时出现困难就是因为从物理层接收数据之后,直接提交给应用层,这样应用层必然是面向字节的,通信方式是如下形式:
物理层 -->> 应用层
在这里,我们要做的是在物理层与应用层之间插入一个链路层,也即OSI模型的第二层,本文要描述的就是这个链路层的协议,通信方式会变成如下形式:
物理层 -->> 链路层 -->> 应用层
由于大部分人都****惯于直接操作串口,所以链路层只需要实现最基本的组帧功能即可,没有必要搞的那么复杂。这里链路层的功能负责将物理层的字节数据,按照一定规则封装成帧,然后提交给应用层,这样应用层接收的便是完整的一帧数据,而不是零零散散的字节数据。
那么链路层使用什么样的方法来进行封装会比较好呢,这里可以效仿网络通信协议中一些知名协议的做法,比如SLIP、PPP协议等,这些协议的链路层都是通过转义的方法来组帧。因此,我们的串口成帧协议也是使用转义的方法,但是要说明一点,这里只提供一种组帧的方法,任何可靠性的问题如检测、纠错等必须由上层来实现。
串口成帧链路层组帧规则如下:
首先我们要定义三个特殊字符:帧起始标志SOF,用0x7d表示;帧结束标志EOF,用0x7e表示、转义标志ESC表示0x7f。数据帧封装格式如下表所示:
串口链路层帧格式
域名称
描述
SOF
帧起始标志,固定为0x7d,SOF是Start of Frame的英文编写
DATA
要传输的数据,串口数据建议在512字节以内为宜。
EOF
帧结束标志,固定为0x7