1. SPI协议概述:总线历史、四线制与全双工通信
1.1 SPI总线发展简史
SPI(Serial Peripheral Interface,串行外设接口)由摩托罗拉(Motorola)于20世纪80年代中期提出,最初用于其MC68000系列微控制器与外围芯片之间的短距离板级通信。与同期流行的I²C总线相比,SPI以更高的速率、更低的协议开销和全双工能力迅速成为嵌入式系统中传感器、ADC/DAC、显示驱动、存储器(Flash/SRAM)和无线收发器的事实标准接口。2000年后,SPI被纳入多种MCU和SoC的片上外设,并衍生出Dual/Quad SPI、DSPI、QSPI等变体,但四线制基础模式至今仍是所有变体的核心。
关键时间节点:
- 1985年 — 摩托罗拉首次在MC68HC11系列中定义SPI。
- 1990年代 — SPI被多家半导体厂商采纳,成为事实标准(非IEEE/IEC官方标准)。
- 2000年代 — Linux内核引入spidev框架,SPI驱动进入通用操作系统。
- 2010年后 — 高速SPI(>50 MHz)在FPGA和高端MCU中普及。
1.2 四线制信号定义与工作原理
标准SPI使用四条信号线实现主-从(Master-Slave)通信。下表列出各信号线的名称、方向与功能:
| 信号线 | 全称 | 方向(主→从) | 功能描述 |
|---|---|---|---|
| SCLK | Serial Clock | 主→从 | 由主设备产生,决定数据采样/切换的时序节拍 |
| MOSI | Master Out Slave In | 主→从 | 主设备发送数据至从设备 |
| MISO | Master In Slave Out | 从→主 | 从设备发送数据至主设备 |
| CS | Chip Select | 主→从 | 片选信号,低电平有效,选中特定从设备 |
通信由主设备完全控制:主设备通过拉低CS选中从设备,在SCLK上产生时钟脉冲,同时在MOSI线上逐位发送数据,并从MISO线上同步接收从设备返回的数据。一次传输完成后,主设备拉高CS释放总线。
常见误区:CS信号必须在整个传输帧内保持有效(低电平),不能在每个字节之间翻转,否则从设备会误判为传输终止。部分从设备允许CS在字节间保持低电平,但标准模式要求CS连续有效。
1.3 全双工通信特点
SPI最显著的优势是全双工(Full-Duplex)通信:在每个SCLK周期内,主设备通过MOSI发送一位数据,同时从设备通过MISO返回一位数据。发送与接收在硬件层面并行进行,无需像I²C那样等待应答或切换数据方向。
全双工带来的关键特性:
- 吞吐量翻倍 — 在相同时钟频率下,有效数据交换速率是半双工协议的两倍。
- 无应答延迟 — 数据流连续,适合高速数据采集(如ADC采样值读取)和存储器连续读写。
- 硬件移位寄存器实现 — 主从设备各有一个移位寄存器,SCLK每跳变一次,双方同时移出一位并移入一位,逻辑简单、延迟低。
下图展示了一个完整字节(8位)传输过程中MOSI与MISO的数据流:
1.4 SPI与常见串行总线对比
下表从关键维度对比SPI与I²C、UART,帮助理解SPI的定位与适用场景:
| 特性 | SPI | I²C | UART |
|---|---|---|---|
| 信号线数量 | 4(SCLK, MOSI, MISO, CS) | 2(SCL, SDA) | 2(TX, RX) |
| 通信模式 | 全双工 | 半双工 | 全双工 |
| 最大速率 | 通常10~80 MHz,可达100+ MHz | 标准100 kHz / 快速400 kHz / 高速3.4 MHz | 通常115.2 kbps ~ 10 Mbps |
| 从设备选择 | 独立CS线(每从设备一根) | 7位或10位地址 | 点对点,无寻址 |
| 协议开销 | 极低(无起始/停止/应答位) | 较高(地址+读写位+应答) | 低(起始位+停止位+可选校验) |
| 多主支持 | 不支持(标准模式) | 支持多主仲裁 | 不支持 |
| 典型应用 | Flash、ADC/DAC、传感器、显示 | EEPROM、温度传感器、RTC | GPS、蓝牙模块、调试串口 |
1.5 SPI通信系统架构
下图展示了一个典型SPI系统中主设备与多个从设备的连接拓扑:
1.6 SPI传输的典型软件流程
在Linux或RTOS驱动中,一次完整的SPI传输通常遵循以下步骤:
- 配置SPI控制器 — 设置时钟频率、CPOL/CPHA模式、数据位宽(8/16/32位)、MSB/LSB优先。
- 拉低CS — 选中目标从设备。
- 循环发送/接收 — 对每个字节/字,将数据写入发送寄存器(MOSI),同时从接收寄存器读取数据(MISO)。
- 等待传输完成 — 轮询状态寄存器或等待中断/ DMA完成。
- 拉高CS — 释放