4. SPI 总线协议详解:物理层、4线制、CPOL/CPHA 模式与全双工通信

SPI(Serial Peripheral Interface,串行外设接口)由 Motorola 公司于 20 世纪 80 年代提出,是一种高速、全双工、同步的串行通信总线。本章深入剖析 SPI 的物理层特性、4线制信号定义、时钟极性与相位配置,以及全双工通信的底层机制,为后续结合 DMA 实现高性能传输奠定基础。

4.1 物理层与 4 线制信号定义

SPI 总线采用主从(Master-Slave)架构,通常由 1 个主设备控制多个从设备。物理层通过 4 根信号线实现同步全双工通信:

信号线 全称 方向(主→从) 功能描述
SCK Serial Clock 主 → 从 由主设备产生,同步数据传输的时钟信号
MOSI Master Out Slave In 主 → 从 主设备发送数据至从设备的数据线
MISO Master In Slave Out 从 → 主 从设备发送数据至主设备的数据线
CS Chip Select 主 → 从 片选信号,低电平有效,选中特定从设备
关键概念:SPI 的物理层没有定义固定的数据包格式、地址或应答机制,这些完全由上层协议(如设备数据手册)规定。这种简洁性使得 SPI 的吞吐量远高于 I²C,但同时也要求驱动开发者对时序有更精确的控制。

下图展示了 SPI 单主多从的典型拓扑结构,其中 CS 线独立控制每个从设备,SCK、MOSI、MISO 则共享于所有从设备:

SPI 单主多从物理拓扑(4线制) 主设备 (Master) SCK 发生器 移位寄存器 从设备 1 CS1 移位寄存器 从设备 2 CS2 从设备 3 CS3 SCK MOSI MISO CS (独立片选) CS 独立控制线 SCK/MOSI/MISO 共享总线
硬件设计要点:在高速 SPI(≥10 MHz)布线时,SCK 应尽量短且远离其他数字信号线,以减少串扰。MOSI 与 MISO 应保持等长,避免数据线与时钟线之间的时序偏移(Skew)。CS 线建议使用 GPIO 直接控制,以获得最快的片选切换速度。

4.2 CPOL 与 CPHA:SPI 的四种工作模式

SPI 协议通过 时钟极性(CPOL, Clock Polarity) 和 时钟相位(CPHA, Clock Phase) 两个参数定义数据采样与切换的时序关系。这两个参数组合出 4 种标准模式:

模式 CPOL CPHA SCK 空闲电平 数据采样边沿 数据切换边沿
Mode 0 0 0 低电平 上升沿 下降沿
Mode 1 0 1 低电平 下降沿 上升沿
Mode 2 1 0 高电平 下降沿 上升沿
Mode 3 1 1 高电平 上升沿 下降沿
常见错误:主设备与从设备的 CPOL/CPHA 配置必须完全一致,否则会导致数据移位错位。例如,若主设备配置为 Mode 0(上升沿采样),而从设备配置为 Mode 1(下降沿采样),则主设备采样到的数据将是前一位的旧值,通信完全失败。

下图以 Mode 0(CPOL=0, CPHA=0)和 Mode 3(CPOL=1, CPHA=1)为例,展示 SCK、MOSI 与 MISO 的时序关系:

SPI 时序:Mode 0 与 Mode 3 对比 Mode 0 (CPOL=0, CPHA=0) SCK MOSI b7 b6 b5 b4 b3 b2 b1 b0 ↑ 采样 (上升沿) ↓ 切换 (下降沿) Mode 3 (CPOL=1, CPHA=1) SCK MOSI b7 b6 b5 b4 b3 b2 b1 b0 ↓ 采样 (下降沿) ↑ 切换 (上升沿) 采样边沿 切换边沿 数据有效

4.3 全双工通信机制

SPI 的核心优势在于其 全双工(Full-Duplex) 通信能力:在每个 SCK 时钟周期内,主设备通过 MOSI 发送一位数据,同时从设备通过 MISO 发送一位数据。这种同时收发机制使得 SPI 的吞吐量是相同时钟频率下 I²C 的两倍。

全双工通信的底层实现依赖于主从双方的 移位寄存器(Shift Register):

  1. 初始化:主设备将待发送数据加载到发送移位寄存器,从设备也将待发送数据加载到其发送移位寄存器。
  2. 时钟驱动:每个 SCK 边沿,主从双方同时将移位寄存器中的最高位(MSB-first 或 LSB-first)移出到数据线上,同时从数据线上移入一位新数据。
  3. 交换完成:经过 8 个(或 16 个)时钟周期后,主设备的接收移位寄存器中存储了从设备发送的完整数据,反之亦然。
性能指标:在 20 MHz SCK 频率下,SPI 的理论单向数据速率为 20 Mbps,全双工双向总吞吐量可达 40 Mbps。实际应用中,受限于 GPIO 中断响应延迟和 CPU 轮询开销,裸机驱动通常只能达到 60%~70% 的理论速率。这正是后续章节引入 DMA 传输的核心动机。

下图展示了 SPI 全双工通信中移位寄存器的数据交换过程:

SPI 全双工移位寄存器数据交换 主设备发送移位寄存器 [ b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 ] 主设备接收移位寄存器 [ r7 | r6 | r5 | r4 | r3 | r2 | r1 | r0 ] 从设备发送移位寄存器 [ s7 | s6 | s5 | s4 | s3 | s2 | s1 | s0 ] 从设备接收移位寄存器 [ m7 | m6 | m5 | m4 | m3 | m2 | m1 | m0 ] MOSI MISO SCK 时钟驱动同步移位 每个 SCK 周期:主设备通过 MOSI 发送 1 bit,同时从设备通过 MISO 发送 1 bit → 全双工交换

4.4 SPI 通信流程与代码示例

一个完整的 SPI 数据传输周期包含以下步骤:

  1. 片选拉低:主设备将目标从设备的 CS 引脚拉低,激活从设备。
  2. 时钟启动:主设备开始产生 SCK 时钟信号,频率由 SPI 时钟分频器配置决定。
  3. 数据移位:在每个 SCK 边沿(取决于 CP