通信方式对比—UART/SPI/IIC
一、UART
UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是一种非常基础且广泛使用的串行通信协议。它不是像SPI或I²C那样的“总线”,而通常是一种点对点的通信方式。几乎所有的微控制器和计算机都包含UART硬件,它也是我们最常接触到的调试接口(例如通过USB转串口模块在电脑上查看单片机的打印信息)。
1. UART的核心概念
- 通用(Universal): 意味着它的通信参数(如速度、数据位、校验位等)是可配置的,可以与各种不同的设备进行通信。
- 异步(Asynchronous): 这是UART最核心的特点。与SPI和I²C不同,UART通信的双方没有共享的时钟线。发送方和接收方必须事先约定好相同的通信速率(波特率),接收方依靠数据信号本身的变化(起始位)来开始同步并按约定的速率接收数据。
- 收发器(Receiver/Transmitter): UART硬件模块通常包含一个独立的接收器和一个独立的发送器,因此可以同时进行数据的接收和发送,实现 全双工(Full-Duplex) 通信。
2. UART的硬件接口
UART通信最少只需要两根线:
引脚名称 | 功能描述 |
---|---|
TX (Transmit) | 发送数据线。发送设备的数据从该引脚输出。 |
RX (Receive) | 接收数据线。接收设备的数据从该引脚输入。 |
连接方式:
为了实现双向通信,两台设备的连接方式是交叉连接:
- 设备A的
TX
连接到 设备B的RX
- 设备A的
RX
连接到 设备B的TX
- 通常还需要一根 地线(GND) 来提供共同的参考电平,保证信号的正确识别。所以,最基本的UART通信是三线制(TX, RX, GND)。
3. UART的数据帧格式(The Protocol)
由于没有时钟线,UART通过一种标准的数据包结构(称为“帧”)来确保数据的正确解析。一个UART数据帧通常包含以下几个部分:
- 空闲状态(Idle State): 在没有数据传输时,TX线保持在高电平。
- 起始位(Start Bit):
- 通信的开始信号。
- 发送方将TX线从高电平拉低,并保持一个时钟周期的时间。
- 这个下降沿告诉接收方:“注意,数据要来了!”。接收方检测到这个下降沿后,会启动自己的内部时钟,准备在后续的特定时间点采样数据位。
- 起始位固定为1位,且电平为低(逻辑0)。
- 数据位(Data Bits):
- 这是真正要传输的有效数据。
- 数据位的长度是可配置的,通常为5、6、7、8位,最常见的是8位(一个字节)。
- 数据传输的顺序是最低有效位(LSB)在前,最高有效位(MSB)在后。例如,要发送字符’C’(ASCII码为
0x41
,二进制为0100 0001
),发送的比特流顺序是1 0 0 0 0 0 1 0
。
- 校验位(Parity Bit) - 可选:
- 一种简单的错误检测机制。
- 它的值取决于数据位中“1”的数量。
- 无校验(None Parity): 最常用,不使用校验位。
- 偶校验(Even Parity): 如果数据位中“1”的个数是奇数,则校验位置为1;如果是偶数,则校验位置为0。目标是使数据位+校验位中“1”的总数为偶数。
- 奇校验(Odd Parity): 与偶校验相反,目标是使数据位+校验位中“1”的总数为奇数。
- 校验位只能检测出奇数个位的错误,无法检测出偶数个位的错误,也无法纠正错误,因此是一种较弱的校验方式。
- 停止位(Stop Bit(s)):
- 标志着一个数据帧的结束。
- 发送方将TX线拉高,并保持至少一个时钟周期的时间。
- 停止位的长度可以是1位、1.5位或2位,最常用的是1位。
- 停止位确保了无论最后一个数据位是0还是1,总线在帧结束后都会回到高电平的空闲状态,为下一个起始位(下降沿)做准备。
4. UART的同步机制和波特率
- 波特率(Baud Rate): 这是理解异步通信的关键。波特率表示每秒传输的**码元(符号)**数量。在UART中,一个码元就是一位(也就是一个高低电平,例如上面最常用的一帧数据帧是10位,也就是10个高低电平),所以波特率等同于比特率(bits per second, bps)。
- 同步原理:
- 约定: 通信双方必须预先配置成完全相同的波特率(以及数据位、校验位、停止位配置)。常见的波特率有9600, 19200, 38400, 57600, 115200等。
- 触发: 接收方持续监测RX线。当检测到从高到低的跳变(起始位)时,它启动一个内部定时器。
- 采样: 接收方并不会在电平变化时立即采样,而是在每个位的中间时刻进行采样。它会等待起始位开始后的1.5个位周期时间(即第一个数据位的中心),采样D0。然后每隔1个位周期时间,依次采样D1, D2… 直到所有数据位和校验位都被采样。
- 容错: 在位的中心采样可以最大程度地容忍发送方和接收方之间微小的时钟频率差异。只要在采样完整个帧的过程中,累积的误差不超过半个位周期,通信就能成功。
5. 物理层标准:不仅仅是0和1
UART定义了协议层(数据帧格式),但没有严格规定物理层的电压标准。这导致了多种物理接口的存在:
- TTL/CMOS电平:
- 这是微控制器(MCU)内部和板级通信最常用的电平。
- 逻辑’1’ ≈ VCC (例如 3.3V 或 5V)
- 逻辑’0’ ≈ GND (0V)
- 抗干扰能力差,传输距离短(通常在1米以内)。
- RS-232:
- 一种经典的串口标准,常见于旧式电脑的COM口和工业设备。
- 它使用负逻辑和更高的电压来增强抗干扰能力和传输距离(可达15米)。
- 逻辑’1’ (Mark) = -3V 到 -15V
- 逻辑’0’ (Space) = +3V 到 +15V
- MCU的TTL电平UART要与RS-232设备通信,必须使用电平转换芯片(如 MAX232)。直接连接会损坏设备!
- RS-485 / RS-422:
- 采用差分信号传输,抗共模干扰能力极强。
- 使用两根线(A和B)的电压差来表示逻辑。例如,V(A) > V(B) 表示’1’,V(B) > V(A) 表示’0’。
- RS-422 支持一点对多点(一个主发送,多个从接收)。
- RS-485 在RS-422基础上改进,支持多点对多点(总线上任何设备都可以成为主发送方),是真正的多机通信总线。
- 传输距离非常远(可达1200米),速率也很高。同样需要电平转换芯片(如 MAX485)。
6. UART的优缺点
优点
- 实现简单: 只需要两根线(不计地线),硬件和软件实现都非常简单。
- 广泛支持: 几乎所有微控制器和处理器都内置了UART硬件。
- 协议灵活: 通信参数可调,适应性强。
- 无需时钟线: 节省了一个引脚,简化了布线。
- 全双工通信: 可以同时收发数据。
缺点
- 异步限制速度: 由于依赖内部时钟同步,波特率不能无限高,否则时钟误差累积会导致采样错误。
- 协议开销: 每个字节都需要额外的起始位和停止位,降低了有效数据传输率。例如,传输8位数据至少需要10位(1起始+8数据+1停止),开销为20%。
- 点对点通信: 标准UART不支持多设备总线(没有地址机制)。(注:RS-485物理层可以实现多点,但需要在应用层软件实现寻址和仲裁)。
- 无硬件应答: 发送方不知道接收方是否成功接收了数据。可靠性需要上层协议来保证。
- 错误检测能力弱: 奇偶校验只能检测部分错误,无法纠错。
7. 小结
UART (Universal Asynchronous Receiver/Transmitter - 通用异步收发器): 这是一个通信协议和硬件实现。它定义了数据是如何被打包成帧(起始位、数据位、奇偶校验位、停止位)进行异步传输的。UART 工作在逻辑电平(TTL/CMOS),例如 0V 代表逻辑’0’,3.3V/5V 代表逻辑’1’。它本身不定义电压、电流或连接器标准,主要用于芯片与芯片之间(板级)的通信。
RS232 和 RS485 (Recommended Standard): 这两者是物理层电气标准。它们不关心数据帧的格式(那是 UART 的工作),而是定义了如何用电压信号来表示逻辑’0’和’1’,以及相关的电气特性(如电压、阻抗、线缆长度、速率等)。它们是用来将 UART 的逻辑信号转换为能够进行更长距离、更稳定传输的电信号。
简单比喻:
- UART 就像是你要说的语言和语法(例如,一句话要有主谓宾)。
- RS232 和 RS485 就像是你说话的方式:是通过电话大声说(RS232),还是通过对讲机系统让多个人听到(RS485)。
它们经常协同工作:一个微控制器(MCU)的 UART 硬件生成数据帧,然后通过一个 RS232 或 RS485 收发器(Transceiver IC)转换成相应的电平信号,再通过线缆发送出去。
UART vs. RS232 vs. RS485 详细对比表
特性 / 类别 | UART (逻辑层) | RS232 (物理层) | RS485 (物理层) |
---|---|---|---|
基本定义 | 通信协议和硬件模块,定义数据帧格式 | 物理层电气标准,定义信号电压和引脚 | 物理层电气标准,定义差分信号和总线 |
信号电平 | 逻辑电平 (TTL/CMOS) • 逻辑 ‘0’: ~0V • 逻辑 ‘1’: ~3.3V 或 5V |
单端、高电压、反逻辑 • 逻辑 ‘0’ (Mark): +3V 到 +15V • 逻辑 ‘1’ (Space): -3V 到 -15V |
差分信号 • 逻辑 ‘1’: A-B > +200mV • 逻辑 ‘0’: A-B < -200mV |
通信模式 | 点对点 (Point-to-Point) 一个设备直接连接另一个设备 |
点对点 (Point-to-Point) 一个驱动器 (Driver) 连接一个接收器 (Receiver) |
多点 (Multi-Drop / Multi-Point) 多个设备可以挂在同一总线上 |
双工模式 | 全双工 (Full-Duplex) 独立的 TX 和 RX 线,可同时收发 |
全双工 (Full-Duplex) 独立的 TXD 和 RXD 线 |
半双工 (Half-Duplex) (2线制,最常见) 全双工 (Full-Duplex) (4线制) |
所需线缆数 (最小) | 2根 + GND (TX, RX, GND) |
3根 (TXD, RXD, GND) |
2根 (半双工: A, B) 4根 (全双工: TX_A/B, RX_A/B) |
通信距离 | 非常短 通常在同一块PCB上,最多数米 |
较短 标准为 15米 (50英尺) 左右 |
非常长 标准可达 1200米 (4000英尺) |
通信速率 | 很高(板级),可达数 Mbps | 较低 标准为 20 kbps,实际常用 115200 bps |
很高 可达 10 Mbps 或更高 (速率与距离成反比) |
抗噪能力 | 差 逻辑电平很容易受干扰 |
一般 比 TTL 好,但单端信号仍易受共模噪声影响 |
极好 差分信号能有效抵消共模噪声 |
总线上的设备数 | 2个 (1 对 1) | 2个 (1个驱动器, 1个接收器) | 最多 32 个“单位负载” (现代收发器可支持128或256个节点) |
接地要求 | 必须共地 信号以地为参考 |
必须共地 信号以地为参考 |
需要信号地线 以保证设备间的共模电压在允许范围内 |
典型应用 | • 芯片间通信 • 蓝牙模块 • GPS模块 |
• PC COM 端口 • 工业仪表 (旧) • 调试接口 |
• 工业自动化 (Modbus) • DMX512 舞台灯光 • 楼宇自控 |
优点 | • 硬件集成在MCU中 • 协议简单,易于实现 |
• 简单,广泛支持 • 比TTL电平稳定 |
• 长距离传输 • 强大的抗干扰能力 • 支持多节点组网 |
缺点 | • 距离短,抗噪差 • 不适合板外连接 |
• 距离短,速度慢 • 抗噪能力一般 • 不支持多点通信 |
• 需要外部收发器芯片 • 半双工需要控制收发方向 • 布线需要考虑阻抗匹配和终端电阻 |
当你需要在同一块电路板上的两个芯片之间通信时:
直接使用 UART 接口连接它们的 TX 和 RX 引脚。这是最简单、最直接的方式。当你的设备需要连接到一台旧式电脑的 COM 口,或者与一个只支持 RS232 的设备进行短距离(15米内)通信时:
在你的 MCU 的 UART 接口后面增加一个 RS232 收发器芯片(如 MAX232),它会将 UART 的 0/5V 逻辑电平转换为 RS232 的 +/- 12V 电平。当你需要构建一个通信网络,连接多个设备(超过2个),或者通信距离很远(几十到上千米),尤其是在有电磁干扰的工业环境中时:
在你的 MCU 的 UART 接口后面增加一个 RS485 收发器芯片(如 MAX485)。所有设备都并联到 A/B 两条总线上,构成一个强大的多点通信网络。这是工业领域最常用的串行通信方式。
二、IIC
IIC(Inter-Integrated Circuit)总线,它也被广泛地称为 I2C。这是一种非常流行、简单而强大的串行通信协议。
1. IIC 是什么?- 核心概念
IIC (Inter-Integrated Circuit),通常写作 I2C,是由飞利浦公司(现在的恩智浦 NXP)在20世纪80年代初设计的一种同步、多主控、多从机、半双工的串行通信总线。
- 同步 (Synchronous): 通信双方(主设备和从设备)共享一根时钟线(SCL)。数据的发送和接收都由这个时钟信号来协调,确保了数据传输的可靠性。
- 多主控 (Multi-Master): 总线上可以有多个设备发起通信(充当主设备)。协议内建了“仲裁”机制,以解决多个主设备同时尝试控制总线的冲突。
- 多从机 (Multi-Slave): 总线上可以挂载多个接收和响应命令的设备(从设备)。每个从设备都有一个唯一的地址,主设备通过这个地址来指定与哪个设备通信。理论上,7位地址模式下可以连接127个设备(地址0000000为广播地址)。
- 半双工 (Half-Duplex): 数据可以在两个方向上传输(主到从,从到主),但不能在同一时刻进行。数据线(SDA)是双向的。
- 串行 (Serial): 数据是一位一位地在单根数据线上进行传输。
- 总线 (Bus): 意味着多个设备可以连接到同一组线上。
最核心的特点是,它仅用两根线(SDA 和 SCL) 就可以实现设备间的复杂通信,极大地简化了电路板的布线和硬件设计。
2. 历史与背景
I2C 最初是为了简化电视机内部各个芯片之间的通信而设计的。在那个时代,芯片间通信通常需要大量的并行数据线,导致布线复杂、成本高昂。I2C 的出现,使得如微控制器(MCU)、EEPROM、实时时钟(RTC)、数模/模数转换器(ADC/DAC)等芯片可以非常方便地连接在一起,大大降低了系统设计的复杂度。
3. 物理层
I2C 总线在物理上由两根信号线和地线(GND)组成:
SCL (Serial Clock) - 串行时钟线:
- 由主设备产生和控制。
- 为数据传输提供同步时钟信号。SDA线上的数据在SCL为高电平时必须保持稳定,在SCL为低电平时才允许改变。
SDA (Serial Data) - 串行数据线:
- 双向数据线,用于传输数据。
- 无论是主设备还是从设备,都可以通过这条线发送或接收数据。
开漏(Open-Drain)输出与上拉电阻
这是 I2C 能够实现多设备共享总线的关键技术。
- 开漏输出: I2C 设备连接到 SCL 和 SDA 线的引脚都是开漏(或开集电极)结构。这意味着设备只能将总线拉低至低电平(GND),但不能主动输出高电平。当设备想发送高电平时,它会“释放”总线,使其处于高阻态。
- 上拉电阻 (Pull-up Resistors): 为了在总线被释放时能够恢复到高电平状态,SCL 和 SDA 线上必须各连接一个上拉电阻到电源(VCC)。当总线上所有设备都释放总线时,这两个电阻会将线路电压拉到高电平。
这个设计带来了两个巨大的好处:
- 避免冲突: 如果两个设备同时尝试控制总线,一个拉低,一个释放(想输出高电平),总线最终表现为低电平,不会因为高低电平直接短路而损坏设备。
- 实现“线与”逻辑 (Wired-AND): 只有当所有设备都释放总线时,总线才为高电平。只要有任何一个设备将总线拉低,总线就为低电平。这个特性是多主控仲裁机制的基础。
4. IIC 协议详解 - 通信的规则
I2C 通信就像一场有严格规则的对话。
起始(START)与停止(STOP)条件
通信的开始和结束由两种特殊信号定义,它们不属于数据传输的一部分。
- 起始条件 (START): 在 SCL 保持高电平期间,SDA 从高电平跳变为低电平。这标志着一次通信的开始,所有从设备都开始监听总线,准备接收地址。
- 停止条件 (STOP): 在 SCL 保持高电平期间,SDA 从低电平跳变为高电平。这标志着一次通信的结束,总线被释放。
设备寻址(Addressing)
- START 条件之后,主设备发送的第一个字节是地址帧。
- 它由 7位从设备地址 和 1位读/写控制位 组成。
- 读/写位 (R/W):
0
表示写操作(主设备要向从设备发送数据)。1
表示读操作(主设备要从从设备请求数据)。
- 读/写位 (R/W):
- 总线上所有的从设备都会接收这个地址帧,并与自己的地址进行比较。如果匹配,该从设备就被选中,准备后续的通信。
数据传输与应答(ACK/NACK)
- 数据有效性: 在 SCL 为高电平期间,SDA 上的数据必须保持稳定。数据的改变只能在 SCL 为低电平期间发生。
- 数据传输: 数据以字节(8位)为单位进行传输,高位(MSB)在前。SCL 每产生一个脉冲,SDA 上就传输一位数据。
- 应答 (Acknowledge, ACK): 每当主设备或从设备成功发送完一个字节(8位)的数据后,接收方必须在第9个时钟脉冲期间回复一个应答信号。
- ACK (应答): 接收方将 SDA 拉低,表示“我已成功接收到数据,请继续”。
- NACK (非应答, Not Acknowledge): 接收方保持 SDA 为高电平,表示“我未接收到数据”或“我正忙”或“读操作结束”。
- 在主设备读取数据时,主设备会在读取最后一个字节后发送一个 NACK,以告知从设备数据读取结束。
一个完整的通信时序
A. 主设备向从设备写数据 (Master Write)
- START: 主设备发送起始条件。
- Address Frame: 主设备发送 7位从机地址 + 写位(
0
)。 - ACK: 匹配的从设备回复一个 ACK。
- Data Frame 1: 主设备发送第一个数据字节。
- ACK: 从设备回复一个 ACK。
- Data Frame 2: 主设备发送第二个数据字节。
- ACK: 从设备回复一个 ACK。
- … (可以继续发送更多数据) …
- STOP: 主设备发送停止条件,结束通信。
B. 主设备从从设备读数据 (Master Read)
- START: 主设备发送起始条件。
- Address Frame: 主设备发送 7位从机地址 + 读位(
1
)。 - ACK: 匹配的从设备回复一个 ACK。
- Data from Slave: 从设备发送第一个数据字节。
- ACK from Master: 主设备回复一个 ACK,表示还想继续读。
- Data from Slave: 从设备发送第二个数据字节。
- ACK from Master: 主设备回复一个 ACK。
- … (主设备继续接收,每次都回 ACK) …
- Data from Slave: 从设备发送最后一个数据字节。
- NACK from Master: 主设备回复一个 NACK,告知从设备“我读完了,不要再发了”。
- STOP: 主设备发送停止条件,结束通信。
5. 高级特性
时钟拉伸(Clock Stretching)
有时,从设备可能需要一些时间来处理接收到的数据或准备要发送的数据(例如,从EEPROM内部读取数据)。在这种情况下,从设备可以在接收完一个字节后,在回复ACK之前,将 SCL 线强行拉低。主设备会检测到 SCL 被拉低,并暂停发送下一个时钟脉冲,进入等待状态,直到从设备释放 SCL 线。这个机制给予了慢速从设备与快速主设备同步的能力。
多主控(Multi-Master)与仲裁(Arbitration)
当两个或多个主设备同时尝试在总线上发起通信时,就会发生冲突。I2C 的仲裁机制可以优雅地解决这个问题:
- 所有主设备在发送数据时都会同时监测 SDA 线。
- 由于“线与”逻辑,如果一个主设备想发送高电平(释放SDA)而另一个主设备发送低电平(拉低SDA),SDA线将最终呈现低电平。
- 想发送高电平的主设备会检测到 SDA 的实际电平与自己想发送的电平不符,它就知道自己“输掉”了仲裁,会立刻停止驱动总线,并转为从机模式等待总线空闲。
- 而发送低电平的主设备没有检测到冲突,它会继续它的通信。
这个过程是非破坏性的,数据不会丢失,赢得仲裁的主设备可以无缝地完成它的通信。
6. IIC 的速度模式
I2C 支持多种速度,以适应不同应用的需求:
- Standard-mode (Sm): 100 kbit/s
- Fast-mode (Fm): 400 kbit/s
- Fast-mode Plus (Fm+): 1 Mbit/s
- High-speed mode (Hs-mode): 3.4 Mbit/s
- Ultra Fast-mode (UFm): 5 Mbit/s (这是单向的,更像是推送协议)
最常用的是 Standard-mode 和 Fast-mode。
7. IIC 的优缺点
优点
- 接线少: 只需要两根信号线,大大简化了PCB布局和连接器设计。
- 灵活性高: 很容易在总线上增加或移除设备,扩展性好。
- 成本低: 硬件实现简单,许多MCU都内置了I2C控制器。
- 有确认机制: ACK/NACK 机制确保了数据传输的可靠性。
- 支持多主控: 允许多个设备发起通信。
缺点
- 速度受限: 相对于 SPI、USB 等协议,I2C 的速度较慢。
- 物理距离短: 总线电容会随着线缆长度和设备数量的增加而增大,这会限制通信速度和距离,通常只适用于板级或设备内部通信。
- 地址空间有限: 7位地址最多支持127个设备,虽然有10位地址扩展,但不如SPI那样通过片选线可以支持几乎无限的设备。
- 协议相对复杂: 相比 UART,I2C 的协议状态(START/STOP/ACK/NACK/Addressing)更多,软件实现更复杂一些。
8. 典型应用场景
I2C 无处不在,特别是在嵌入式系统中:
- 传感器: 读取温度、湿度、压力、加速度、陀螺仪等传感器数据。
- 存储器: 读写 EEPROM、FRAM 等非易失性存储器,用于保存配置信息。
- 实时时钟 (RTC): 设置和读取时间。
- 显示驱动: 控制OLED或LCD小屏幕。
- I/O 扩展器: 用一个I2C接口扩展出更多的GPIO口。
- 电源管理芯片 (PMIC): 配置和监控电池充电、电压调节等。
- 音频编解码器 (Audio Codecs): 设置音量、均衡器等参数。
三、SPI
1. 核心概念
SPI (Serial Peripheral Interface),是由摩托罗拉(Motorola)公司在20世纪80年代中期开发的一种同步、全双工、主从式的串行通信总线。
- 同步 (Synchronous): 和 I2C 类似,通信双方共享一根时钟线(SCLK),所有的数据传输都由这个时钟信号进行同步。
- 全双工 (Full-Duplex): 数据可以同时在两个方向上传输。主设备向从设备发送数据的同时,从设备也可以向主设备发送数据。这是通过两根独立的数据线(MOSI 和 MISO)实现的。
- 主从式 (Master-Slave): SPI 网络中有一个主设备 (Master) 和一个或多个从设备 (Slave)。
- 主设备: 负责发起通信、生成时钟信号、并通过片选线选择与之通信的从设备。
- 从设备: 只能被动地响应主设备的请求,使用主设备提供的时钟信号进行数据收发。
- 总线 (Bus): 多个从设备可以共享 SCLK、MOSI 和 MISO 这三条线,但每个从设备都需要一根独立的片选线。
2. 历史与背景
SPI 的设计初衷是为了在微控制器和各种外围设备(如闪存、传感器、ADC等)之间提供一种简单、高速的点对点通信方式。与 I2C 的多主控复杂性不同,SPI 的协议非常简单,几乎没有协议开销(如地址、ACK/NACK位),这使得它能够以非常高的速度传输数据。
3. 物理层 - 四线制的标准
标准的 SPI 通信需要四根信号线:
SCLK (Serial Clock) - 串行时钟:
- 由主设备产生和控制。
- 为数据传输提供同步脉冲。数据的每一位都在时钟的一个特定边沿被发送和采样。
MOSI (Master Out, Slave In) - 主出从入:
- 数据从主设备流向从设备的通道。
- 也常被称为
SDO
(Serial Data Out)、DO
(Data Out) 在主设备端,或SDI
(Serial Data In)、DI
(Data In) 在从设备端。
MISO (Master In, Slave Out) - 主入从出:
- 数据从从设备流向主设备的通道。
- 也常被称为
SDI
(Serial Data In)、DI
(Data In) 在主设备端,或SDO
(Serial Data Out)、DO
(Data Out) 在从设备端。
CS / SS (Chip Select / Slave Select) - 片选:
- 由主设备控制,用于选择要通信的从设备。
- 通常是低电平有效。当主设备想与某个从设备通信时,会将其对应的 CS 线拉低。
- 总线上有多少个从设备,主设备就需要提供多少根独立的 CS 线(在标准模式下)。当某个从设备的 CS 线为高电平时,它会忽略 SCLK 信号并保持 MISO 线为高阻态,以免干扰总线。
4. SPI 协议详解 - 通信的规则
主从架构 (Master-Slave Architecture)
通信永远由主设备发起。主设备是整个总线的“指挥官”,决定了通信的速率和时序。
数据传输机制 - 环形移位寄存器
理解 SPI 数据传输最直观的方式是,想象主设备和从设备内部各有一个移位寄存器 (Shift Register)。
- 当通信开始时(CS被拉低,部分设备也可能是拉高),这两个寄存器可以看作是头尾相连,形成一个环形。
- 主设备在 SCLK 的驱动下,将自己寄存器中的数据一位一位地通过 MOSI 线“推”入从设备的寄存器。
- 同时,从设备寄存器中的数据也一位一位地通过 MISO 线“推”入主设备的寄存器。
- 经过8个(或16个,取决于数据长度)时钟周期后,主设备和从设备就完成了数据的交换。主设备的原始数据到了从设备,从设备的原始数据到了主设备。
这个“交换”过程就是 SPI 全双工的本质。即使你只想写数据,你也必须完成整个交换过程,只是你会忽略从 MISO 线上收到的数据。同理,如果你只想读数据,你也必须通过 MOSI 发送一些“虚拟”数据(通常是全0或全1)来产生时钟,以“换回”你想要的数据。
一个完整的通信时序
- 片选: 主设备将目标从设备的 CS 线从高电平拉至低电平。
- 时钟生成: 主设备开始在 SCLK 线上产生时钟脉冲。
- 数据交换: 在每个时钟周期,主设备在 MOSI 线上发送一位数据,同时在 MISO 线上接收一位数据。数据传输通常是高位(MSB)在前。
- 通信结束: 当预定数量的数据(例如一个或多个字节)交换完毕后,主设备停止 SCLK 时钟。
- 释放片选: 主设备将 CS 线重新拉回高电平,结束本次通信。从设备此时不再监听总线。
5. 核心配置:CPOL 与 CPHA - SPI 的四种模式
SPI 的灵活性在于主从设备必须在时钟极性 (CPOL) 和时钟相位 (CPHA) 上达成一致。
CPOL (Clock Polarity) - 时钟极性:
- 定义了 SCLK 在空闲状态(即 CS 为高电平时)的电平。
- CPOL = 0: 空闲时 SCLK 为低电平。第一个时钟边沿是上升沿。
- CPOL = 1: 空闲时 SCLK 为高电平。第一个时钟边沿是下降沿。
CPHA (Clock Phase) - 时钟相位:
- 定义了数据是在时钟的哪个边沿被采样(读取)。
- CPHA = 0: 数据在时钟周期的第一个边沿被采样。
- CPHA = 1: 数据在时钟周期的第二个边沿被采样。
四种工作模式总结
这两种配置组合起来,构成了 SPI 的四种标准工作模式:
模式 | CPOL | CPHA | 描述 (数据在哪个边沿被采样) |
---|---|---|---|
Mode 0 | 0 | 0 | 空闲时钟为低,在第一个边沿 (上升沿) 采样 |
Mode 1 | 0 | 1 | 空闲时钟为低,在第二个边沿 (下降沿) 采样 |
Mode 2 | 1 | 0 | 空闲时钟为高,在第一个边沿 (下降沿) 采样 |
Mode 3 | 1 | 1 | 空闲时钟为高,在第二个边沿 (上升沿) 采样 |
Mode 0 是最常用、最普遍的模式。 在进行通信前,主设备必须配置成与目标从设备所支持的模式相匹配。
6. 多从设备配置 (Multi-Slave Configurations)
独立片选模式 (Independent Slave Select)
这是最常见的方式。主设备为每一个从设备都分配一个独立的 CS 引脚。SCLK、MOSI、MISO 线由所有设备共享。
- 优点: 逻辑简单直接,可以与任何一个从设备进行高速通信,互不干扰。
- 缺点: 当从设备数量增多时,会消耗主设备大量的 GPIO 引脚。
菊花链模式 (Daisy-Chain)
这是一种节省引脚的方式。所有从设备的 CS 线可以并联到一根线上。
- 连接方式: 主设备的 MOSI 连接到第一个从设备的 MOSI,第一个从设备的 MISO 连接到第二个从设备的 MOSI,以此类推。最后一个从设备的 MISO 连接回主设备的 MISO。
- 工作方式: 数据像贪吃蛇一样,从主设备发出,穿过每一个从设备,最后回到主设备。如果每个设备的数据长度是8位,要与3个设备通信,主设备就需要连续发送24个时钟脉冲,将数据“推”遍整个链条。
- 优点: 无论有多少从设备,都只需要一根 CS 线。
- 缺点:
- 通信速度受限于链条中最慢的设备。
- 如果链条中任何一个设备出现故障,整个链条都会失效。
- 软件实现更复杂,更新一个设备的数据需要重写整个链条。
7. SPI 的优缺点
优点
- 速度快: 协议简单,没有额外开销,时钟频率可以达到几十甚至上百 MHz。
- 全双工通信: 可以同时收发数据,效率高。
- 协议简单: 硬件实现(移位寄存器)和软件控制都非常简单。
- 数据长度灵活: 不像 I2C 强制为8位,SPI 可以传输任意长度的数据帧。
缺点
- 占用引脚多: 每个从设备都需要一个额外的 CS 引脚。
- 没有应答机制: 主设备无法知道从设备是否成功接收到数据(没有 ACK/NACK),通信的可靠性依赖于硬件的稳定性。
- 没有流控: 从设备无法像 I2C 那样通过时钟拉伸来告知主设备“请等一下”。
- 只能单主控: 协议本身不支持多主控,总线上只能有一个主设备。
- 通信距离短: 高速信号容易受干扰,通常只用于板级通信。
8. 典型应用场景
由于其高速特性,SPI 被广泛用于需要大量数据吞吐的场合:
- 存储器: SD卡、MMC卡、串行Flash(Nor/NAND Flash)、FRAM。
- 显示设备: LCD、OLED 显示屏的驱动。
- 数据转换器: 高速 ADC (模数转换器) 和 DAC (数模转换器)。
- 传感器: 特别是需要高采样率的传感器,如陀螺仪、加速度计、图像传感器。
- 通信模块: 以太网控制器 (如 W5500)、无线模块 (如 nRF24L01)。
四、总结
UART vs. IIC (I2C) vs. SPI 综合对比表
特性 / 维度 | SPI (Serial Peripheral Interface) | IIC / I2C (Inter-Integrated Circuit) | UART (Universal Asynchronous Receiver/Transmitter) |
---|---|---|---|
核心思想 | 高速数据流,主从同步,全双工数据交换 | 多点总线控制,主从同步,半双工命令/响应 | 点对点异步,简单可靠的字符流传输 |
通信方式 | 同步 (Synchronous) | 同步 (Synchronous) | 异步 (Asynchronous) |
数据传输 | 全双工 (Full-Duplex) 数据可同时收发 |
半双工 (Half-Duplex) 数据只能单向传输 |
全双工 (Full-Duplex) 独立的收发线 |
时钟信号 | 有 (SCLK) 由主设备产生 |
有 (SCL) 由主设备产生,从设备可“拉伸” |
无 (No Clock Line) 双方约定波特率,通过起始/停止位同步 |
标准线数 | 4根 (SCLK, MOSI, MISO, CS) |
2根 (SDA, SCL) |
2根 (TX, RX) |
连接拓扑 | 单主,多从 (标准模式下) |
多主,多从 (协议支持仲裁) |
点对点 (Point-to-Point) |
设备选择 | 硬件片选线 (CS/SS) 每个从设备需要一根独立的CS线 |
软件地址 (7位/10位) 通过总线发送地址来选择设备 |
物理直连 TX连RX,RX连TX,无选择机制 |
总线设备数 | 受限于主设备GPIO数量 (每个从设备消耗一个引脚) |
理论上多达127个 (7位地址) 受总线电容限制 |
2个 (1对1) |
通信速度 | 非常快 通常可达几十甚至上百 MHz |
中低速 标准100kHz, 快速400kHz, 高速模式可达几MHz |
相对较慢 常用9600~115200 bps, 最高可达几Mbps |
数据可靠性 | 较低 无内置的应答(ACK)或流控机制 |
较高 有应答机制 (ACK/NACK),从机可时钟拉伸(流控) |
一般 有奇偶校验位(Parity)可选,但无应答机制 |
协议复杂度 | 硬件简单 本质是移位寄存器,软件实现简单 |
中等复杂 需处理START/STOP, 地址, ACK/NACK, 仲裁等 |
非常简单 配置好参数(波特率等)后即可收发数据 |
硬件实现 | 通常由MCU内置的SPI外设实现 | 通常由MCU内置的I2C外设实现 | 通常由MCU内置的UART/USART外设实现 |
功耗 | 较高 通常使用推挽输出(Push-Pull) |
较低 开漏(Open-Drain)结构 + 上拉电阻 |
中等 推挽输出(Push-Pull) |
优点 | • 速度最快 • 全双工 • 协议简单,硬件开销小 |
• 接线最少 (2根) • 支持多主多从 • 有确认和流控机制,可靠性好 |
• 协议和实现都非常简单 • 只需2根线 • 广泛应用,支持长距离(配合RS232/485) |
缺点 | • 占用引脚多 • 无应答和流控 • 只能单主控 |
• 速度相对较慢 • 总线电容限制距离和设备数 • 协议比SPI/UART复杂 |
• 异步,有同步开销 (起始/停止位) • 速度受限 • 双方波特率必须精确匹配 |
典型应用 | • 高速数据传输 - SD卡, Flash存储器 - LCD/OLED显示屏 - 高速ADC/DAC - 无线模块(nRF24L01) |
• 板级设备管理和控制 - 传感器 (温度, 湿度, 加速度计) - EEPROM存储器 - 实时时钟(RTC) - I/O扩展器, 电源管理芯片 |
• 设备间调试与通信 - PC与MCU的串口调试 - GPS, 蓝牙, GSM/GPRS模块 - 配合RS232/RS485实现远距离工业控制 |
参考
[1] 超简单的一种通信,2分钟搞懂,串口通讯的工作原理!
[2] 4分钟看懂!I2C通讯协议 最简单的总线通讯!
[3] 深入理解SPi通讯协议,5分钟看懂!