4. SPI 基础配置:时钟极性、时钟相位、数据帧格式与波特率
SPI 通信的可靠性高度依赖于主从设备之间的时序参数完全一致。在配置 MCU 的 SPI 外设时,必须正确设置 时钟极性 (CPOL)、时钟相位 (CPHA)、数据帧格式 和 波特率 四个核心参数。任何一项配置错误,都会导致数据移位错位或通信失败。
4.1 时钟极性 (CPOL) 与时钟相位 (CPHA)
CPOL 和 CPHA 共同决定了 SPI 总线上时钟信号 (SCK) 的空闲电平状态以及数据采样/切换的边沿。这两个参数通常组合为 4 种模式 (Mode 0 ~ Mode 3)。
| SPI 模式 | CPOL | CPHA | 空闲时钟电平 | 数据采样边沿 | 数据切换边沿 |
|---|---|---|---|---|---|
| Mode 0 | 0 | 0 | 低电平 | 第一个跳变沿 (上升沿) | 第二个跳变沿 (下降沿) |
| Mode 1 | 0 | 1 | 低电平 | 第二个跳变沿 (下降沿) | 第一个跳变沿 (上升沿) |
| Mode 2 | 1 | 0 | 高电平 | 第一个跳变沿 (下降沿) | 第二个跳变沿 (上升沿) |
| Mode 3 | 1 | 1 | 高电平 | 第二个跳变沿 (上升沿) | 第一个跳变沿 (下降沿) |
开发提示: 绝大多数 SPI 从设备默认使用 Mode 0 (CPOL=0, CPHA=0) 或 Mode 3 (CPOL=1, CPHA=1)。在配置前,务必查阅目标从设备的数据手册中的时序图,确认其要求的 SCK 空闲电平和采样边沿。
下图展示了 Mode 0 和 Mode 3 的典型时序差异,重点关注 SCK 空闲电平与数据采样点的位置。
4.2 数据帧格式:8 位与 16 位
SPI 外设支持可编程的数据帧长度,通常为 8 位 或 16 位。此设置决定了每次片选 (CS) 有效期间,通过 MOSI/MISO 线传输的数据位数。
- 8 位数据帧 (DS=0): 最常用模式,兼容绝大多数 SPI 传感器、存储器 (如 Flash, EEPROM) 和 ADC 芯片。每次传输一个字节。
- 16 位数据帧 (DS=1): 用于某些高速 DAC、音频编解码器或特定协议设备。一次传输两个字节,效率更高,但需确保从设备支持。
配置陷阱: 当主设备配置为 16 位帧格式,而从设备仅支持 8 位时,通信将完全错位。务必通过数据手册确认从设备的帧格式要求。对于支持 8 位/16 位混合通信的 MCU,通常需要软件干预来切换寄存器。
4.3 波特率设置
SPI 波特率决定了 SCK 时钟的频率,直接影响通信速度。波特率通常由 MCU 系统时钟 (PCLK) 经过分频得到。
计算公式:
SPI_波特率 = PCLK / 分频系数
常见的分频系数包括 2、4、8、16、32、64、128、256。例如,当 PCLK = 72 MHz 时:
| 分频系数 | SPI 波特率 | 典型应用场景 |
|---|---|---|
| 2 | 36 MHz | 高速 Flash、SRAM |
| 4 | 18 MHz | 高速 ADC、LCD 驱动 |
| 8 | 9 MHz | 通用传感器、EEPROM |
| 16 | 4.5 MHz | 低速传感器、隔离通信 |
| 64 | 1.125 MHz | 长线缆、抗干扰场景 |
波特率选择原则:
- 从设备上限: 波特率不得超过从设备数据手册标称的最大 SCK 频率。
- 信号完整性: 在 PCB 走线较长或环境干扰较大时,适当降低波特率以保证数据无误。
- DMA 传输考量: 在轮询模式下,波特率受 CPU 处理速度限制;若后续启用 DMA,可尝试使用更高分频系数以释放 CPU 负载。
4.4 配置流程与代码示例
以下代码展示了在 STM32 HAL 库中如何配置 SPI1 为 Mode 0、8 位数据帧、8 MHz 波特率 (假设 PCLK=72 MHz)。
SPI_HandleTypeDef hspi1;
void MX_SPI1_Init(void)
{
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; // 软件管理片选
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; // 72/8 = 9 MHz
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; // MSB 先行
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
下图总结了 SPI 基础配置的完整决策流程,帮助开发者在初始化时快速定位参数。
4.5 常见配置错误与排查
- 时钟模式不匹配: 主设备使用 Mode 0,从设备使用 Mode 3,导致数据采样点错误。排查时使用示波器测量 SCK 空闲电平。
- 帧格式不一致: 主设备配置为 16 位,从设备仅支持 8 位,导致数据移位。检查数据手册中的帧格式说明。
- 波特率过高: 从设备无法响应高速 SCK,导致数据读出为 0xFF 或随机值。尝试降低分频系数。
- MSB/LSB 顺序错误: 部分设备要求 LSB 先行,若配置为 MSB 先行,数据会反向。确认 FirstBit 配置。