1. SPI协议基础:从一根线到四根线的进化

大家好,我是你们的嵌入式驱动开发讲师。今天咱们聊聊SPI——这个在嵌入式世界里几乎无处不在的串行通信协议。

说实话,我刚入行那会儿,总觉得SPI不就是四根线嘛,有啥好学的?直到有一次调试一块LCD屏幕,死活刷不出图像,最后发现是时钟极性配反了……嗯,从那以后我再也不敢小看这四根线了。

1.1 SPI总线概述

SPI,全称Serial Peripheral Interface,串行外设接口。它由摩托罗拉公司在80年代推出,初衷很简单——给微控制器和外围设备之间搭一条高速通道。

你想想看,I2C虽然省引脚,但速度上不去;UART虽然简单,但只能点对点。SPI呢?速度可以跑到几十兆赫兹,还支持多设备,所以成了ADC、DAC、LCD、SD卡、传感器这些外设的标配接口。

SPI的核心特点:

  • 全双工通信——发送和接收同时进行,不像I2C那样需要等应答
  • 主从模式——一个主设备控制时钟,一个或多个从设备响应
  • 同步通信——所有数据交换都由主设备产生的时钟驱动
  • 高速率——典型速率在1MHz到50MHz之间,有些器件能跑到100MHz+

我个人习惯把SPI比作「乒乓对话」:主设备每发一个字节,从设备就回一个字节。你发出去的数据和收进来的数据,是同一时钟沿上完成的。这个特性在驱动开发中特别重要——后面讲中断和DMA的时候你会深有体会。

1.2 四线制信号定义

标准的SPI接口有四根信号线。我见过不少新手把这四根线搞混,尤其是MISO和MOSI——焊反了可是要飞线的。

信号名 全称 方向 作用
SCLK Serial Clock 主→从 由主设备产生,同步数据传输
MOSI Master Out Slave In 主→从 主设备发送数据给从设备
MISO Master In Slave Out 从→主 从设备发送数据给主设备
SS/CS Slave Select / Chip Select 主→从 片选信号,低电平有效,选中从设备

这里有个小细节:MOSI和MISO的名字是站在主设备角度定义的。所以从设备那边,MOSI引脚其实是数据输入,MISO是数据输出。我曾经见过一块国产芯片,它的数据手册把这两个引脚标反了,害得我排查了半天——所以拿到新芯片,第一件事就是核对引脚定义。

避坑指南: 多从机共用一个SPI总线时,所有从设备的SCLK、MOSI、MISO都并联在一起,但每个从设备必须有独立的SS引脚。我曾经为了省GPIO,用了一个译码器来选通SS,结果时序上出了点问题——后面讲多从机拓扑时会细说。

1.3 主从模式与多从机拓扑

SPI的通信模型很简单:一个主设备,一个或多个从设备。主设备负责产生时钟、控制片选、发起传输。从设备只能被动响应。

多从机拓扑有两种常见方式:

  1. 独立片选方式——每个从设备独占一根SS线,主设备用多个GPIO分别控制。优点是软件简单,缺点是占用引脚多。
  2. 菊花链方式——所有从设备共用SS和SCLK,但数据像串糖葫芦一样从一个设备传到下一个。优点是省引脚,缺点是延迟大、软件复杂。

我个人在实际项目中几乎只用独立片选方式。菊花链虽然看起来高级,但调试起来太痛苦了——任何一个从设备出问题,整条链都断了。

下面这张图展示了典型的单主多从拓扑结构:

SPI单主多从拓扑结构图 主设备 (Master) SCLK | MOSI | MISO 从设备1 (Slave) 从设备2 (Slave) 从设备3 (Slave) SCLK MOSI MISO SS1 SS2 SS3 拓扑说明 • 主设备产生SCLK时钟 • MOSI连接所有从设备 • MISO连接所有从设备 • 每个从设备独立SS • 同一时刻只选通一个从设备 • 未选中的从设备MISO为高阻 优点: 软件控制简单 设备间互不干扰 缺点:占用GPIO多

1.4 时钟极性与相位(CPOL/CPHA)详解

好了,到了本章最核心、也最容易踩坑的部分——时钟极性和相位。我敢说,十个SPI驱动出问题,有八个是这里配错了。

CPOL(Clock Polarity) 决定时钟空闲时的电平:

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

CPHA(Clock Phase) 决定数据在哪个时钟沿被采样:

  • CPHA = 0:在第一个时钟沿采样(上升沿或下降沿,取决于CPOL)
  • CPHA = 1:在第二个时钟沿采样

组合起来就是四种模式:

模式 CPOL CPHA 空闲电平 数据采样沿 数据变化沿
模式0 0 0 低 上升沿 下降沿
模式1 0 1 低 下降沿 上升沿
模式2 1 0 高 下降沿 上升沿
模式3 1 1 高 上升沿 下降沿

你可能会问:「这么多模式,我该用哪个?」

答案是:看从设备的数据手册。每个SPI从设备都会明确标注它支持哪种模式。比如常见的W25Q系列Flash,支持模式0和模式3;而某些ADC只支持模式1。

重要提醒: 主设备和从设备的CPOL和CPHA必须完全一致,否则数据会错位。我曾经调试一块OLED屏,图像一直花屏,用逻辑分析仪抓了波形才发现——主设备配的是模式0,从设备要的是模式3。就差一个时钟沿,折腾了我一整天。

下面这张时序图能帮你直观理解四种模式的区别:

SPI四种模式时序对比图 SPI四种模式时序对比 模式0 (CPOL=0, CPHA=0) SCLK ↑采样 ↑采样 ↑采样 ↑采样 模式1 (CPOL=0, CPHA=1) SCLK ↓采样 ↓采样 ↓采样 ↓采样 模式2 (CPOL=1, CPHA=0) SCLK ↓采样 ↓采样 ↓采样 ↓采样 模式3 (CPOL=1, CPHA=1) SCLK ↑采样 ↑采样 ↑采样 ↑采样 MOSI D7 D6 D5 D4 D3 D2 D1 D0 关键记忆法:CPOL决定空闲电平,CPHA决定采样沿。 CPHA=0时在第一个沿采样,CPHA=1时在第二个沿采样。

这里分享一个我自己的记忆方法:「CPOL看空闲,CPHA看第几」。CPOL=0时空闲低电平,CPOL=1时空闲高电平;CPHA=0时第一个沿采样,CPHA=1时第二个沿采样。简单吧?

调试技巧: 如果你不确定从设备用哪种模式,可以用逻辑分析仪抓一下从设备在空闲时的SCLK电平——高就是CPOL=1,低就是CPOL=0。然后看数据变化发生在哪个沿,就能反推出CPHA。我每次拿到新模块,第一件事就是抓波形确认模式,绝不只看数据手册——因为手册也可能写错。

1.5 本章小结

好了,SPI协议的基础部分就讲到这里。我们聊了四根信号线的定义、主从拓扑的两种方式、以及最容易出错的时钟极性和相位配置。

记住一句话:SPI驱动开发,七分配置,三分代码。只要把CPOL/CPHA、时钟频率、数据位宽这些参数配对了,剩下的就是收发数据的事。配错了?嗯,那就准备好逻辑分析仪慢慢查吧。