SPI 四种模式:CPOL 和 CPHA 详解

做 SPI 设计,第一道坎就是分清四种模式。

CPOL 和 CPHA 这两个参数,决定了数据什么时候采样、什么时候跳变。

看似只是两位寄存器配置,一旦搞错,你的 SPI 接口要么读回全 0,要么数据歪七扭八。我见过好几个项目,Debug 花了三天,最后发现问题就是模式配反了。

1. 两个参数到底在说什么?

参数 全称 控制什么
CPOL Clock Polarity(时钟极性) 空闲时 SCK 是高电平还是低电平
CPHA Clock Phase(时钟相位) 数据是在 SCK 的第一个边沿采样,还是第二个边沿采样

CPOL = 0:空闲时 SCK 为低电平。

CPOL = 1:空闲时 SCK 为高电平。

CPHA = 0:在 SCK 的第一个边沿(上升或下降)采样数据。

CPHA = 1:在 SCK 的第二个边沿(上升或下降)采样数据。

关键理解:
— CPOL 决定“没时钟的时候线是趴着还是躺着”;
— CPHA 决定“数据是在时钟的第一次跳变被抓走,还是第二次”。

2. 四种组合,一张图说清楚

我个人习惯把这四种模式叫作 模式 0、1、2、3,对应的 CPOL/CPHA 分别是:

模式 CPOL CPHA 空闲 SCK 电平 采样边沿
0 0 0 低 上升沿(第一个边沿)
1 0 1 低 下降沿(第二个边沿)
2 1 0 高 下降沿(第一个边沿)
3 1 1 高 上升沿(第二个边沿)

你想想看:为什么模式 0 和模式 2 都是第一个边沿采样,但采样边沿一个上升一个下降?因为 CPHA=0 固定取第一个边沿,但 CPOL 决定了空闲电平和跳变方向——CPOL=0 时第一个边沿是上升,CPOL=1 时第一个边沿是下降。反过来,CPHA=1 的情况也是同理。

快速记忆法:
Mode 0 是最常用的,很多便宜传感器默认就用它。
如果你不确定从设备支持什么模式,先试 Mode 0,不行再试 Mode 3。

下面我用 SVG 把这四种模式的时序关系画了一下,方便你对比:

SPI 四种模式时序对比图 模式0 (CPOL=0, CPHA=0) MOSI: D0 D1 D2 D3 D4 D5 D6 D7 (在第一个边沿采样) 模式1 (CPOL=0, CPHA=1) MOSI: D0 D1 D2 D3 D4 D5 D6 D7 (在第二个边沿采样) 模式2 (CPOL=1, CPHA=0) MOSI: D0 D1 D2 D3 D4 D5 D6 D7 (在第一个边沿采样) 模式3 (CPOL=1, CPHA=1) MOSI: D0 D1 D2 D3 D4 D5 D6 D7 (在第二个边沿采样) 采样边沿 模式0 SCK 模式1 SCK 模式2 SCK 模式3 SCK

3. 配错了会怎样?

说白了就是采样点没对上。你发射数据是在时钟的某个边沿,但从设备却在另一个边沿采样——读到的数据会整体偏移一个 bit。

我在项目中遇到过:一个温度传感器读回来的温度值一直在 0x00 和 0x80 之间跳,根本不是有效数据。后来抓出来看波形,发现主机配置成了 Mode 0,但传感器的数据手册要求 Mode 3。因为模式 0 的第一个边沿是上升沿,而模式 3 的第二个边沿也是上升沿——听起来好像都是上升沿采样?不对!模式 0 第一个上升沿采的是 主机刚启动时的数据,而模式 3 第二个上升沿采的是 数据稳定后的值。一个字节差了一个时钟周期,当然全错。

常见陷阱:
— 一些带 SPI 的 flash 芯片既支持 Mode 0 也支持 Mode 3,但如果你配置成 Mode 1 或 Mode 2,通讯可能不稳定,偶尔对偶尔错。
— 从设备的 初始输出数据 可能是在第一个边沿之前就变化了,还是之后才变化?这决定了建立时间和保持时间是否满足。
— 我建议你查从设备数据手册中的时序图:找到 SCLK 波形旁边的 MOSI/MISO 变化点,看它是在第一个边沿变化还是在第二个边沿变化。对应 CPHA 就能定下来。

4. 实战中如何快速确认模式?

你想想看:你要是拿到一个不熟悉的从设备,又没有手册,怎么办?

我曾经用逻辑分析仪去抓从设备在空闲时 CS 拉低后的第一个时钟行为:如果从设备在 CS 拉低后、第一个时钟边沿来之前就把 MISO 数据准备好了,那多半是 CPHA=0;如果一定要等到第一个边沿之后 MISO 才有数据,那就是 CPHA=1。CPOL 更好判断——看 SCK 空闲时是高还是低就行。

调试小技巧:
在 RTL 仿真阶段,我习惯给 SPI 模块配一个 模式检测器:连续发送 0x55(01010101),然后读取回的数据。如果回的数据是 0x55 就说明模式匹配;如果是 0xAA 就说明偏移了一位;如果是乱码,说明建立时间有问题,模式本身可能没错但时序裕量不够。

5. 时序约束里怎么体现四种模式?

做 STA 的时候,四种模式的差异会直接影响你的 输入延迟 和 输出延迟 约束。

模式 采样边沿类型 数据变化相对时钟边沿 约束关注点
0 上升沿 变化在下降沿(第二个边沿) 输入数据需在上升沿前建立好
1 下降沿 变化在上升沿(第一个边沿) 输入数据需在下降沿前建立好
2 下降沿 变化在上升沿(第二个边沿) 输入数据需在下降沿前建立好
3 上升沿 变化在下降沿(第一个边沿) 输入数据需在上升沿前建立好

嗯,这里要注意:模式 0 和模式 3 虽然采样边沿都是上升沿,但数据变化的位置不同。模式 0 的数据在下降沿变化,所以从采样上升到下一次数据变化之间有半个周期(加上 CPOL 决定的空闲电平时间)来保持;模式 3 的数据也是在下降沿变化,但 CPOL=1 时,采样上升沿之后的下一个下降沿就是下一个数据变化——所以模式 3 的保持时间更紧张。我建议在对模式 3 做时序分析时,多留一点 slack。

总结:
— CPOL 决定空闲电平,CPHA 决定采样边沿顺序。
— 四种模式就是(空闲电平低/高)×(第一边沿/第二边沿)。
— 实际项目中 60% 用 Mode 0,30% 用 Mode 3,剩下的 10% 是 Mode 1 和 Mode 2 的特殊器件。
— 调试时先查手册,再看波形,最后调配置寄存器。