2. SPI时序分析:CPOL和CPHA详解
SPI通信,说白了就是主设备跟从设备之间的一种“握手”协议。但握手的方式,得提前说好。这个“说好”的过程,就体现在时钟极性(CPOL)和时钟相位(CPHA)上。
我刚开始调SPI的时候,总觉得这东西玄乎。不就是发数据嘛,时钟线拉高拉低,数据线跟着走就行了。结果呢?第一次调一个AD转换器,死活读不到数据。示波器一挂上去,波形看着也对,但就是不对。后来才发现,是CPOL和CPHA没配好。从设备要的是模式0,我配成了模式3。嗯,从那以后,我再也不敢小看这两个参数了。
2.1 CPOL和CPHA到底是什么?
先看定义,别嫌枯燥,这是基础。
- CPOL(Clock Polarity,时钟极性):决定SCLK空闲时的电平状态。
- CPOL = 0:空闲时SCLK为低电平
- CPOL = 1:空闲时SCLK为高电平
- CPHA(Clock Phase,时钟相位):决定数据是在SCLK的哪个边沿被采样。
- CPHA = 0:在第一个边沿采样(上升沿或下降沿,取决于CPOL)
- CPHA = 1:在第二个边沿采样
你想想看,这两个参数组合起来,就是4种模式。很多从设备的datasheet里会直接告诉你“支持SPI Mode 0”或者“Mode 3”。这里的Mode,指的就是CPOL和CPHA的组合。
| 模式 | CPOL | CPHA | 空闲时钟电平 | 数据采样边沿 | 数据移位边沿 |
|---|---|---|---|---|---|
| Mode 0 | 0 | 0 | 低电平 | 上升沿 | 下降沿 |
| Mode 1 | 0 | 1 | 低电平 | 下降沿 | 上升沿 |
| Mode 2 | 1 | 0 | 高电平 | 下降沿 | 上升沿 |
| Mode 3 | 1 | 1 | 高电平 | 上升沿 | 下降沿 |
这张表,我建议你收藏一下。每次调SPI之前,先看一眼,心里有个底。
2.2 四种工作模式波形图
光说理论不够,咱们直接看波形。下面这张SVG图,把四种模式的时序关系画清楚了。
核心要点:采样边沿和移位边沿总是相反的。一个边沿用来把数据从发送移位寄存器推出去(移位),另一个边沿用来把数据锁存进接收移位寄存器(采样)。
2.3 数据采样与移位时机
这里有个容易搞混的地方。很多人以为数据是在时钟边沿“同时”发送和接收的。其实不是。
SPI是全双工通信,主设备和从设备在同一个时钟边沿,各自做自己的事。具体来说:
- 移位边沿:发送方把数据从移位寄存器推一位到数据线上。
- 采样边沿:接收方从数据线上把这一位数据锁存进自己的移位寄存器。
举个例子,Mode 0(CPOL=0, CPHA=0):
- SCLK空闲是低电平。
- 第一个边沿(上升沿)到来时,接收方采样数据。
- 第二个边沿(下降沿)到来时,发送方移位数据。
你想想看,为什么采样要在移位之前?因为数据必须在采样之前就已经稳定在数据线上了。在Mode 0里,数据其实是在上一个时钟的下降沿就已经被推出来了,等到下一个上升沿,数据已经稳定了,这时候采样,稳稳的。
个人经验:我调试SPI时,习惯先用示波器抓一下SCLK和MOSI/MISO的波形,然后数一数采样点是不是在数据位的中间位置。如果采样点刚好在数据跳变的边沿上,那八成是CPOL或CPHA配反了。
2.4 时钟极性与相位匹配
匹配,是SPI调试里最关键的环节。主设备和从设备的CPOL和CPHA必须完全一致,否则通信就是鸡同鸭讲。
怎么匹配?我一般按这个步骤来:
- 查datasheet:从设备的datasheet里通常会写明支持哪种模式。比如“Supports SPI Mode 0 and Mode 3”。
- 看时序图:datasheet里有时序图,上面会标出采样点是在上升沿还是下降沿,空闲时钟是高还是低。
- 配置主设备:根据从设备的要求,配置主设备的CPOL和CPHA。
- 验证:发一个已知数据,看看回读的数据对不对。
注意:有些从设备对时序要求很苛刻,比如要求SCLK的上升沿时间不能超过某个值,或者数据建立时间(Setup Time)和保持时间(Hold Time)有严格限制。这时候光配对模式还不够,还得调整SPI时钟频率。
我曾经遇到过一个传感器,datasheet上写的是Mode 0,但我怎么调都读不到正确的数据。后来用示波器一量,发现从设备实际采样点比理论值晚了那么一点点。最后我把SPI时钟从10MHz降到了5MHz,问题就解决了。所以,时钟频率太高,有时候也会导致采样失败。
2.5 常见匹配错误与排查方法
匹配错误,是SPI调试里最常见的坑。我总结了几种典型情况:
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 读回的数据全是0xFF或0x00 | CPOL/CPHA不匹配,从设备没正确采样 | 检查datasheet,确认模式;用示波器看采样点位置 |
| 数据偶尔对,偶尔错 | 时钟频率太高,建立/保持时间不足 | 降低SPI时钟频率;检查走线长度 |
| 第一个字节正确,后面全错 | 片选信号(CS)时序问题 | 检查CS拉低到第一个时钟边沿的时间 |
| 数据移位了1位或几位 | CPHA配置错误,采样边沿和移位边沿搞反了 | 交换CPHA的值试试 |
我个人习惯,在调试新器件时,先用最低的SPI时钟频率(比如1MHz)跑一下,确保模式匹配没问题,再慢慢往上提频率。这样可以排除掉很多时序相关的干扰因素。
2.6 总结一下
CPOL和CPHA,说白了就是定义了一个“什么时候发、什么时候收”的约定。主设备和从设备必须遵守同一个约定,才能正常通信。
记住这几点:
- CPOL决定空闲电平,CPHA决定采样边沿是第一个还是第二个。
- 四种模式,Mode 0和Mode 3最常用。
- 采样边沿和移位边沿总是相反的。
- 匹配错误时,先查datasheet,再用示波器看波形。
- 时钟频率太高,也会导致采样失败。
嗯,SPI时序这部分,说难不难,说简单也不简单。关键是动手去调,多抓几次波形,心里就有数了。