单片机串口协议 六种串口协议特征及范式
在现实生活中,我们总是需要与人打交道,彼此之间毫无关系。单片机是相同的,它需要与各种设备交互。例如,汽车的显示仪器需要知道汽车的速度和电机的运行参数,然后显示仪器需要从汽车的底部控制器获得数据。获得该数据的过程是一个通信过程。类似的例子是控制器通常是单个芯片或PLC和变频器之间的通信。沟通的双方需要遵守一套既定的规则,也就是协议,这就像我们之间的对话,双方都必须遵守一套语言和语法规则来实现对话。
通信协议又分为硬件层协议和软件层协议。硬件层协议主要规范了物理上的连线,传输电平信号及传输的秩序等硬件性质的内容。常用的硬件协议有串口,IIC, SPI, RS485, CAN和 USB。软件层协议则更侧重上层应用的规范,比如modbus协议。
好了,那这里我们就简单介绍51单片机的串口通信协议,以下简称串口。串口的6个特征如下。
(1)、物理上的连线至少3根,分别是Tx数据发送线,Rx数据接收线,GND共用地线。
(2)、0与1的约定。RS232电平,约定﹣5V至﹣25V之间的电压信号为1,﹢5V至﹢25V之间的电压信号为0 。TTL电平,约定5V的电压信号为1,0V电压信号为0 。CMOS电平,约定3.3V的电压信号为1,0V电压信号为0 。其中,CMOS电平一般用于ARM芯片中。
(3)、发送秩序。低位先发。
(4)、波特率。收发双方共同约定的一个数据位(0或1)在数据传输线上维持的时间。也可理解为每秒可以传输的位数。常用的波特率有300bit/s, 600bit/s, 2400bit/s, 4800bit/s, 9600bit/s。
(5)、通信的起始信号。发送方在没有发送数据时,应该将Tx置1 。 当需发送时,先将Tx置0,并且保持1位的时间。接受方不断地侦测Rx,如果发现Rx常时间变高后,突然被拉低(置为0),则视为发送方将要发送数据,迅速启动自己的定时器,从而保证了收发双方定时器同步定时。
(6)、停止信号。发送方发送完最后一个有效位时,必须再将Tx保持1位的时间,即为停止位。
串口协议开发:
以下解析范式都是采用数据队列的形似来存储,并且根据设备运行速度差异,还需增加数据包队列来存储解析完毕的数据包
1.范式一《固定长度》无校验
0x6B----------20字节--------0xB6
上面数据中有一个帧头0x6B,帧尾0xB6,中间数据20个。
每次数据要找到帧头0x6B才开始存储,读取完22个字节后结束储存,并判断最后一个字节是否为0xB6.
这种范式如果出现误码,整个包就会变成错误包,会比较危险。
1.范式二《固定长度》有校验
0x6B----------20字节--------校验-0xB6
上面数据中有一个帧头0x6B,帧尾0xB6,中间数据20个,帧尾前面有一个校验码。
每次数据要找到帧头0x6B才开始存储,读取完23个字节后结束储存,并判断最后一个字节是否为0xB6.
并且判断校验码。
这种范式解决上述出现的误码问题。
1.范式三《不固定长度》无校验
0x6B----------N字节---------0xB6
上面数据中有一个帧头0x6B,帧尾0xB6,中间数据N个,帧尾前面有一个校验码。
每次数据要找到帧头0x6B才开始存储,读取到0xB6后结束储存,并判断最后一个字节是否为0xB6.
这种范式会出现错误解包的问题,例如数据中出现了0xB6的数据,这个包就丢了。
依然会有误码的问题。
1.范式四《不固定长度》有校验
0x6B----------N字节--------校验-0xB6
上面数据中有一个帧头0x6B,帧尾0xB6,中间数据N个,帧尾前面有一个校验码。
每次数据要找到帧头0x6B才开始存储,读取到0xB6后结束储存,并判断最后一个字节是否为0xB6.
并且判断校验码。
这种范式解决上述出现的误码问题。
这种范式会出现错误解包的问题,例如数据中出现了0xB6的数据,这个包就丢了。
1.范式五《不固定长度》有校验,加入转义字符
0x6B----------N字节--------校验-0xB6
如果数据中有0xB6数据,那么数据包就被提前结束了,并不是我们想要的数据。
这里需要加入转义字符
0xB6 -> 0xBf,0x01
0xBf -> 0xBf,0x02
上面数据中有一个帧头0x6B,帧尾0xB6,中间数据N个,帧尾前面有一个校验码。
每次数据要找到帧头0x6B才开始存储,读取到0xB6后结束储存,并判断最后一个字节是否为0xB6.
并且判断校验码。
需要去解析特定的转义字符
这种范式解决上述出现的误码问题。
这种范式不会出现错误解包的问题。
1.范式6《不固定长度》有校验
0x6B-0xB6-N数据长度---------N字节--------校验
上面数据中有一个帧头0x6B,0xB6,数据长度,中间数据N个,校验码。
每次数据要找到帧头0x6B才开始存储,读取到数据长度后读取对应长度,再读取一个校验码。
判断校验码即可。
这种范式解决上述出现的误码问题。
这种范式不会出现错误解包的问题。