第三章:SPI工作模式——CPOL和CPHA的四种组合
SPI的极性(CPOL)和相位(CPHA)这俩参数,新手看了头大,老手也容易翻车。我这些年调过的SPI设备少说也有几十种,踩过的坑能排成串。
说白了,CPOL决定时钟空闲时的电平。CPHA决定数据在时钟的哪个边沿被采集。两两组合,正好四种模式。
3.1 先搞清楚CPOL和CPHA各管什么事
| 参数 | 含义 | 取值 | 效果 |
|---|---|---|---|
| CPOL | 时钟极性 | 0 | 空闲时SCLK为低电平 |
| 1 | 空闲时SCLK为高电平 | ||
| CPHA | 时钟相位 | 0 | 第一个边沿(上升或下降)采集数据 |
| 1 | 第二个边沿采集数据 |
CPOL = 0,空闲低。CPOL = 1,空闲高。这个好记。
CPHA = 0,时钟的第一个动作(从空闲跳变到有效)用来锁存。CPHA = 1,时钟的第二个动作(从有效跳变回空闲)用来锁存。
我当年犯过的错
我曾经把一个CPHA=0的从机,配成了CPHA=1,结果数据全是乱的。示波器上波形看着像那么回事,但读出来的字节对不上。后来发现手册里写着“Data is latched on the first edge”,我愣是没当回事。从那以后我再也不敢只看波形猜模式了。
3.2 四种模式一览表
| 模式 | CPOL | CPHA | 空闲时钟 | 数据采样边沿 | 常见从机芯片举例 |
|---|---|---|---|---|---|
| 模式0 | 0 | 0 | 低 | 上升沿(第一个边沿) | 大多数通用SPI Flash、SD卡 |
| 模式1 | 0 | 1 | 低 | 下降沿(第二个边沿) | 某些ADC、DAC |
| 模式2 | 1 | 0 | 高 | 下降沿(第一个边沿) | 部分温度传感器 |
| 模式3 | 1 | 1 | 高 | 上升沿(第二个边沿) | 很多微控制器内部SPI外设 |
这里有个规律:模式0和模式3,采样边沿都是上升沿。模式1和模式2,采样边沿都是下降沿。区别就在空闲电平上。
3.3 一张图看懂四种模式
下面这个SVG图把四种模式的时钟和数据关系画出来了。我建议你存下来,写代码之前看一眼。
3.4 如何快速确定该用哪个模式
打开从机数据手册,找到时序图那一页。看两个地方:
- 空闲时SCLK是高还是低 —— 对应CPOL
- 数据是在第一个边沿变化,还是第二个边沿被采集 —— 对应CPHA
举个例子。你拿一个SPI Flash芯片,手册上写“Data is shifted on the rising edge of SCLK”。如果空闲时SCLK是低,那就是模式0。如果空闲时SCLK是高,那就是模式3。
我个人的习惯
调新板子时,我一般先把主机配成模式0。因为绝大多数器件默认支持模式0。如果通信不正常,我再试着切模式3(都一样是上升沿采样,只是空闲电平不同)。
3.5 代码里怎么配置
不同MCU配置方式不一样,但思路一致。以STM32的HAL库为例:
// SPI句柄初始化
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; // CPOL = 0
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; // CPHA = 0
// 这就是模式0
// 如果你想用模式1(CPOL=0, CPHA=1):
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
// 模式2(CPOL=1, CPHA=0):
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
// 模式3(CPOL=1, CPHA=1):
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
避坑小贴士
我曾经遇到过一款国产温度传感器,手册上写着“支持模式0和模式3”。我试了模式0,能读,但偶尔丢一个字节。换成模式3,稳如老狗。后来查勘误表才发现——芯片内部逻辑对下降沿触发有微小的保持时间裕量问题。所以多试一种模式,有时候能救命。
3.6 用逻辑分析仪判断当前模式
如果你手头有逻辑分析仪(我每次都开),抓一段SCLK和CS的波形,看CS拉低之后第一个时钟跳变的方向:
- 如果空闲低,第一个跳变是上升沿 → 可能是模式0(CPHA=0)
- 如果空闲低,第一个跳变是下降沿 → 可能是模式1(CPHA=1)
- 如果空闲高,第一个跳变是下降沿 → 可能是模式2(CPHA=0)
- 如果空闲高,第一个跳变是上升沿 → 可能是模式3(CPHA=1)
再看片选释放时SCLK是啥电平:如果和空闲一致,基本就能确认。
嗯,这章就到这。四种模式,说穿了就是自由组合两个只有0/1的开关。关键是要和从机芯片的时序图对上号。调通一次,以后就快了。