4. SPI 协议详解:四线机制与时钟配置

SPI 这玩意儿,说实话,是我在嵌入式开发里用得最多的同步串口之一。它简单、高效,而且几乎所有 MCU 都自带硬件外设。但很多人只停留在「会调库」的阶段,一旦遇到通信不稳定、数据错位,就抓瞎了。

今天咱们就把 SPI 的四根线、时钟极性(CPOL)和相位(CPHA)彻底讲透。我保证,听完这节课,你不仅能调通 SPI,还能自己排查 90% 的通信问题。

4.1 四线机制:SCK、MOSI、MISO、CS

SPI 全称是 Serial Peripheral Interface,同步、全双工、主从架构。它用四根线搞定一切:

信号线 全称 方向(主→从) 作用
SCK Serial Clock 主→从 时钟信号,由主机产生,决定数据传输速率
MOSI Master Out Slave In 主→从 主机发送数据给从机
MISO Master In Slave Out 从→主 从机发送数据给主机
CS Chip Select 主→从 片选信号,低电平有效,选中特定从机

这里有个关键点:SPI 是全双工的。什么意思?主机在发送一个字节的同时,也在接收从机发来的一个字节。你想想看,这比 I2C 那种半双工要快一倍。

核心理解:SPI 的收发是同时发生的。主机每发出一个 SCK 脉冲,MOSI 上送出一位数据,MISO 上同时采样一位数据。所以 SPI 的「发送」和「接收」其实是同一件事的两个面。

我个人习惯把 SPI 比作「乒乓球对打」:主机发一个球(MOSI),从机同时回一个球(MISO),SCK 就是击球的节奏。CS 则是喊「轮到你了」的开关。

4.2 时钟极性(CPOL)和相位(CPHA)

好,重点来了。CPOL 和 CPHA 这两个参数,我见过太多工程师在这上面翻车。说白了,它们决定了 SCK 在空闲时的电平,以及数据在哪个边沿被采样。

4.2.1 CPOL:时钟极性

CPOL 定义的是 SCK 在空闲状态(没有数据传输时)的电平。

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

嗯,就这么简单。但别急,它要和 CPHA 配合起来看。

4.2.2 CPHA:时钟相位

CPHA 定义的是数据在 SCK 的哪个边沿被采样。

  • CPHA = 0:在 SCK 的第一个边沿采样数据(上升沿或下降沿,取决于 CPOL)。
  • CPHA = 1:在 SCK 的第二个边沿采样数据。

你可能会问:「第一个边沿是上升还是下降?」这取决于 CPOL。我整理了一张表,你一看就明白:

SPI 模式 CPOL CPHA 空闲时钟电平 数据采样边沿 数据输出边沿
模式 0 0 0 低 上升沿(第一个边沿) 下降沿
模式 1 0 1 低 下降沿(第二个边沿) 上升沿
模式 2 1 0 高 下降沿(第一个边沿) 上升沿
模式 3 1 1 高 上升沿(第二个边沿) 下降沿

实战技巧:大多数 SPI 从机芯片默认使用模式 0(CPOL=0, CPHA=0)。但总有些「刺头」芯片用模式 3。我建议你拿到 datasheet 后,第一件事就是查 SPI 模式。我曾经因为没看 datasheet,调一个 LCD 驱动调了整整一下午,最后发现是模式配反了。

4.3 数据采样与建立的时序关系

为什么 CPOL 和 CPHA 这么重要?因为它直接决定了数据能否被正确采样。你想想看,如果主机在某个边沿输出数据,而从机却在同一个边沿采样,那采到的可能是上一个位,或者是不稳定的跳变。

正确的做法是:数据在一个边沿建立(输出),在另一个边沿采样(捕获)。这样数据有半个时钟周期的时间稳定下来。

以模式 0 为例:

  • SCK 空闲为低。
  • 主机在 SCK 的下降沿更新 MOSI 上的数据。
  • 从机在 SCK 的上升沿采样 MOSI 上的数据。

这样,数据从更新到被采样,中间有半个时钟周期的建立时间,足够信号稳定。

注意:如果 CPOL 和 CPHA 配置错误,数据可能会在跳变边沿被采样,导致读到错误的值。这种错误非常隐蔽,因为数据看起来「大部分是对的」,但偶尔会跳变。我曾经在一个传感器项目中遇到过,读出来的温度值每隔几秒就跳一下,最后用示波器一看,原来是 CPHA 配反了。

4.4 多从机连接方式

SPI 支持一主多从。有两种接法:

  • 独立片选:每个从机独占一根 CS 线。主机想和谁通信,就把对应的 CS 拉低。这是最常用的方式。
  • 菊花链:所有从机共用 CS 和 SCK,但 MOSI 和 MISO 串联起来。数据像流水线一样依次经过每个从机。这种方式用得少,一般只在移位寄存器场景下用。

我个人强烈建议用独立片选。菊花链虽然省 IO,但调试起来太痛苦了——任何一个从机出问题,整条链都废了。

4.5 知识结构图:SPI 协议核心逻辑

下面这张图帮你把 SPI 的整个知识脉络串起来:

SPI 协议核心逻辑结构图 SPI 协议核心逻辑 物理层:四线 SCK | MOSI | MISO | CS 时序层:CPOL + CPHA CPOL=0/1 CPHA=0/1 4 种 SPI 模式 模式0/1/2/3 连接方式 独立片选 菊花链 数据采样 建立边沿 采样边沿 关键:主从双方 CPOL/CPHA 必须一致 否则数据采样会错位,通信失败

4.6 实战中的避坑指南

最后,分享几个我这些年踩过的坑:

  • CS 的拉高时机:很多从机要求在最后一个 SCK 边沿之后保持 CS 低电平一段时间(称为 CS hold time)。如果 CS 拉高太快,从机可能还没完成内部处理,导致数据丢失。我一般会在传输结束后加一个微秒级的延时再拉高 CS。
  • 时钟频率上限:SPI 的速率不是越高越好。从机有最大时钟频率限制,而且 PCB 走线太长时,高速信号会反射。我遇到过在 20MHz 下跑得好好的,换了一根长排线就乱码了。降频到 10MHz 就稳了。
  • MISO 竞争:多从机共用 MISO 线时,必须保证未选中的从机把 MISO 置为高阻态,否则多个从机同时驱动 MISO 会打架。有些老芯片不支持高阻,那就得加三态缓冲器。

调试利器:逻辑分析仪是调试 SPI 最好的工具。把 SCK、MOSI、MISO、CS 四根线都抓下来,对照 datasheet 的时序图看。我曾经用这个方法,半小时就找到了一个隐藏了三天的问题——原来是 CS 的毛刺导致从机被误选中。