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图,把四种模式的时序关系画清楚了。

SPI四种工作模式时序图 SPI 四种工作模式时序对比 Mode 0 (CPOL=0, CPHA=0) SCLK 采样 Mode 1 (CPOL=0, CPHA=1) SCLK 采样 Mode 2 (CPOL=1, CPHA=0) SCLK 采样 Mode 3 (CPOL=1, CPHA=1) SCLK 采样 SCLK 时钟线 数据采样点 注意:Mode 0 和 Mode 3 最常用 采样边沿 = 第一个边沿(CPHA=0)或第二个边沿(CPHA=1)

核心要点:采样边沿和移位边沿总是相反的。一个边沿用来把数据从发送移位寄存器推出去(移位),另一个边沿用来把数据锁存进接收移位寄存器(采样)。

2.3 数据采样与移位时机

这里有个容易搞混的地方。很多人以为数据是在时钟边沿“同时”发送和接收的。其实不是。

SPI是全双工通信,主设备和从设备在同一个时钟边沿,各自做自己的事。具体来说:

  • 移位边沿:发送方把数据从移位寄存器推一位到数据线上。
  • 采样边沿:接收方从数据线上把这一位数据锁存进自己的移位寄存器。

举个例子,Mode 0(CPOL=0, CPHA=0):

  1. SCLK空闲是低电平。
  2. 第一个边沿(上升沿)到来时,接收方采样数据。
  3. 第二个边沿(下降沿)到来时,发送方移位数据。

你想想看,为什么采样要在移位之前?因为数据必须在采样之前就已经稳定在数据线上了。在Mode 0里,数据其实是在上一个时钟的下降沿就已经被推出来了,等到下一个上升沿,数据已经稳定了,这时候采样,稳稳的。

个人经验:我调试SPI时,习惯先用示波器抓一下SCLK和MOSI/MISO的波形,然后数一数采样点是不是在数据位的中间位置。如果采样点刚好在数据跳变的边沿上,那八成是CPOL或CPHA配反了。

2.4 时钟极性与相位匹配

匹配,是SPI调试里最关键的环节。主设备和从设备的CPOL和CPHA必须完全一致,否则通信就是鸡同鸭讲。

怎么匹配?我一般按这个步骤来:

  1. 查datasheet:从设备的datasheet里通常会写明支持哪种模式。比如“Supports SPI Mode 0 and Mode 3”。
  2. 看时序图:datasheet里有时序图,上面会标出采样点是在上升沿还是下降沿,空闲时钟是高还是低。
  3. 配置主设备:根据从设备的要求,配置主设备的CPOL和CPHA。
  4. 验证:发一个已知数据,看看回读的数据对不对。

注意:有些从设备对时序要求很苛刻,比如要求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时序这部分,说难不难,说简单也不简单。关键是动手去调,多抓几次波形,心里就有数了。