前置知识
- 波特率:每秒钟传递的bit的个数。
- 差分信号:使用两根线之间的电压差来表示高低电平。(传统的是用一根线相较于
GND线(接地线)来表示高低电平)
UART(串口)协议
UART 叫通用异步收发器,是一种通用的串行异步通用总线。该总线有两条数据线,能够实现全双工的发送和接收。
协议规定与格式
- 数据线在空闲的时候,必须设置为高电平。
- 发送数据的时候先发送数据的低位,再发送数据的高位。
- 发送目标数据的格式: 起始位(
一位低电平)+目标数据+校验位(一位,可有可无)+停止位(一位高电平) - 目标数据的位数可以是
5~8位,常用8位。
串口协议规定一次性发8位,是为了防止因收发双方时钟的差异导致累积误差的出现(
因为这是异步通信,所以没有时钟线,收发双方各用各的时钟)。
如上图,两个芯片进行串口通信的连接图,其中
TXD用于发送数据,RXD用于接收数据。
串口通信的存在的问题
串口通信只是定义了信号的时序,没有定义接口的电气特性(电压等)。两个不同的设备之间,它们的接口标准可能不同,因而不能直接相连。串口通信采用TTL信号(电平)来表示0和1,抗干扰能力较差,数据传输过程中很容易出错。串口通信的距离极短。
RS232协议
RS232协议是一个国际标准,基于串口通信,在接口的电气特性上做了规定。该标准规定采用一个标准的连接器,标准中对连接器的每个引脚的作用加以规定,还对信号的电平加以规定。
RS——232接口一般只使用用RXD,TXD,GND这三条线。
协议规定
- 信号:该标准规定
-5v到-15v为逻辑"1",+5v到+15v为逻辑"0"。 - 以上电气规定可以增强抗干扰能力,增大通信距离,其传输距离可达15米。
信号的时序与串口通信一致。- 串口通信之间传输的信号是
TTL,要想使用RS232标准的接口,需要使用转换器,将TTL信号转换成RS232信号。
RS232存在的问题
- 接口的信号电平值较高,易损坏接口电平的芯片,而且与
TTL电平不兼容,需要电平转换芯片才能与TTL电路相连。 RS232的通信速度较低。- 易产生共模干扰。
- 传输距离较短(
15m)。
RS485协议
RS485协议也是一个标准,使用该标准能够在远距离条件下以及电子噪声大的环境下有效传输信号。其次,RS232和串口都只能实现点到点的通信,但是RS485却可以通过RS485总线将多个设备(最多32个RS485设备)连接到一起,建成一个设备网络。
协议规定
- 信号:
RS485采用差分信号进行数据传输。共有两个线——H和L,当两线之间的电压差(H-L)为+2v到+6v则表示逻辑"1",为-2v到-6v则表示逻辑"0"。 RS485使用的电平比RS232要低,传输距离比RS232要长(可达1500m)。RS485电平与TTL电平兼容,可以很方便地与TTL电路连接。RS485采用两线制(即设备连接只有两根线),这种接线方式为总线式拓扑结构,能够在同一根总线上挂载多个设备。- 因为采用差分信号来表示电平,而
RS485设备上只有两根线(两线制),因此数据的发送和接收不能同时进行,只能采用半双工的形式进行。 RS485在于串口进行通信时,同样需要转换芯片,将TTL信号转换成差分信号。
注意:
RS232和RS485都只是在电气特性上做了规定,信号时序上用的还是串口那一套。
IIC协议
IIC总线是一个串行的半双工总线,适用于近距离,低速的芯片之间的通信。IIC总线有两根双向的信号线,一个数据线SDA负责收发数据,一个时钟线SCL负责通信双方的同步。IIC总线结构简单,成本低,因此在各个领域得到广泛的运用。
协议规定
IIC总线是一个多主机总线,连接到IIC总线上的器件分为主机和从机,主机有权发起和结束一次通信,而从机只能被主机呼叫。当总线上有多个主机同时启用总线时,IIC也具备冲突检测和仲裁的功能来防止错误的产生。每个连接到IIC总线的设备都有一个唯一的地址(7bit),且每个器件都可以作为主机或者从机(同一时刻只有一个主机),总线上的器件的增加和删除不会影响到其他器件正常工作,IIC总线上的发送数据的器件为发送器,接收数据的器件为接收器。
- 在空闲状态时,
IIC的两根线SDA与SCL均被设置为高电平。 - 当
SCL为高电平时,SDA由高变低表示起始信号。 - 当
SCL为低电平时,SDA由低变高表示停止信号。 - 起始信号发出后,总线就处于占用状态,停止信号发出后,总线就处于空闲状态。
IIC总线通信时每个字节为8位长度,数据传送时,先传送最高位,再传送低位。- 发送器发送完一个字节数据后,接收器必须发送1位应答位(低电平)来回应发送器。即一帧包含9位。
IIC总线在数据传送时,当时钟线为低电平时,发送器发送一位数据,在此期间允许数据线上的数据发生变化(0变为1,1变为0),当时钟线为高电平时,接收器读取一位数据,在此期间,数据线SDA上的数据不允许再发生变化,必须保持稳定。
IIC总线通信过程
- 主机发送起始信号,启用总线(其他器件收到该起始信号后,就不会再作为主机启用该
IIC总线)。 - 主机发送一个字节数据指明从机地址和后续字节传送方向。(从机地址 (高7位)+字节传送方向(最低位,
0表示主->从,1表示从->主)) - 被寻址的从机发送应答信号回应主机。
- 发送器发送一个字节数据。
- 接收器发送应答信号回应发送器。
- 重复执行
4~5步。 - 通信完成后,主机发送停止信号释放总线(其他器件收到该停止信号后,就可以作为主机启用该
IIC总线)。
SPI协议
SPI是串行外设接口的缩写,SPI是一种高速的,全双工的,同步的串行通信总线。SPI至少有4根线:MISO(主设备输入从设备输出),MOSI(主设备输出从设备输入),SCLK(时钟线),CS(片选)。SPI使用引脚较少且布线方便,因此越来越多的芯片集成了这个通信协议。
注意:主机通过片选信号线CS来选择与之通信的从机。
SPI通信过程
SPI总线在进行数据传送时,先传送高位后传送低位,高电平表示逻辑"1",低电平表示逻辑"0",一个字节传送完成后无需应答即可开始下一个字节的传送。SPI总线在进行数据传送时,当时钟线SCLK在下降沿时,发送器发送数据,在上升沿时,接收器读取数据。SPI没有起始信号,终止信号,应答信号之类的。发完一个字节数据后可以直接继续发下一个字节的数据。
SPI极性与相位
极性CPOL:表示SCLK(时钟线)空闲时的状态。
- CPOL=0,SCLK空闲时为低电平。
- CPOL=1,SCLK空闲时为高电平。
相位的采样CPHA:表示采样时刻(即读数据)。
- CPHA=0,每个周期的第一个时钟沿采样(读数据)。
- CPHA=1,每个周期的第二个时钟沿采样(读数据)。
注意:IIC与SPI均说采用TTL电平。
MQTT协议
MQTT协议是一种轻量级、高效的发布/订阅模式通信协议,专为低带宽、高延迟或不可靠网络环境设计(如物联网IoT场景),主要应用在物联网,小型设备,移动应用。(MQTT协议的端口号一般是1883)
发布者与订阅者关系:
- 传感器收集到了数据,将数据发送到了
mqtt云上,这个时候,传感器就叫发布者,mqtt云就叫代理服务器。- 其他设备想要获取传感器数据,就需要提前告诉
mqtt云:我需要这个传感器的数据。这种行为就叫订阅,该设备就叫订阅者。- 当
mqtt云收到指定传感器的数据时,就会自动将其数据发送给订阅了该传感器的设备。
发布者与代理
连接
- 发布者向代理发送连接请求,代理接受连接请求,连接成功。
- 发布者与代理预定好时间,每隔目标时间,发布者发送一次心跳,代理接收到心跳,就会进行心跳响应,如果代理在目标时间间隔没有收到心跳,则默认该发布者已经不在了,因此会自动断开与该发布者的连接。
- 若发布者想要断开与代理的连接,只需要向代理发送关闭的请求。
QOS消息等级
发布者向代理发送消息,有以下几个优先级:
QoS0: 代理接收到该消息时,不需要应答,因此该优先级常常用来传递一些不太重要的消息。QoS1: 代理接收到该消息时,必须要应答,即向发布者发送确认收到的信号,如果发布者未收到确认信号,则其会继续向代理发送相同消息,直到收到一次确认信号为止。QoS2: 发布者发送消息,代理接收到该消息后,必须要应答,当发布者接收到应答信号后,就会发送信息发送结束的信号(即发布释放),代理收到发布释放信号后,也会向发布者发送发布完成信号,在这个过程中,双方如果没有收到对应的信号就会一直等待,直到收到为止。
订阅者与代理
订阅者与代理之间的连接、消息优先级和发布者与代理之间的情况完全相同。
注意:订阅者可以向代理发出
订阅或取消订阅某个发布者 的请求。
MQTT协议格式
MQTT协议是基于TCP和IP协议来设计封装的。
固定报头
MQTT协议的重点是TCP首部后面的2字节的固定报头。
下面是固定报头的第一个字节:
如上图所示,第一个字节
高4位用于标识该报文的类型,共有16种类型,最低位用于标记该条消息应不应该保存到服务端(若保存,则该条消息会发给未来的订阅者),第1,2位表示该条消息的QOS等级,第3位标识该条消息是否是重发消息。
下面是固定报头的第二个字节:
如上图所示,理论上MQTT的固定报头最多可以有5个字节,但其实从第二个字节开始,就是在记录该消息所携带的数据的长度,每个字节(从第二个字节开始)最高位用来标识是否有下一个字节,剩余六位用来记录数据的长度,因此MQTT理论上最长可携带128*4个字节的数据。
可变报头
一般请求的可变报头都非常的简单,但连接请求的可变报头相对复杂,因此这里重点讲一下。
如上图所示,连接请求的可变报头至少有10个字节:
- 首先是协议名,共占6个字节,前两个字节以字符的形式来说明协议名的长度,如
"04"表示协议名长4个字节。协议名:"MQTT"。这六个字节全是utf-8编码的字符。 - 然后就是协议级别,占1个字节。
- 连接标准,占1个字节,该字节的每一位都携带对应的数据,所谓遗嘱,即是该发布者在断开与代理的连接后,向所有订阅者发布的最后消息。
新开始表示该连接是不是第一次连接(因为连接可能是断后重连)。 - 保持连接,占2个字节,
表示发布者向代理发送心跳的时间间隔,"060"表示间隔60秒。 - 属性,该部分内容必须是
MQTT 5.0以上版本才能具有的,属于新特性,因此一般不进入传统统计,这里也不详细解释。