欢迎光临散文网 会员登陆 & 注册

精讲串口通信协议,小白少走弯路的东西

2022-05-18 20:12 作者:大方老师单片机课堂  | 我要投稿

精讲串口通信协议小白少走弯路的东西


///插播一条:我自己在今年年初录制了一套还比较系统的入门单片机教程,想要的同学找我拿就行了免費的,私信我就可以~点我头像黑色字体加我地球呺也能领取哦。最近比较闲,带做毕设,带学生参加省级或以上比///


串口通信协议,基本上是每个单片机开发人员必会的协议,是所有通信协议里面最最常用的。但是很多人并没有去研究过细节,这篇文章干货满满,将带你深入串口协议的内部。

1、串口协议简介

什么是串口通信?

简而言之,串口通信就是通过一根导线TX,只讨论发送,当然一定还包GND),将需要的数据bit流传送给接收端,既然是通信,参与的双方当然要制定数据的传输方式以及规范。

随便打开一个串口助手都可以看到,如果需要使用串口就需要配置端口、波特率、数据位、停止位、校验位、流控这些参数。


如果接收端和发送端的设置不同,就可能会导致数据异常。

端口:这个就不用解释了,使用串口芯片安装驱动后就可以在电脑上看到端口号了。


现在,我们从电平信号角度分析一下波特率、数据位、停止位、校验位、流控(由于用的比较少,暂不分析)的作用。

2、电平信号分析

打开串口工具,分别调整如下参数

调整参9600/8/N/1,发送十六进制数55 AA


调整参115200/8/N/1发送十六进制数55 AA


调整参9600/7/N/1发送十六进制数55 AA


调整参9600/8/O/1发送十六进制数55 BA


调整参9600/8/E/1发送十六进制数55 BA


调整参9600/8/N/2发送十六进制数55 AA


B代表起始位E代表停止位,很明显看出是先传输的bit,再传输的bit

分析,调整波特率并不会影响整体波形形状,只bit的持续时长不同9600波特率时的一bit大概104us115200波特率大概9us,这是可以算出来96001000ms/9600 = 104.1us1152001000/115200=8.6us。分析可知波特率越大,传输速度越快。

分析,调整数据位55本来应该01010101但是数据位调整7之后55变成1010101AA本来10101010变成0101010,分析可知错误的数据位会将传输的字节从高位开始截断,可能导致数据丢失。一般来说除非特殊需求,否则不会调整数据位参数。

①④分析,将校验位调整至奇校(ODD)后,传输bit多了一个奇校验位,就是说如果本来8bitbit位按位加起来是偶数,则在最高位需要补一1,否则055传输变成 (1)01010101BA(0)10111010,同样偶校验EVENMASK校验(校验位始终1SPACE校验(校验位始终0)是相同的道理。

分析,将停止位设置2后,传输的结束位(图片中E)变成之前2倍,分析可知,设置停止位,可改变数据传输完成后的停止bit持续的时间。

3、为什么需要起始位和停止位?

波特率、数据位、校验位很好理解,都是为了实现不同的业务需求,但是起始位和停止位存在的意义是什么呢?

起始位:平时这根导线上是高电平,如果接收方检测到低电平了,说明要开始接受数据了,是发送方通知接收方开始接受的一种方式。(不考虑流控)

停止位:发送方通知接收方发送完成的一种方式。发送方发送完一个字节后暂停一再继续发送下一个字节。

这时帅气的小伙伴就要问了,起始位存在的意义可以理解,但是为什么需要停止位呢?不是提前都约定好了传8bit,接收方不能就接受8bit后认为一个字节传输结束OK了吗?

能思考到这一步的小伙伴已经很棒了。如果我们是设计师,我们从设计的角度设计一下接收方接受数据的伪代码

//接收端接收数据线程

while(1) {

//接收到起始位下降沿电平

if((isGetStartFlag == 0) && getDownEdge()) {

Delayus(52);

//检测起始位低电平

if(isLowPin()) {

isGetStartFlag = 1;

getBitIndex = 0;

}

}

//已经接收到起始位

if(isGetStartFlag) {

Delayus(104);

if(getHighOrLow() == high) {

//接收1bit

}else {

//接收0bit

}

getBitIndex++;

if(getBitIndex == 8) {

//字节接收完成

isGetStartFlag = 0;

getBitIndex = 0;

}

}

}

按照这种伪代码逻辑,如果不存在停止位,会产生两个问题。

1、可能无法检查下降沿

如果上一个字节最后一次传输0,而下一个字节的起始位也0,那么下一个字节的起始位就检测不到下降沿,无法触发下一个字节的传输,就会丢失数据。这时帅气的小伙伴又要问了,那我不检查下降沿,只检查低电平不行吗?直接getDownEdgeisLowPin函数不就可以了吗,确实可以,这样又会引入第二个问题。

2、时钟同步问题

AB10分钟后你提醒我喝水,然B就看着自己的表10分钟后提A,这A一看表,才过9分钟。这种场景现实也会出现,造成的原因AB的表不同步或者有误差这个误差的引入就导致AB所指10不相同,在我们这个串口的场景里,就是发送方和接收方约定9600波特率,也就相当于约定104.1us传输一个字节,按照上面的伪代码,几个采集点应该是


但是由于误差,可能导致采集点偏移为


这两个图能大致表达时钟不同步,导致接收设备的采集点后移,如果这时引入了停止位,第二BYTE开始时,由于还是从下降沿开始采集,所以会重置上一BYTE引入的误差。


4、总结

这篇干货基本把串口协议分析透彻了,大家在分析协议的时候,最好是从设计的角度去思考这样设计的作用,如果有什么分析不对的地方,欢迎大家指正

精讲串口通信协议,小白少走弯路的东西的评论 (共 条)

分享到微博请遵守国家法律