概述

UART(Universal Asynchronous Receive Transmitter)

通用异步收发器,即我们经常所说的串口,基本都用于调试。UART通信方式需要两根数据线RXTX和地线GND。TX是用来发送数据,RX是用来接收数据,因为有两根数据线,收和发可以同时进行,所以它是全双工通信。

IIC(Inter Integrated Circuit)

IIC通信方式需要一根时钟线SCL和数据线SDA,由于其只有一根数据线,只能进行分时收发,所以是半双工通信,两条线上可以挂载许多设备,不同的设备以不同的IIC地址来区分。

SPI(Serial Peripheral Interface,)

串行外设接口,是摩托罗拉开发的全双工同步串行总线;SPI 接口由SDI(串行数据输入),SDO(串行数据输出),SCK(串行移位时钟),CS(从使能信号)四种信号构成,如没有CS 信号,则只能存在一个从设备,主设备通过产生移位时钟来发起通讯。通讯时,数据由SDO 输出,SDI 输入,数据在时钟的上升或下降沿由SDO 输出,在紧接着的下降或上升沿由SDI 读入,这样经过8/16 次时钟的改变,完成8/16 位数据的传输。

工作方式

UART

时序图

工作原理

发送数据过程

空闲状态,线路处于高电位;当收到发送数据指令后,拉低线路一个数据位的时间 T,接着数据按低位到高位依次发送,数据发送完毕后,接着发送奇偶校验位和停止位(停止位为高电位),一帧数据发送结束。

接收数据过程

空闲状态,线路处于高电位;当检测到线路的下降沿(线路电位由高电位变为低电位)时说明线路有数据传输,按照约定的波特率从低位到高位接收数据,数据接收完毕后,接着接收并比较奇偶校验位是否正确,如果正确则通知后续设备准备接收数据或存入缓存。由于UART是异步传输,没有传输同步时钟。为了能保证数据传输的正确性,UART 采用 16 倍数据波特率的时钟进行采样。每个数据有 16 个时钟采样,取中间的采样值,以保证采样不会滑码或误码。一般 UART 一帧的数据位数为 8,这样即使每个数据有一个时钟的误差,接收端也能正确地采样到数据。

接收数据时序

当检测到数据的下降沿时,表明线路上有数据进行传输,这时计数器CNT开始计数,当计数器为24=16+8 时,采样的值为第0位数据;当计数器的值为40时,采样的值为第1位数据,依此类推,进行后面6个数据的采样。如果需要进行奇偶校验,则当计数器的值为152时,采样的值即为奇偶位;当计数器的值为 168 时,采样的值为”1”表示停止位,一帧数据接收完成。一个标准的10位异步串行通信协议(包含1个起始位、1个停止位和8个数据位)收发时序,如下:

SPI

接口

SPI通信以主从方式工作,需要至少3根线,存在多个从设备时,则需要第4根线CS来选择从设备。

SDO 主设备数据输出,从设备数据输入
SDI 主设备数据输入,从设备数据输出
SCLK 时钟信号,由主设备产生
CS 从设备使能信号,由主设备控制

工作原理

SPI是串行同步通讯协议,数据是一位一位的传输的。这就是SCLK时钟线存在的原因,SCLK提供同步的时钟脉冲,SDI,SDO则基于同步时钟完成数据传输。数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取,完成一位数据传输。因此,至少需要8次时钟信号的改变(上升沿和下降沿为一次),才能完成8位数据的传输。

特点

SCLK信号线只由主设备控制,从设备不能控制信号线,在基于SPI的通信中,至少有一个主控设备。这样的传输方式有一个优点,SPI允许数据一位一位的传送,甚至允许暂停,因为SCLK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCLK时钟线的控制可以完成对通讯的控制。另外,SPI是全双工同步数据传输,数据传输速率很高,可达到50MHz。

但是,SPI接口有一个缺点,其没有指定的流控制,没有应答机制确认是否接收到数据。

IIC

IIC 接口的协议里面包括设备地址信息,IIC总线是一个真正的多主机总线,可以同一总线上连接多个从设备,通过应答来互通数据及命令。

数据协议

假设A给B发数据,A->SCL接B->SCL, A->SDA接B->SDA。起初SDA和SCL上的电平都为高电平,接着A先把SDA拉低,等SDA变为低电平后再把SCL拉低,以上两个动作构成了IIC协议的起始位,此时SDA就可以发送数据了。与此同时,SCL发送一定周期的脉冲(周期和PCLK有关,一般会在IIC的控制寄存器中设置)。SDA发送数据和SCL发送脉冲要符合的关系是:SDA必须在SCL是高电平时保持有效,在SCL是低电平时发送下一位,而SCL会在上升沿对SDA进行采样。规定一次必须传8位数据,8位数据传输结束后A释放SDA,但SCL会再发一个脉冲,这会触发B通过将SDA置为低电平表示确认。最后SCL先变为高电平,SDA再变为高电平,这就构成了是IIC协议的结束标志。如果B没有将SDA置为低电平,则A停止发送下一帧数据。

IIC总线上的每个设备都有唯一地址,数据包传输时先发送地址位,接着才发送数据。一个地址字节由7个地址位和1个指示位组成,总共可以挂载128个设备。指示位是0表示写操作,1表示读操作。还有10位寻址模式,使用两个字节来保存地址,第一个字节的最低两位和第二个字节的8位合起来构成10位地址。

完整数据传输

特点

  1. 需严格按照时序图的要求进行操作;
  2. 若与口线上带内部上拉电阻的单片机接口连接,可以不外加上拉电阻;
  3. 程序中为配合相应的传输速率,在对口线操作的指令后可用NOP指令加一定的延时;
  4. 为了减少意外的干扰信号将EEPROM内的数据改写可用外部写保护引脚(如果有),或者在EEPROM内部没有用的空间写入标志字,每次上电时或复位时做一次检测,判断EEPROM是否被意外改写。
  5. 对IIC总线的一次操作完之后,需要等待一段时间才能进行第二次操作,否则是启动不了总线的;
  6. 在时钟线(SCL)为高电平的时候,一定不能动数据线(SDA)状态,除非是启动或者结束总线;
  7. IIC传输速率有限,标准模式下可达到100Kbps,快速模式下可达到400Kbps,高速模式下达到4Mbps,不能实现全双工,不适合传输大量数据。

区别和联系

总结

  1. SPI总线由三条信号线组成:串行时钟(SCLK)、串行数据输出(SDO)、串行数据输入(SDI)。SPI总线可以实现多个SPI设备互相连接。提供SPI串行时钟的SPI设备为SPI主机或主设备(Master),其他设备为SPI从机或从设备(Slave)。主从设备间可以实现全双工通信,当有多个从设备时,还可以增加一条从设备选择线(片选)。

    如果用通用IO口模拟SPI总线,必须要有一个输出口(SDO),一个输入口(SDI),另一个口则视实现的设备类型而定,如果要实现主从设备,则需输入输出口,若只实现主设备,则需输出口即可,若只实现从设备,则只需输入口即可。

  2. IIC总线是双向、两线(SCL、SDA)、串行、多主控(multi-master)的接口标准,具有总线仲裁机制,非常适合在器件之间进行近距离、非经常性的数据通信。在它的协议体系中,传输数据时都会带上目的设备的设备地址,因此可以实现设备组网

    如果用通用IO口模拟IIC总线,并实现双向传输,则需一个输入输出口(SDA),另外还需一个输出口(SCL)。

  3. UART总线异步串口,因此一般比前两种同步串口的结构要复杂很多,一般由波特率产生器(产生的波特率等于传输波特率的16倍)、UART接收器、UART发送器组成,硬件上由两根线,一根用于发送,一根用于接收。

    显然,如果用通用IO口模拟UART总线,则需一个输入口,一个输出口。

比较

  1. SPI和UART可以实现全双工,但IIC不行;

  2. IIC线更少,我觉得比UART、SPI更为强大,但是技术上也更加麻烦些,因为IIC需要有双向IO的支持,而且使用上拉电阻,但是抗干扰能力较弱,一般用于同一板卡上芯片之间的通信,较少用于远距离通信。SPI实现则要简单一些,UART需要固定的波特率,就是说两位数据的间隔要相等,而SPI则无所谓,因为它是有时钟的协议;

  3. IIC的速度比SPI慢一点,协议比SPI复杂一点,但是连线也比标准的SPI要少;

  4. UART一帧可以传5/6/7/8位,IIC必须是8位;

  5. SPI用片选信号选择从机,IIC用地址选择从机。

    … …




    • end