前言
最近串口用的多,感觉有必要简单列一下用过的通信协议帧,这样可以总结下来和大家交流一下,有需要的可以直接参考
一、单片机串口简介
单片机中的串口(UART)是一种单字节收发的通信方式一般三根线就够了,标准线序对接的话是九针DB9类型,常用的对三线(rx tx gnd | A B gnd)使用简单方便,常用于短距离,较少连接器件的通信。 串口增加外部控制芯片会将串口变为RS232和RS485两种通信类型的电平,RS232的逻辑1和0分为对应+15V和-15V,RS485的逻辑1和0对应A B端口的电压差+2 ~ +6和-2 ~ -6。RS232不可以连接多个子设备,可实现全双工通信,RS485可实现多个器件的挂载,单双工通信。 因为是单字节收发,所以就需要一个规定好的通信格式来实现解析与发送,这个就是通信协议。
二、常用的通信协议类型
1.没有格式
没有格式有时候就是王道,许多器件厂商直接使用字符串命令式控制。比如
/s1000
设置速度为1000
/r0000
回复出厂设置。 这种有个好处就是在一些资源及性能一般的器件中可直接使用,不用队列,不用缓存,直接在中断中进行数据的读取与赋值,简单粗暴。switch case轻松解决。适用于简单短命令短数据场合。 缺点就是通信数据不能太长,容易出现误操作(谁手残乱发送数据碰巧改了核心数据就完犊子了)。
2.帧头帧尾+数据
帧头 | 数据长度 | 数据 | 校验位 | 帧尾 |
---|
0XF5 | 0X4 | 0X01 0X02 0X03 0X04 | 0XC5 | 0X5F |
简单常用的就是这种带帧头帧尾或者校验位的格式。通常在单片机中进行数据的接收然后存放到缓存队列中,然后主循环中根据帧头帧尾对缓存队列数据进行提取,一帧一帧的进行赋值操作。 校验的有很多,和校验、CRC等等,这里我觉得还可以实现加密,自己设置一个加密算法,校验位就用加密算法得出,别人拿不到加密算法只有通信协议也是不能驱动你的器件的。(骚操作,好多连校验位都没有,越简单越可靠) 此种有点是简单可靠,上下位机容易根据通信格式进行数据的交互,适合较长数据的传输。
3.帧头帧尾+数据+附加功能码
帧头 | 功能码 | 数据长度 | 数据 | 校验位 | 帧尾 |
---|
0XF5 | 0X01 | 0X4 | 0X01 0X02 0X03 0X04 | 0XC5 | 0X5F |
这种格式兼容第二种,可以处理不同类型的命令,比如读和写。 功能码可以无限添加,比如使用两个功能码一个指示对哪个变量操作,另一个指示读还是写操作。这种应该是最广泛使用的了吧,工作量也不是很大,自己调试调试也很容易实现。
4.帧头帧尾+数据+附加功能码+目标地址
帧头 | 地址 | 功能码 | 数据长度 | 数据 | 校验位 | 帧尾 |
---|
0XF5 | 0XCC | 0X01 | 0X4 | 0X01 0X02 0X03 0X04 | 0XC5 | 0X5F |
这种加地址的就有意思了,具备了识别器件的能力。比如你随便拿了一个同类型不同地址的器件接入,你发送命令器件就不鸟你。这种适合用在485通信总线上,所有器件根据地址去识别是否去执行。 优点是具备器件识别功能有命令执行唯一性,适合485通信。 缺点是232使用的话有点鸡肋。目前我见过的大多是这种不管是485还是232通信(其实地址也算是一个功能码,问题不大)。
5.帧头帧尾+数据+附加功能码+转发功能
帧头 | 源长度 | 源地址 | 目标长度 | 目标地址 | 功能码 | 数据长度 | 数据 | 校验位 | 帧尾 |
---|
0XF5 | 0X01 | 0XCC | 0X02 | 0XDD 0XBB | 0X01 | 0X4 | 0X01 0X02 0X03 0X04 | 0XC5 | 0X5F |
这个是我使用过的最厉害的串口通信协议了,通过地址长度及地址域实现判别是否是需要转发下一级还是进行操作命令。 此条命令过程为:0XCC的器件发送命令帧给0XDD的器件,0XDD的器件发现自己不是最终目标,重新组帧发送给地址为0XBB的下一级器件,0XBB接收到命令后发现自己是最终目标因此执行命令。 这种的通信协议优点是功能俱全,可实现转发。 缺点就是解析帧的程序复杂,增加一个转发就会加一个重新组帧的时间,转发越多越费时间。(不过谁没事用串口串这么多子级呢,有病么,完全可以考虑使用其它通信方式了) 这种应该是将串口适配了其它通信方式(比如can、tcp/ip等),这样程序处理得当的话应该可以实现不同通信方式的混搭,比如主板通过串口发送,下一级通过CAN总线发送给更多的器件,也许CAN总线发送完了子器件又有子器件用串口发送接收,总之来说具备了转发就具备了一定的通信兼容性。 有点复杂串口还是用第4种方式就够了。
6.MODBUS RTU
这个很牛批,我没咋用过,简单说一下。这个单片机得用485通信了,牛就牛在是一种正规的统一标准,有现成的集成模块买过来就能用的那种,电气类工业控制中常用如PLC。 Modbus-RTU模式是指当控制器设为在Modbus网络上以RTU(远程终端模式)模式通信,在消息中的每个8Bit包含两个4Bit的十六进制字符。Markdown将文本转换为 HTML 。 操作方式的话和4的差不多(但人家就是做成了认可的标准就是牛),多涉及一些寄存器的操作,寄存器一般都是按位操作,每一位都有每一位的功能,一下就扩展了很多用处。
7.其它
其它就是其它,可以混为一谈的一些方式,这些多半是上述几种的混搭型。有的有帧头,没有帧尾,有的有帧尾但用地址做帧头,有的不加校验,有的用固定长度实现帧尾的功能,有的奇葩还用地址做帧头,校验做帧尾还不固定长度。
总结
差不多了,一个串口基本的通信协议帧也就这些了,后续想到了再添加。不要一味的追求功能多,简单实用才是最可靠的。能不加通信协议就不加,最好。 突然间想到了一个点子,单片机程序是不是也可将上述协议帧中的每一个功能位模块化,做到一种完全的兼容,比如我用到了帧头我就调用一个添加程序添加帧头,用到了功能码就专门添加一个功能码位放功能码,外部再做一个大封装,这样会很容易一个通信模板兼容所有通信协议。(也许也没必要,大多数都很简单,提取的数据也不多,何况我的C++还一塌糊涂,等我有实力了在考虑吧,不慌)
参考文献
|