我也聊聊串口通信协议:用户层通信协议的编制

来源:互联网 发布:ubuntu怎么上传文件 编辑:程序博客网 时间:2024/03/29 08:17

1.闲话闲聊

最重要的写在前面:用户层通信协议就是数据包格式!!!
没有进行串口通讯实践的朋友可能会想:为什么要编制用户通信协议呢?通信过程中为什么要进行数据处理呢?在设计中编过串口通信程序的读者应该张口就可以回答:为了按规定格式从串口发送数据,也为了从接收到的数据中将需要的信息提取出来
串口通信协议一般可以从两个角度来思考:底层通信协议和用户层协议。底层协议一般有计算机硬件提供商和设备厂家提供,在一般性的通信编程中很少会涉及(我估计1000个搞通信的,能编底层的也就那么1,2个),而用户层协议则是面向使用者的,也就是我们在编程中通常谈到的通信协议。这种用户层的通信协议,简单来说,就是数据以何种格式发送出去,或者说如何从接收到的某种格式的数据中提取需要的数据,以及在发送和接收过程中如何保证这些数据的正确性,即数据校验
这片帖子先扯扯为什么要编?原理是什么?现存的协议有什么?这些基本问题,为后面逐步深入奠定基础。

2.为什么要编制用户通信协议?

大多数MFC等界面开发数据都已经准备好了,只需做一个可视化工作就可以了。可是实际很多工作可不是这样,我们需要实时采集并处理显示数据。举例子说,我们刚入门做通信编程时,大多时候只是从串口接收数据,并显示在GUI窗口上。然而我们却忽略了一个非常关键的细节:如何从接收到的数据中提取有用的信息?如何处理我们发送出去的数据?这些问题才是我们进行通信编程的目标所在,也就是说,通信协议才是对接软件与硬件交流的关键!
在大多数编程实践中,接收与发送数据并不需要直接显示在程序界面中,而只是需要将对我们有价值的几个数据显示,或者根本就没有必要进行显示,而是直接在程序内部进行处理。这是,数据发送方与数据接收方就必须事先约好数据发送的格式。当然,我说的这个数据发送格式的约定实际上就是数据通信协议!

3.有感而发——谈谈GPS模块的数据接收过程

GPS:Global Positioning System
近年来,GPS系统已经在大地绘制、海上渔用、车辆定位监控、建筑、农业等各个领域得到广泛应用。目前,市场上的大部分GPS接收模块都是通过RS-232串口与PC/MCU进行数据传输。这些数据包括了经度、纬度、时间、卫星使用情况等基本信息。我们需要从GPS接收模块发送出来的数据中提取出我们要用的信息,比如最简单的定位信息(只用到了经纬信息)。因此,我们就必须了解从GPS模块获得的信息,并进行数据挑选。
例如,从GPS接收模块得到的定位信息如下:
$GPGGA,hhmmss,dddmm,mmmm,a,dddmm,mmmm,a,x,xx,x.x,x.x,M,,M,x.x,xxxx,*hh<CR><LF>
这实际上是NMEA-0183无线通信输出格式(National Marine Electronics Association, NMEA, 美国海洋电子协会)。每次都会发出像上面格式的一个数据串,更多的时候我们都把这个字符串称为一个数据包。
  • $是包头,GPGGA是包名;
  • hhmmss,dddmm,mmmm,a,dddmm,mmmm,a,x,xx,x.x,x.x,M,,M,x.x,xxxx是数据内容;
  • *是指包尾;
  • hh为校验位;
  • <CR>是回车符,ASCII码值为13;
  • <LF>是换行符,ASCII码值为10。
这里加上回车符和换行符,只是为了方便调试。
下面对这个包进行实例化:
$GPGGA,033744,2446.5241,N,12100.1536,E,1,10,0.8,133.4,M, , , ,*1F
在我们实际定位的系统中,并不能够显示这些数据就足够了,我们还需要实时将有关的数据提取出来,或者在程序中使用,或者提供给第三方。为了提取出“有用的”信息,我们必须要知道该数据包的格式定义。具体解释如下:


知道了GPS的数据通信协议格式,我们便可以得到相应的位置信息:北纬24度46.5241分、东经121度00.1536分、格林威治时间03点37分44秒、定位卫星编号10。
其实,这种GPS必须遵循的数据描述格式就称为通信用户协议,这种协议一般一方单独建立就好,另一方只需要依据这样的协议来进行数据接收与发送就好!
这其实也能深刻地解释为什么我们要编制用户协议。

4.串口通信中用户层协议编制原理

在串口用户层的通信协议中,一般是围绕发送方如何建立数据包和接收方如何处理数据包,并从数据包中提取出我们关心的信息。通信协议也为这个事儿进行服务。实际上,用户层的通信协议没有那么严谨,随意一点就好......但是,还是有那么几个原则需要我们严格遵守:

4.1 数据包必须有包头

包头是供接收方判断一个数据包开始传输的重要标志,接收方从收到的数据中判断接收到了包头,就认为接收的数据已经开始,真正的数据信息马上就会到达。但是,我们必须要切记一点,包头字符必须有别于数据信息,也就是说,这种特征是数据包中其他数据没有的,否则会造成混乱。

4.2 非定长数据必须有包尾

这个很少用,用也很好理解

4.3 定长数据应该指明长度

对于长度不变的数据包,数据长度应该事先约定。这样接收方在知道接受长度之后,就能够判断接收的数据包是否结束。

4.4 建议对数据进行校验

串口通信底层协议(机器硬件实现)已经设置了奇偶检验方式。其实,如果在用户层添加新的校验,可以对数据进行进一步的排错,这样可以更好地保证数据的正确性。

4.5 换行符的使用

如果是要显示数据,前列推荐在数据包的结尾添加换行符,方便阅读接收到的数据。然而,如果仅把接收到的数据作为基础数据,那就没有必要了......

4.6 如果更新快的数据,建议尽量简短

如果要求数据更新快,就要让每次传输的数据尽量短。

5.在串口通信中几种常用的用户层协议

在常见的用户层协议中,按照输出数据的可读性可以分为完整性协议和简单型协议,NMEA-0183无线通信输出协议,包含了包头、数据,包尾、校验、换行,而且数据之间还有逗号分隔,观察数据非常方便。但是数据包长度增加,发送时间也会增加,这在很多更新快的场合是不合适的;简单型协议则去掉了在程序中不需要利用的换行与分隔符,有时甚至连校验也省略了。

5.1 NMEA-0183无线通信协议

5.2 自定义的通信协议

自定义通信协议可以设置的非常简单,也可以为了查看方便,设置得比较复杂。简单的协议一般需要传送的信息比较简单,而且没必要直接进行观察。
以四字节组成的通信协议为例,进行深入研究:




这个简单的例子,可以说明,仅仅是4个字节的通信协议就可以传送大量的信息,而且还加入了校验,在实际的应用中,我们还是应该进行协议的扩充!

6.总结

在实际应用中,我们能看到各种协议,但是它们的实质都是一样的。首先,对数据进行“打包”发送;然后接收方,对数据进行“拆包”。进而对数据包中的数据进行处理,或是提取有用的数据,或是进行编码翻译,这也是下一部分,将要讨论的话题。







1 0
原创粉丝点击