2、SPI基础概念:SPI定义、四线制(SCLK、MOSI、MISO、SS)、全双工同步通信特点、与I2C/UART对比
SPI(Serial Peripheral Interface,串行外设接口)是由摩托罗拉公司于20世纪80年代中期推出的一种高速、全双工、同步的串行通信总线。它最初是为MC68000系列微处理器与外围芯片之间的短距离板级通信而设计,如今已成为嵌入式系统、传感器采集、存储芯片(如Flash、SD卡)、显示驱动、ADC/DAC、CAN控制器等外设互连的事实标准之一。与I2C和UART相比,SPI在传输速率、全双工能力和协议简洁性上具有显著优势,但其代价是需要更多的引脚资源,且缺乏标准的应答机制。理解SPI的本质,需要从物理层信号定义、主从通信模型、数据移位机制以及时序约束四个维度入手。
上图展示了SPI最核心的四线制主从通信模型。主设备(Master)主动产生时钟SCLK和片选信号SS,并通过MOSI线发送数据,同时通过MISO线接收从设备(Slave)返回的数据。这种“一主多从”的拓扑结构,配合全双工的数据通路,使得SPI在需要高速、连续数据交换的场景(如音频采样、显示刷新、固件升级)中表现尤为出色。下面我们将从定义、信号线功能、通信特性以及与I2C/UART的对比四个层面展开详细解析。
2.1 SPI定义与核心设计思想
SPI是一种同步、全双工、主从式串行通信协议。所谓“同步”,是指通信双方共享同一时钟源(由主机产生SCLK),数据的发送和接收都在时钟边沿(上升沿或下降沿)触发,因此不存在UART中需要双方约定波特率的问题。所谓“全双工”,是指在一次数据传输周期内,主机通过MOSI发送数据的同时,从机也通过MISO向主机发送数据,两个方向的数据传输互不干扰。这种设计使得SPI在需要“请求-响应”或“读写同时进行”的场景(如读取ADC转换结果的同时写入下一通道配置)中效率极高。
SPI的协议本身非常简单,没有复杂的帧格式、地址编码或应答机制。一次完整的传输过程可以概括为:主机拉低SS选中从机 → 主机在SCLK的每个时钟周期通过MOSI发送1位数据,同时从MISO读取1位数据 → 传输完成后主机拉高SS释放从机。这种“裸传输”特性使得SPI的协议开销几乎为零,传输速率可以轻松达到数十MHz甚至更高(取决于器件和PCB布线质量)。
核心设计思想:SPI的设计哲学是“把复杂性留给软件,把简洁性留给硬件”。硬件只负责移位寄存器的同步移位,而帧格式、校验、流控等高级功能完全由主控芯片的软件(或SPI外设的硬件状态机)来实现。这也是SPI能够保持高速和灵活性的根本原因。
2.2 四线制信号详解
SPI总线由四根信号线组成,每根线都有明确且不可替代的作用。理解每根线的电气特性和时序要求,是进行SPI硬件设计和驱动开发的基础。
| 信号线名称 | 全称 | 方向(主设备视角) | 功能描述 | 关键特性 |
|---|---|---|---|---|
| SCLK | Serial Clock | 输出 | 串行时钟,由主机产生,用于同步所有数据传输 | 频率决定通信速率;极性和相位可通过CPOL/CPHA配置 |
| MOSI | Master Out Slave In | 输出 | 主机发送数据线,数据从主机移位寄存器输出到从机 | 在SCLK边沿被从机采样 |
| MISO | Master In Slave Out | 输入 | 主机接收数据线,从机通过该线将数据返回给主机 | 从机在SCLK边沿驱动该线;未选中时需处于高阻态 |
| SS | Slave Select | 输出(可多路) | 片选信号,低电平有效,用于选中目标从设备 | 每个从机独占一根SS线;SS拉低后从机必须响应 |
在实际工程中,MOSI和MISO有时会被合并为三线制(半双工),但标准SPI始终是四线制。此外,当总线上挂载多个从设备时,主设备需要为每个从设备分配独立的SS引脚,而SCLK、MOSI、MISO则共享。这种拓扑结构简单直接,但SS引脚的数量会限制可挂载的从设备数量。
2.3 全双工同步通信的工作机制
SPI的全双工同步特性,源于其内部的双移位寄存器结构。主设备和从设备各有一个移位寄存器,通过MOSI和MISO首尾相连,形成一个虚拟的环形移位通路。在SCLK的每个时钟周期内,主设备移位寄存器的高位通过MOSI移出,同时从设备移位寄存器的高位通过MISO移入主设备。经过8个时钟周期(假设数据宽度为8位),主设备发送的字节完全移入从设备,而从设备返回的字节也完全移入主设备。
这种机制带来两个重要推论:第一,SPI的每次传输都是“交换”而非“单向发送”。即使主机只想读取从机的数据,也必须先发送一个字节(通常为0x00或命令码)来产生时钟;同理,如果主机只想发送数据,从机返回的字节通常被忽略。第二,从机必须在SS有效期间保持MISO线的驱动状态,否则当主机尝试读取时,MISO线会处于浮空状态,导致读回的数据为随机值。因此,多从机共享MISO时,未选中的从机必须将MISO置为高阻态(通过三态门实现)。
// 伪代码示例:SPI全双工交换一个字节
uint8_t spi_transfer_byte(uint8_t tx_data) {
uint8_t rx_data = 0;
for (int i = 7; i >= 0; i--) {
// 在SCLK上升沿发送当前位
if (tx_data & (1 << i)) {
MOSI = 1;
} else {
MOSI = 0;
}
// 在SCLK下降沿采样MISO
rx_data |= (MISO << i);
// 产生一个时钟脉冲(由硬件或软件延时实现)
SCLK = 1;
delay();
SCLK = 0;
delay();
}
return rx_data;
}
上述代码展示了SPI软件模拟的基本逻辑。在实际MCU中,SPI外设硬件会自动完成移位操作,但理解这一底层过程对于调试时序问题和设计非标准位宽(如12位、16位)的通信至关重要。
2.4 SPI与I2C、UART的对比分析
在嵌入式系统设计中,SPI、I2C和UART是三种最常用的串行通信协议。它们各有优劣,适用于不同的应用场景。下表从多个维度进行了系统对比:
| 对比维度 | SPI | I2C | UART |
|---|---|---|---|
| 通信方式 | 同步(共享时钟) | 同步(共享时钟) | 异步(各自时钟) |
| 数据方向 | 全双工 | 半双工 | 全双工 |
| 信号线数量 | 4根(SCLK/MOSI/MISO/SS) | 2根(SDA/SCL) | 2根(TX/RX) |
| 传输速率 | 极高(10MHz~100MHz+) | 中低(100kHz~3.4MHz) | 中(通常≤1.5Mbps) |
| 多设备支持 | 需独立SS线,从机数量受限于引脚 | 7位/10位地址,可挂载多达128个设备 | 点对点,多设备需额外协议支持 |
| 应答机制 | 无硬件应答,需软件约定 | 有ACK/NACK应答 | 无硬件应答,需软件校验 |
| 协议复杂度 | 极简,无帧格式 | 较复杂(起始/停止/地址/数据/应答) | 简单(起始位/数据/停止位) |
| 典型应用 | Flash、ADC、LCD、SD卡 | 传感器、EEPROM、RTC | 调试串口、GPS、蓝牙模块 |
从表中可以看出,SPI的优势在于速率和全双工,劣势在于引脚占用和缺乏标准应答。I2C的优势在于引脚少、支持多设备,但速率较低且协议复杂。UART的优势在于无需时钟线、适合远距离,但只能点对点通信。在实际选型时,应遵循以下原则:
- 追求高速数据流(如显示刷新、固件下载) → 优先选择SPI。
- 需要挂载多个低速传感器且引脚紧张 → 优先选择I2C。
- 与PC或外部模块通信,且距离较远 → 优先选择UART(或RS-232/RS-485)。
2.5 实战场景:SPI Flash读取与写入的时序分析
以常见的SPI NOR Flash(如W25Q64)为例,其读操作(0x03命令)和写操作(0x02命令)的时序充分体现了SPI的特点。假设主控MCU主频为100MHz,SPI时钟配置为20MHz,我们需要读取Flash的ID(0x9F命令)。
操作流程:
- 主机将SS拉低,选中Flash芯片。
- 主机通过MOSI发送命令字节0x9F(读ID)。
- 在发送命令的同时,Flash通过MISO返回的字节无效(通常为0x00)。
- 命令发送完成后,主机继续发送3个任意字节(通常为0x00),此时Flash在MISO上依次返回制造商ID(0xEF)、设备ID(0x40)和容量ID(0x17)。
- 主机拉高SS,结束传输。
整个过程中,主机发送了4个字节,同时接收了4个字节。如果使用逻辑分析仪抓取波形,可以清晰地看到MOSI上的命令序列和MISO上的响应序列在时间上完全对齐。这正是全双工同步通信的直观体现。
经验提醒:在调试SPI通信时,务必使用逻辑分析仪同时抓取SCLK、MOSI、MISO和SS四路信号。观察SS拉低后,第一个SCLK上升沿是否与MOSI上的第一位数据对齐。如果发现数据错位,优先检查CPOL(时钟极性)和CPHA(时钟相位)配置是否与从机数据手册一致。
2.6 常见误区与总结复盘
在实际项目开发中,工程师在SPI基础概念上常犯以下错误,值得特别警惕:
误区一:忽略MISO高阻态要求。在多从机共享MISO的总线上,如果从机的SS未被拉低,其MISO引脚必须输出高阻态。若从机内部没有三态门控制,则需要在硬件上增加隔离芯片(如74HC125)。否则,多个从机同时驱动MISO会导致总线冲突,甚至损坏芯片。
误区二:混淆CPOL和CPHA的四种组合。CPOL决定SCLK空闲时的电平(0为低,1为高),CPHA决定数据采样边沿(0为第一个边沿,1为第二个边沿)。不同厂商的从机芯片可能采用不同的模式(如W25Q系列支持Mode 0和Mode 3),配置错误会导致数据完全错位。
误区三:认为SPI传输必须“有来有回”。虽然SPI是全双工,但很多从机(如某些DAC芯片)只接收数据而不返回数据。此时主机可以忽略MISO上的数据,但必须保证MISO引脚不悬空(可配置为输入上拉或直接悬空,视芯片而定)。
总结复盘:SPI的基础概念虽然简单,但其工程实现涉及电气特性、时序配置、多设备管理和软件协议设计等多个层面。掌握SPI的定义和四线制信号功能,是后续学习SPI模式配置、DMA传输、中断处理和驱动开发的前提。建议读者在理解本节内容后,动手使用MCU的SPI外设与一块SPI Flash或传感器进行实际通信,并用逻辑分析仪观察波形,将理论知识与实际信号对应起来,这样才能真正内化SPI的通信机制。