2. SPI协议基础:SPI总线四线制与时钟配置
SPI(Serial Peripheral Interface)是一种全双工、同步、主从式串行通信总线。在嵌入式系统中,SPI Flash 是 SPI 设备中最典型的应用之一。理解 SPI 的四线制信号和时钟极性/相位配置,是驱动开发的第一步,也是后续扇区擦除和 DMA 写入优化的基础。
2.1 SPI 四线制信号定义
标准 SPI 总线使用四条信号线完成主设备与从设备之间的数据交换。下表列出了四线制的名称、方向与功能:
| 信号线 | 全称 | 方向(主→从) | 功能描述 |
|---|---|---|---|
| SCK | Serial Clock | 主→从 | 由主设备产生的时钟信号,同步所有数据传输 |
| MOSI | Master Out Slave In | 主→从 | 主设备发送数据到从设备的数据线 |
| MISO | Master In Slave Out | 从→主 | 从设备发送数据到主设备的数据线 |
| CS | Chip Select | 主→从 | 片选信号,低电平有效,选中特定的从设备 |
关键点:SPI 是全双工协议——在每个 SCK 时钟周期内,主设备通过 MOSI 发送一位数据,同时从设备通过 MISO 返回一位数据。这意味着一次 SPI 传输总是同时完成发送和接收。
2.2 SPI 四线制连接结构
下图展示了一个主设备与一个 SPI Flash 从设备之间的标准四线制连接拓扑:
硬件连线要点:
- SCK、MOSI、CS 由主设备驱动,MISO 由从设备驱动。
- 多从设备时,每个从设备独占一条 CS 线,SCK/MOSI/MISO 可共享。
- SPI Flash 的 CS 引脚通常带有内部上拉,但建议外部加 10kΩ 上拉电阻以保证空闲状态为高电平。
2.3 时钟极性(CPOL)与时钟相位(CPHA)
SPI 协议通过 CPOL 和 CPHA 两个参数定义时钟信号与数据采样的时序关系。这两个参数共同决定了 SPI 的四种工作模式(Mode 0 ~ Mode 3)。
2.3.1 CPOL:时钟极性
- CPOL = 0:SCK 空闲状态为低电平(0)。
- CPOL = 1:SCK 空闲状态为高电平(1)。
2.3.2 CPHA:时钟相位
- CPHA = 0:数据在 SCK 的第一个跳变沿(上升沿或下降沿)被采样。
- CPHA = 1:数据在 SCK 的第二个跳变沿被采样。
2.3.3 四种 SPI 模式对照表
| SPI 模式 | CPOL | CPHA | 空闲时钟电平 | 数据采样沿 | 数据输出沿 |
|---|---|---|---|---|---|
| Mode 0 | 0 | 0 | 低电平 | 上升沿(第一个沿) | 下降沿 |
| Mode 1 | 0 | 1 | 低电平 | 下降沿(第二个沿) | 上升沿 |
| Mode 2 | 1 | 0 | 高电平 | 下降沿(第一个沿) | 上升沿 |
| Mode 3 | 1 | 1 | 高电平 | 上升沿(第二个沿) | 下降沿 |
常见陷阱:绝大多数 SPI Flash(如 Winbond W25Q 系列、GD25Q 系列)默认工作在 Mode 0(CPOL=0, CPHA=0) 或 Mode 3(CPOL=1, CPHA=1)。这两种模式的数据采样沿都是 SCK 的上升沿,区别仅在于空闲电平。驱动开发前务必查阅 Flash 数据手册确认支持的 SPI 模式,否则通信将完全失败。
2.4 SPI Mode 0 与 Mode 3 时序对比
下图对比了最常用的 Mode 0 和 Mode 3 的时序波形,重点展示 SCK 空闲电平与数据采样点的差异:
2.5 驱动开发中的 SPI 模式配置
在嵌入式驱动中,SPI 模式通过配置 MCU 的 SPI 控制寄存器实现。以下是一个基于 STM32 HAL 库的配置示例,将 SPI 设置为 Mode 0:
/* SPI 初始化结构体配置 - Mode 0 (CPOL=0, CPHA=0) */
SPI_HandleTypeDef hspi1;
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER; // 主模式
hspi1.Init.Direction = SPI_DIRECTION_2LINES; // 全双工
hspi1.Init.DataSize = SPI_DATASIZE_8BIT; // 8 位数据
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; // CPOL = 0
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; // CPHA = 0
hspi1.Init.NSS = SPI_NSS_SOFT; // 软件控制 CS
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; // MSB 先传输
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
HAL_SPI_Init(&hspi1);
配置检查清单:
- 确认 SPI Flash 数据手册中指定的支持模式(通常为 Mode 0 或 Mode 3)。
- 设置 CPOL 与 CPHA 与 Flash 要求一致。
- 设置数据位宽为 8 位(SPI Flash 标准命令均为 8 位)。
- 设置 MSB 先传输(SPI Flash 协议要求)。
- 使用软件 NSS(CS)控制,以便灵活管理片选时序。
2.6 SPI 通信时序关键指标
| 参数 | 说明 | 典型值(SPI Flash) |
|---|---|---|
| SCK 频率 | 时钟速率,决定通信速度 | 20 MHz ~ 104 MHz(取决于 Flash 型号) |
| CS 建立时间 | CS 拉低到第一个 SCK 沿的时间 | ≥ 5 ns |
| CS 保持时间 | 最后一个 SCK 沿到 CS 拉高的时间 | ≥ 5 ns |
| 数据建立时间 | 数据在采样沿之前必须稳定的时间 | ≥ 2 ns |
| 数据保持时间 | 数据在采样沿之后必须保持的时间 | ≥ 2 ns |
优化提示:在后续章节的 DMA 写入优化中,SCK 频率是决定吞吐量的核心因素。但要注意,过高的 SCK 频率可能导致信号完整性下降,尤其是在长走线或高容性负载场景下。建议在 PCB 设计时保持 SPI 走线长度 < 10 cm,并串联 22Ω 电阻以抑制过冲。
2.7 本章小结
- SPI 四线制(SCK、MOSI、MISO、CS)是实现全双工同步通信的基础。
- CPOL 决定 SCK 空闲电平,CPHA 决定数据采样沿,两者组合产生四种 SPI 模式。
- SPI Flash 最常用 Mode 0 和 Mode 3,驱动配置时需严格匹配 Flash 数据手册。
- 正确的 SPI 模式配置是后续扇区擦除、页编程和 DMA 写入优化的前提条件。