2. SPI 通信协议基础:四线工作原理与 CPOL/CPHA 模式详解
SPI(Serial Peripheral Interface,串行外设接口)是一种全双工、同步、主从式的串行通信总线。在嵌入式系统中,SPI Flash 是使用最广泛的非易失性存储介质之一,其固件烧录与备份操作完全依赖于 SPI 协议的正确配置。本节将深入剖析 SPI 的四线工作机制以及时钟极性(CPOL)与相位(CPHA)的四种模式。
2.1 SPI 四线信号定义与工作原理
标准的 SPI 总线使用四条信号线完成主设备(Master)与从设备(Slave)之间的数据交换。这四条线分别是:
| 信号线 | 全称 | 方向(主→从) | 功能描述 |
|---|---|---|---|
| SCK | Serial Clock | 主 → 从 | 由主设备产生的同步时钟信号,决定数据传输速率 |
| MOSI | Master Out Slave In | 主 → 从 | 主设备发送数据至从设备的数据线 |
| MISO | Master In Slave Out | 从 → 主 | 从设备发送数据至主设备的数据线 |
| CS | Chip Select | 主 → 从 | 片选信号,低电平有效,用于选中目标从设备 |
SPI 通信的核心机制是 移位寄存器交换。主设备和从设备内部各有一个 8 位(或更多位)的移位寄存器。在每个时钟脉冲的边沿(上升沿或下降沿),主设备通过 MOSI 线移出一位数据,同时从设备通过 MISO 线移出一位数据。经过 8 个时钟周期后,主设备和从设备完成了 1 字节的数据交换。
关键特性: SPI 是全双工通信,意味着在每一个时钟周期内,主设备发送一位数据的同时,也能接收一位数据。这与 I²C 或 UART 的半双工模式有本质区别。
2.2 时钟极性(CPOL)与时钟相位(CPHA)详解
SPI 协议定义了四种不同的工作模式,由 时钟极性(CPOL) 和 时钟相位(CPHA) 两个参数组合决定。这两个参数决定了数据采样和输出的具体时序。
- CPOL(Clock Polarity):定义 SCK 空闲状态时的电平。
- CPOL = 0:空闲时 SCK 为低电平(0)。
- CPOL = 1:空闲时 SCK 为高电平(1)。
- CPHA(Clock Phase):定义数据采样发生在 SCK 的哪个边沿。
- CPHA = 0:在 SCK 的第一个边沿(上升沿或下降沿)采样数据。
- CPHA = 1:在 SCK 的第二个边沿(上升沿或下降沿)采样数据。
⚠️ 常见错误: 主设备与从设备的 SPI 模式必须完全一致(CPOL 和 CPHA 均相同),否则会导致数据错位或通信失败。烧录器与 SPI Flash 芯片的模式不匹配是固件烧录失败的常见原因之一。
2.3 四种 SPI 模式对比
下表总结了 CPOL 和 CPHA 组合产生的四种标准 SPI 模式:
| 模式 | CPOL | CPHA | 空闲时钟电平 | 数据采样边沿 | 数据输出边沿 |
|---|---|---|---|---|---|
| 模式 0 | 0 | 0 | 低电平 | 上升沿(第一个边沿) | 下降沿(第二个边沿) |
| 模式 1 | 0 | 1 | 低电平 | 下降沿(第二个边沿) | 上升沿(第一个边沿) |
| 模式 2 | 1 | 0 | 高电平 | 下降沿(第一个边沿) | 上升沿(第二个边沿) |
| 模式 3 | 1 | 1 | 高电平 | 上升沿(第二个边沿) | 下降沿(第一个边沿) |
💡 实用技巧: 绝大多数 SPI Flash 芯片(如 Winbond W25Q 系列、Macronix MX25 系列)默认工作在 模式 0(CPOL=0, CPHA=0) 或 模式 3(CPOL=1, CPHA=1)。这两种模式的数据采样边沿都是上升沿,区别仅在于空闲时钟电平。在不确定 Flash 规格时,优先尝试模式 0。
2.4 实际应用中的模式选择
在固件烧录与备份场景中,正确配置 SPI 模式至关重要。以下是几条实践建议:
- 查阅数据手册:SPI Flash 芯片的数据手册中会明确标注支持的模式。例如,W25Q128JV 支持模式 0 和模式 3。
- 默认模式优先:大多数 Flash 芯片上电后默认工作在模式 0 或模式 3。如果手册未明确,先尝试模式 0。
- 时钟频率匹配:模式选择与时钟频率无关,但高频下(如 50 MHz 以上)需注意信号完整性,确保采样边沿稳定。
- 软件配置示例:在 STM32 或 ESP32 等 MCU 上,通过 SPI 控制寄存器设置 CPOL 和 CPHA。
📋 配置代码示例(STM32 HAL 库):
SPI_HandleTypeDef hspi1;
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; // CPOL = 0
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; // CPHA = 0
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
HAL_SPI_Init(&hspi1);
通过本节的学习,您应能清晰理解 SPI 四线的工作原理,并能根据 CPOL 和 CPHA 的组合正确配置 SPI 模式,为后续的 Flash 烧录操作打下坚实的协议基础。