嵌入式底层通讯协议原理(SPI,UART,I2C)

一大罐白云 2020/9/16
连接:http://www.javashuo.com/article/p-qpoqetla-mu.htmlhtml

SPI

SPI(Serial Peripheral Interface)串行外围设备接口是许多不一样设备使用的通用通讯协议。例如, SD卡模块, RFID卡读取器模块和 2.4 GHz无线发送器/接收器 均使用SPI与微控制器通讯。
SPI的一个独特优点是能够无中断传输数据。能够在连续流中发送或接收任意数量的位。使用I2C和UART,数据以数据包形式发送,限制为特定位数。开始和中止条件定义了每一个数据包的开始和结束,所以数据在传输过程当中被中断。
经过SPI通讯的设备处于主从关系。主机是控制设备(一般是微控制器),而从机(一般是传感器,显示器或存储芯片)从主机获取指令。SPI的最简单配置是一个主机,一个从机系统,可是一个主机能够控制多个从机(下面有更多介绍)。

MOSI(主机输出/从机输入) –主机将数据发送到从机的线路。安全

MISO(主机输入/从机输出) –从机将数据发送到主机的线路。异步

SCLK(时钟) –时钟信号线。ui

SS / CS(从站选择/芯片选择) –主站用于选择向其发送数据的从站的线路。
params
实际上,从站的数量受到系统负载电容的限制,这下降了主机在电压电平之间准确切换的能力。spa

SPI如何运做

时钟

时钟信号将主设备的数据位输出同步到从设备的位采样。每一个时钟周期传输一位数据,所以数据传输的速度取决于时钟信号的频率。因为主机配置并生成时钟信号,因此SPI通讯始终由主机启动3d

设备共享时钟信号的任何通讯协议都称为同步SPI是一种同步通讯协议。还有一些 异步方法不使用时钟信号。例如,在UART通讯中,将双方都设置为指示数据传输速度和时序的预配置波特率。htm

可使用时钟极性时钟相位的属性来修改SPI中的时钟信号。这两个属性共同定义什么时候输出位以及什么时候对其进行采样。主机能够设置时钟极性,以容许在时钟周期的上升沿或降低沿输出和采样位。能够设置时钟相位,以便在时钟周期的第一沿或第二沿进行输出和采样,而无论它是上升仍是降低。blog

从设备选择

主机能够经过将从机的CS / SS线设置为低电压电平来选择要与之通讯的从机。在空闲,非传输状态下,从选择线保持在高电压电平。主机上可能有多个CS / SS引脚,这容许多个从机并行链接。若是仅存在一个CS / SS引脚,则能够经过菊花链将多个从机链接到主机。接口

多个从设备

能够将SPI设置为与单个主机和单个从机一块儿运行,也能够与由单个主机控制的多个从机一块儿设置。有两种方法能够将多个从站链接到主站。若是主站有多个从站选择引脚,则从站能够按如下方式并联:

若是只有一个从设备选择引脚可用,则能够经过如下方式菊花链链接从设备:
图片

MOSI和MISO

主机经过MOSI线以串行方式将数据发送到从机。从机经过MOSI引脚接收主机发送的数据。从主机发送到从机的数据一般先发送最高有效位。

从机还能够经过MISO线串行将数据发送回主机。从从机发送回主机的数据一般首先以最低有效位发送。

SPI的读像是发一个数据那样简单,整个总线须要的时钟信号是由主机端提供的,也就是说不管是给从机发数据或者从从机读数据,时钟信号都须要由主机来产生,主机要读数据的时候须要给从机时钟信号,这个信号只能是在主机发数据的时候产生,这样就须要主机发一个数据,这样就产生了时钟信号,从机就会把数据放到总线上来了。为了不这个假发出去的数据让从机误动做,通常都是让主机为高电平。

SPI数据传输步骤

  1. 主机输出时钟信号:
  2. 主机将SS / CS引脚切换到低电压状态,从而激活从机:
  3. 主机沿着MOSI线路一次将数据发送到从机。从站读取接收到的位:
  4. 若是须要响应,则从机沿着MISO线一次向主机返回一位数据。主机读取接收到的位:

SPI的优缺点

使用SPI有一些优势和缺点,若是在不一样的通讯协议之间进行选择,则应根据项目要求知道什么时候使用SPI:

优势

  • 没有起始位和中止位,所以能够连续传输数据而不会中断
  • 没有像I2C这样复杂的从站寻址系统
  • 数据传输速率比I2C更高(几乎快两倍)
  • 分开的MISO和MOSI线路,所以能够同时发送和接收数据

缺点

  • 使用四根线(I2C和UART使用两根线)
  • 没有确认已成功接收数据的确认(I2C拥有此确认)
  • 没有任何形式的错误检查,如UART中的奇偶校验位
  • 只容许一个主机

UART

UART表明通用异步接收器/发送器(Universal Asynchronous Receiver/Transmitter)。它不是像SPI和I2C这样的通讯协议,而是微控制器中的物理电路或独立的IC。UART的主要目的是发送和接收串行数据。

关于UART的最大的优势之一是它仅使用两条线在设备之间传输数据

在UART通讯中,两个UART直接相互通讯。发送UART未来自控制设备(如CPU)的并行数据转换为串行形式,以串行方式将其发送到接收UART,而后接收UART将接收到的串行数据转换回并行数据。只须要两条线就能够在两个UART之间传输数据。数据从发送UART的Tx引脚流到接收UART的Rx引脚:

UART 异步传输数据,这意味着没有时钟信号将发送UART的位输出与接收UART的位采样同步。发送UART代替时钟信号,将开始中止位添加到正在传输的数据包中。这些位定义了数据包的开始和结束,所以接收UART知道什么时候开始读取这些位。

当接收UART检测到起始位时,它将开始以称为波特率的特定频率读取输入位。波特率是数据传输速度的度量,以每秒位数(bps)表示。 两个UART必须以大约相同的波特率工做。在位的时序变得太远以前,发送和接收UART之间的波特率只能相差约10%。

还必须将两个UART配置为发送和接收相同的数据包结构。

UART如何运做

将要发送数据的UART从数据总线接收数据。数据总线用于经过其余设备(例如CPU,内存或微控制器)将数据发送到UART。数据以并行形式从数据总线传输到发送UART(电路实现参考数字电路多功能移位寄存器)。发送UART从数据总线获取并行数据后,它将添加起始位,奇偶校验位和中止位,以建立数据包。接下来,数据包在Tx引脚上逐位串行输出。接收UART在其Rx引脚上逐位读取数据包。而后,接收UART将数据转换回并行形式,并删除起始位,奇偶校验位和中止位。最后,接收UART将数据包并行传输到接收端的数据总线:

UART传输的数据被组织成数据包。每一个数据包包含1个起始位,5至9个数据位(取决于UART),一个可选的奇偶校验位以及1个或2个中止位:

起始位

UART数据传输线一般在不传输数据时保持在高电压电平。为了开始数据传输,发送UART在一个时钟周期内将传输线从高电平拉低到低电平。当接收UART检测到高到低电压转换时,它开始以波特率的频率读取数据帧中的位。

数据帧

数据帧包含正在传输的实际数据。若是使用奇偶校验位,则能够是5位,最多8位。若是不使用奇偶校验位,则数据帧的长度能够为9位。在大多数状况下,数据首先以最低有效位发送。

奇偶校验

奇偶性描述数字的偶数或奇数。奇偶校验位是接收UART判断传输期间是否有任何数据更改的方式。电磁辐射,不匹配的波特率或长距离数据传输会改变数据位。接收UART读取数据帧后,它将对值为1的位数进行计数,并检查总数是偶数仍是奇数。若是奇偶校验位为0(偶数奇偶校验),则数据帧中的1位应总计为偶数。若是奇偶校验位为1(奇校验),则数据帧中的1位应合计为奇数。当奇偶校验位与数据匹配时,UART知道传输没有错误。可是,若是奇偶校验位为0,则总数为奇数;或奇偶校验位为1,且总数为偶数,则UART知道数据帧中的位已更改。

中止位

为了用信号通知数据包的结束,发送UART将数据传输线从低电压驱动到高电压至少持续两位时间。

UART传输步骤

  1. 发送UART从数据总线并行接收数据:
  2. 发送UART将起始位,奇偶校验位和中止位添加到数据帧:
  3. 整个数据包从发送UART串行发送到接收UART。接收UART以预先配置的波特率对数据线进行采样:
  4. 接收UART丢弃数据帧中的起始位,奇偶校验位和中止位:
  5. 接收UART将串行数据转换回并行数据,并将其传输到接收端的数据总线:

UART的优缺点

如下是一些利弊,可帮助您肯定它们是否适合您的项目需求:

优势

  • 仅使用两根电线
  • 无需共用时钟信号
  • 具备奇偶校验位以容许进行错误检查
  • 须要双方都设置好数据包的结构
  • 文档可查并应用普遍

缺点

  • 数据帧的大小最大为9位
  • 不支持多个从属系统或多个主系统
  • 每一个UART的波特率必须在彼此的10%以内

I2C

若是您参与过使用OLED显示器,气压传感器或陀螺仪/加速度计模块的项目,则可能会发现本身使用的是I2C。

I2C结合了SPI和UART的最佳功能。使用I2C,您能够将多个从机链接到单个主机(如SPI),而且能够有多个主机控制一个或多个从机。当您但愿有多个微控制器将数据记录到单个存储卡或将文本显示到单个LCD时,此功能很是有用。

与UART通讯同样,I2C仅使用两条线在设备之间传输数据:

SDA(串行数据) –主站和从站发送和接收数据的线路。

SCL(串行时钟) –传送时钟信号的线。

I2C是串行通讯协议,所以数据沿着单条线(SDA线)单个比特意传输。

像SPI同样,I2C是同步的,所以位输出经过主机和从机之间共享的时钟信号同步到位采样。时钟信号始终由主机控制。

I2C如何运做

使用I2C,数据以消息形式传输 。消息被分解 为数据帧。每条消息都有一个包含从站的二进制地址的地址帧,以及一个或多个包含正在发送的数据的数据帧。该消息还包括每一个数据帧之间的开始和中止条件,读/写位和ACK / NACK位:

启动条件: 在SCL线从高电平切换到低电平以前 ,SDA线从高压电平切换到低压电平 。

中止条件: SCL线从低切换到高后, SDA线从低电压切换到高电压 。

地址帧: 每一个从属设备惟一的7位或10位序列,用于在主设备要与其通讯时标识该从属设备。

读/写位: 一位,指定主机是向从机发送数据(低电压)仍是向从机请求数据(高电压)。

ACK / NACK位: 消息中的每一个帧后均带有一个确认/不确认位。若是成功接收到地址帧或数据帧,则会从接收设备向发送方返回ACK位。

寻址

I2C没有像SPI这样的从设备选择线,所以它须要另外一种方式来让从设备知道正在向其发送数据,而不是另外一个从设备。它经过寻址来实现。地址帧始终是新消息中起始位以后的第一帧。

主机将要与之通讯的从机的地址发送给与其链接的每一个从机。而后,每一个从站将从主站发送的地址与其本身的地址进行比较。若是地址匹配,它将向主机发送一个低电压ACK位。若是地址不匹配,则从站不执行任何操做,而且SDA线保持高电平。

读/写位

地址帧的末尾包含单个位,该位通知从设备主机是否要向其写入数据或从中接收数据。若是主机要向从机发送数据,则读/写位为低电压电平。若是主机正在从机请求数据,则该位为高电压电平。

数据帧

主机检测到从机的ACK位后,便可发送第一个数据帧。

数据帧始终为8位长,并以最高有效位优先发送。每一个数据帧后紧跟一个ACK / NACK位,以验证是否已成功接收到该帧。在发送下一个数据帧以前,主机或从机必须接收ACK位(取决于谁发送数据)。

发送完全部数据帧后,主机能够向从机发送中止条件以中止传输。中止条件是SCL线上从低到高的转换以后,SDA线上的电压从低到高的转换,而SCL线保持高电平。

I2C数据传输步骤

  1. 在将SCL线从高电平切换到低电平以前,主机经过将SDA线从高电平切换到低电平来向每一个链接的从机发送启动条件:
  2. 主机向每一个从机发送要与之通讯的从机的7位或10位地址,以及读/写位:
  3. 每一个从机将主机发送的地址与其本身的地址进行比较。若是地址匹配,则从机经过将SDA线拉低一位返回一个ACK位。若是来自主机的地址与从机自身的地址不匹配,则从机将SDA线拉高:
  4. 主机发送或接收数据帧:
  5. 传输完每一个数据帧后,接收设备将另外一个ACK位返回给发送方,以确认已成功接收到该帧:
  6. 为了中止数据传输,主机将SCL切换为高电平,而后再将SDA切换为高电平,从而向从机发送中止条件:

单个主机具备多个从机

因为I2C使用寻址,所以能够从一个主机控制多个从机。使用7位地址时,可使用\(2^7=128\)个惟一地址。使用10位地址并不常见,可是会提供\(2^{10}=1024\)个惟一地址。要将多个从机链接到单个主机,请使用\(4.7K\Omega\)上拉电阻将它们链接,将SDA和SCL线链接到Vcc:

多个主机具备多个从机

多个主机能够链接到一个或多个从机。当两个主机尝试经过SDA线路同时发送或接收数据时,会出现同一系统中多个主机的问题。为了解决这个问题,每一个主机都须要在发送消息以前检测SDA线是低电平仍是高电平。若是SDA线为低电平,则意味着另外一个主机能够控制总线,而且主机应等待发送消息。若是SDA线为高电平,则能够安全地发送消息。要将多个主机链接到多个从机,请使用下图,其中\(4.7K\Omega\)上拉电阻将SDA和SCL线链接到Vcc:

I2C的优缺点

优势

  • 仅使用两根电线
  • 支持多个主机和多个从机
  • ACK / NACK位用于确认每一个帧都已成功传输
  • 硬件不如使用UART复杂
  • 众所周知且应用普遍

缺点

  • 数据传输速率比SPI慢
  • 数据帧的大小限制为8位
  • 须要实现比SPI更复杂的硬件

参考资料

图片来源于:https://www.circuitbasics.com/