2、SPI物理层与时序:CPOL时钟极性、CPHA时钟相位详解、4种工作模式(Mode 0-3)波形分析
SPI 这个协议,说白了就是四根线的事儿。很多刚入行的朋友觉得它简单,不就是 SCK、MOSI、MISO、CS 嘛。但真到了调驱动、对波形的时候,CPOL 和 CPHA 这两个参数经常把人绕晕。
我记得有一次帮同事排查一个 LCD 屏显示花屏的问题。代码逻辑看了三遍,寄存器配置也检查了,就是不对。最后拿示波器一抓,发现是 SPI 模式配错了。主设备用的是 Mode 0,从设备却工作在 Mode 3。时钟边沿对不上,数据全偏了一位。从那以后,我每次写 SPI 驱动,第一件事就是确认主从设备的模式是否一致。
2.1 物理层:四根线各司其职
先快速过一下物理层。SPI 是同步、全双工的串行接口。主设备负责产生时钟,从设备被动响应。
| 信号线 | 全称 | 方向(主设备视角) | 作用 |
|---|---|---|---|
| SCK | Serial Clock | 输出 | 由主设备产生,决定数据传输速率 |
| MOSI | Master Out Slave In | 输出 | 主设备发送数据给从设备 |
| MISO | Master In Slave Out | 输入 | 从设备发送数据给主设备 |
| CS | Chip Select | 输出 | 片选信号,低电平有效,选中目标从设备 |
这里有个细节我提一下:CS 信号在大多数应用中都是低电平有效。但有些特殊的传感器或者老式芯片,可能会用高电平选通。写驱动前一定要看数据手册,别想当然。
2.2 CPOL 和 CPHA:时钟的「脾气」
这两个参数决定了时钟信号在空闲时的状态,以及数据在哪个边沿被采样。
- CPOL(Clock Polarity):时钟极性。它定义的是 SCK 在空闲状态(CS 无效时)的电平。
- CPOL = 0:空闲时 SCK 为低电平。
- CPOL = 1:空闲时 SCK 为高电平。
- CPHA(Clock Phase):时钟相位。它定义的是数据在哪个时钟边沿被采样。
- CPHA = 0:在 SCK 的第一个边沿(上升沿或下降沿)采样数据。
- CPHA = 1:在 SCK 的第二个边沿采样数据。
你想想看,CPOL 决定了时钟的「起始姿势」,CPHA 决定了数据采样的「时机」。这两个组合起来,就是四种工作模式。
核心记忆法:
CPHA = 0 时,数据在第一个边沿被锁存。此时 MOSI/MISO 上的数据会在 SCK 第一个边沿之前就准备好。
CPHA = 1 时,数据在第二个边沿被锁存。数据会在第一个边沿之后才更新。
2.3 四种工作模式(Mode 0 - 3)
四种模式其实就是 CPOL 和 CPHA 的排列组合。我习惯用一张表来记:
| 模式 | CPOL | CPHA | 空闲时钟电平 | 数据采样边沿 | 数据输出边沿 |
|---|---|---|---|---|---|
| Mode 0 | 0 | 0 | 低电平 | 上升沿(第一个边沿) | 下降沿 |
| Mode 1 | 0 | 1 | 低电平 | 下降沿(第二个边沿) | 上升沿 |
| Mode 2 | 1 | 0 | 高电平 | 下降沿(第一个边沿) | 上升沿 |
| Mode 3 | 1 | 1 | 高电平 | 上升沿(第二个边沿) | 下降沿 |
嗯,这里要注意:Mode 0 和 Mode 3 是最常用的两种模式。很多 Flash 芯片、SD 卡默认都支持 Mode 0。而一些无线射频芯片,比如 nRF24L01,默认工作在 Mode 0,但也可以配置为 Mode 3。
2.4 波形分析:眼见为实
光看表格不够直观。我画了一张四种模式的波形对比图,你一看就明白。
从波形上可以清楚看到:
- Mode 0:SCK 空闲为低,在上升沿采样数据。这是最常用的模式,很多 MCU 的 SPI 外设默认就是这个配置。
- Mode 1:SCK 空闲为低,在下降沿采样数据。数据在上升沿更新。
- Mode 2:SCK 空闲为高,在下降沿采样数据。数据在上升沿更新。
- Mode 3:SCK 空闲为高,在上升沿采样数据。数据在下降沿更新。
个人经验: 我习惯在驱动初始化时,先读从设备数据手册里的时序图。手册上通常会标注出数据是在 SCK 的哪个边沿被锁存。如果手册上画的是「数据在 SCK 上升沿被采样」,那就对应 CPHA=0(第一个边沿)。如果画的是「数据在 SCK 下降沿被采样」,那就对应 CPHA=1(第二个边沿)。
2.5 避坑指南:模式不匹配的后果
我曾经在一个项目里,把 STM32 的 SPI 配成了 Mode 0,但外接的 ADC 芯片要求 Mode 2。结果就是:数据读出来全是乱的,偶尔对一次,大部分时间错位。
为什么会这样?因为主设备在上升沿发送数据,从设备却在下降沿采样。主设备以为数据已经送出去了,从设备却还没准备好。两边节奏对不上,数据就串位了。
重要提醒:
- 主设备和从设备的 SPI 模式必须一致,否则通信会失败。
- 同一个 SPI 总线上挂载多个从设备时,每个从设备可以有不同的模式。但每次切换从设备时,主设备需要重新配置模式。
- 有些 MCU 的 SPI 外设支持「模式自动切换」,但我不建议依赖这个功能。手动配置更可靠。
2.6 速率与模式的关系
SPI 的速率由 SCK 的频率决定。但模式会影响最高可靠速率吗?
理论上,四种模式对速率没有直接影响。但在实际布线中,Mode 0 和 Mode 3 因为采样边沿和数据边沿的间隔更均匀,抗干扰能力稍强一些。我个人在高速 SPI(比如超过 20 MHz)时,优先选择 Mode 0 或 Mode 3。
另外,CPHA=0 的模式下,数据在第一个边沿之前就必须准备好。这意味着从设备需要更快的响应时间。如果从设备比较慢,可能会出现建立时间不足的问题。这时候可以适当降低时钟频率,或者改用 CPHA=1 的模式。
总结一下:
CPOL 和 CPHA 决定了 SPI 的「握手方式」。理解它们的关键在于: