通信协议
通信协议
IIC
概念
IIC,一种串行数据总线,只有两根信号线,一根双向数据线SDA,一根时钟线SCL。数据线位宽为1bit,因而IIC传输数据时是一个bit一个bit来传输的。IIC的两根线上可以挂靠多个设备,我们把其中控制时钟线的设备叫做主设备,其他的是从设备。每个IIC设备都有个固话的地址,主设备根据此地址值来确定要通信的从设备。
IIC只有两个信号线: 一条是双向的串行数据线SDA,一条是串行时钟线SCL
- SDA (Serial data) 是数据线,D代表Data也就是数据,Send Data 也就是用来传输数据的
- SCL (Serial clock line) 是时钟线,C代表Clock 也就是时钟 也就是控制数据发送的时序的
协议层
IIC在传输数据过程中共有3种类型信号,开始信号、停止信号、ACK信号。
- 开始:SCL保持高电平,SDA由高到低,表明一个开始信号。
- 停止:SCL保持高电平,SDA由低到高,表明一个停止信号。
- ACK:单片机发完8bit数据后不再驱动总线,SDA和SCL的硬件设计都有上拉电阻,会把SDA变成高电平。在第8个bit,外接IIC设备接收到信号,就会在第9个bit把SDA拉低,处理器监测到SDA拉低就知道外接IIC设备数据已经收到。这个被拉低的bit被认为是一个ACK信号。
数据有效性
IIC信号在数据传输过程中,当SCL为高电平时,数据线SDA必须保持稳定状态,不允许有电平跳变,只有在SCL为低电平期间,数据线上的高电平或低电平状态才允许变化。SCL高电平时,数据线SDA的任何电平变换会看做是总线的起始信号或者停止信号。
应答信号
- 应答信号为低电平时,规定为有效应答位(ACK),表示接收器已经成功地接收了该字节。
- 应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。
数据传送
数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。当一个字节按数据位从高位到低位的顺序传输完后,紧接着从设备将拉低SDA线,回传给主设备一个应答位ACK, 此时才认为一个字节真正的被传输完成,如果一段时间内没有收到从机的应答信号,则自动认为从机已正确接收到数据。
多数从设备的地址为7位或者10位,一般都用七位。八位设备地址=7位从机地址+读/写地址。
- 0表示主设备向从设备(write)写数据
- 1表示主设备向从设备(read)读数据
帧格式
IIC的每一帧数据由9bit组成
- 发送数据:8bit数据 + 1bit ACK
- 设备地址数据:8bit数据为7bit设备地址 + 1bit方向
主机向从机写数据
- 主机首先产生START信号
- 然后紧跟着发送一个从机地址,这个地址共有7位,紧接着的第8位是数据方 向位(R/W),0表示主机发送数据(写),1表示主机接收数据(读)
- 主机发送地址时,总线上的每个从机都将这7位地址码与自己的地址进行比较,若相同,则认为自己正在被主机寻址,根据R/T位将自己确定为发送器和接收器
- 这时候主机等待从机的应答信号(A)
- 当主机收到应答信号时,发送要访问从机的那个地址, 继续等待从机的应答信号
- 当主机收到应答信号时,发送N个字节的数据,继续等待从机的N次应答信号
- 主机产生停止信号,结束传送过程
主机读从机数据
- 主机首先产生START信号
- 然后紧跟着发送一个从机地址,注意此时该地址的第8位为0,表明是向从机写命令
- 这时候主机等待从机的应答信号(ACK)
- 当主机收到应答信号时,发送要访问的地址,继续等待从机的应答信号
- 当主机收到应答信号后,主机要改变通信模式(主机将由发送变为接收,从机将由接收变为发送)所以主机重新发送一个开始start信号,然后紧跟着发送一个从机地址,注意此时该地址的第8位为1,表明将主机设 置成接收模式开始读取数据
- 这时候主机等待从机的应答信号,当主机收到应答信号时,就可以接收1个字节的数据,当接收完成后,主机发送非应答信号,表示不在接收数据
- 主机进而产生停止信号,结束传送过程
SPI
介绍
SPI是一种高速的、全双工、同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。
主从模式
SPI分为主、从两种模式,一个SPI通讯系统需要包含一个(且只能是一个)主设备,一个或多个从设备。提供时钟的为主设备(Master),接收时钟的设备为从设备(Slave),SPI接口的读写操作,都是由主设备发起。当存在多个从设备时,通过各自的片选信号进行管理。
信号线
SPI一般使用四条信号线通信:SDI(数据输入),SDO(数据输出),SCK(时钟),CS(片选)
- MISO:主设备输入/从设备输出引脚。该引脚在主模式下接收数据,在从模式下发送数据。
- MOSI:主设备输出/从设备输入引脚。该引脚在主模式下发送数据,在从模式下接收数据。
- SCLK:串行时钟信号,由主设备产生。
- CS:从设备片选信号,由主设备控制。它的功能是用来作为“片选引脚”,也就是选择指定的从设备,让主设备可以单独地与特定从设备通讯,避免数据线上的冲突。
设备选择
SPI是单主设备(single-master)通信协议,这意味着总线中只有一个设备能发起通信。当SPI主设备想读/写从设备时,它首先拉低从设备对应的CS线(CS是低电平有效),接着开始发送工作脉冲到时钟线上,在相应的脉冲时间上,主设备把信号发到MOSI实现“写”,同时可对MISO采样而实现“读”。
数据发送接收
SPI主机和从机都有一个串行移位寄存器,主机通过向它的SPI串行寄存器写入一个字节来发起一次传输。
- 首先拉低对应SS信号线,表示与该设备进行通信
- 主机通过发送SCLK时钟信号,来告诉从机写数据或者读数据。(SCLK时钟信号可能是低电平有效,也可能是高电平有效,因为SPI有四种模式)
- 主机(Master)将要发送的数据写到发送数据缓存区(Menory),缓存区经过移位寄存器(0~7),串行移位寄存器通过MOSI信号线将字节一位一位的移出去传送给从机,,同时MISO接口接收到的数据经过移位寄存器一位一位的移到接收缓存区。
- 从机(Slave)也将自己的串行移位寄存器(0~7)中的内容通过MISO信号线返回给主机。同时通过MOSI信号线接收主机发送的数据,这样,两个移位寄存器中的内容就被交换。
SPI只有主模式和从模式之分,没有读和写的说法,外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。也就是说,你发一个数据必然会收到一个数据;你要收一个数据必须也要先发一个数据。
SPI通信的四种模式
通过CPOL(时钟极性)和CPHA(时钟相位)来控制我们主设备的通信模式。
时钟极性(CPOL)定义了时钟空闲状态电平:
- CPOL=0,表示当SCLK=0时处于空闲态,所以有效状态就是SCLK处于高电平时
- CPOL=1,表示当SCLK=1时处于空闲态,所以有效状态就是SCLK处于低电平时
时钟相位(CPHA)定义数据的采集时间:
- CPHA=0,在时钟信号SCK的第一个跳变沿采样
- CPHA=1,在时钟信号SCK的第二个跳变沿采样
时钟极性通常写为CKP或CPOL,时钟相位通常写为CKE或CPHA。
UART
UART,全称Universal Asynchronous Receiver/Transmitter,通用异步收发传输器。
USART,全称Universal Synchronous/Asynchronous Receiver/Transmitter,通用同步异步收发传输器。
两者都是一个数据收发器,属于硬件电路范畴。UART使用异步通信,而USART既可异步通信,也可同步通信。当USART使用异步通信时,就变成了UART。单片机的串口指的就是UART或USART。
数据包
UART传输的数据被封装成数据包。每个数据包包含1个起始位,5~9个数据位(取决于UART的具体设置),一个可选的奇偶校验位以及1个或2个停止位,具体如下图所示:
起始位
UART数据传输线通常在不传输数据时保持在高电平。为了开始数据传输,发送端UART在一个时钟周期内将传输线从高电平拉低到低电平。当接收端UART检测到高电压到低电压转换时,它开始以波特率的频率读取数据位中的每一位数据。
数据
数据位包含正在传输的实际数据。如果使用奇偶校验位,则可以是5位,最多8位。如果不使用奇偶校验位,则数据帧的长度可以为9位。在大多数情况下,数据首先以低有效位发送。
校验位
串口通信有四种校验方式:偶校验、奇校验、高校验和低校验。当然没有校验位也是可以的。对于偶和奇校验的情况,串口会设置校验位,用一个值确保传输的数据有偶个或者奇个逻辑高位。
高位和低位不是真正的检查数据,而是强行将校验位设置为逻辑高或者逻辑低。这样使得接收设备能够知道一个位的状态,有机会判断是否有噪声干扰了通信或者是否传输和接收数据是否不同步。
停止位
发送端UART将数据传输线从低电压驱动到高电压至少持续两位数据的时间宽度来表示整个数据包的传输已经结束。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。停止位不仅仅表示传输的结束,并且提供了校正时钟同步的机会。停止位的位数越多,不同时钟同步的容错性越好,但是数据传输率同时也越慢。
波特率
波特率是串口数据的传输速度,即Bit/s,常见的波特率有:9600,19200,38400,57600,115200。
设目前UART的配置为,1个起始位,8个数据位,0个校验位,1个停止位,那么9600的波特率,可以计算出每位数据的时间宽度为:
$$T = \frac{1}{9600} = 0.000104s = 104us$$
那么传输一个字节(10位)则需要$1.04ms$
物理层
- TTL
UART、RS232、RS485在串口通信中,主要区别是电平的不同,其中UART通常使用TTL电平,TTL全名是晶体管-晶体管逻辑集成电路(Transistor-Transistor Logic)。- 逻辑1为+5V
- 逻辑0为0V
- RS232
- 逻辑1为-3V~-15V
- 逻辑0为+3V~+15V
- RS485
RS485是差分信号进行串行传输,在工业通信中,使用RS485比较多,因为RS485是差分信号,可以抑制共模干扰,因此在恶劣的环境中拥有很好的抗干扰性,比较稳定。- 逻辑1以两线间的电压差为+(2~6)V表示
- 逻辑0以两线间的电压差为-(2~6)V表示