SPI协议简介:历史、应用场景与基本工作原理

SPI 这个东西,想当年我做第一块板子的时候,怎么调都调不通。明明线接对了,数据就是不对。后来才发现,时钟极性和相位没对上。说白了,SPI 看起来简单,但坑不少。今天咱们先把底子打好,后面实战才不会懵。

SPI 的历史起源

SPI 全称 Serial Peripheral Interface,是摩托罗拉在 1980 年代搞出来的。那时候并行接口太占管脚,他们想找个简单的四线方案,让主芯片能快速跟外设聊两句。

我查过老文档,最早的 SPI 只用在摩托罗拉自己的微控制器上。后来大家发现这玩意儿好使,就都跟着用了。到今天,几乎所有 MCU 都自带 SPI 硬件模块。

说起来,它从诞生就没怎么变过——简单、快速、全双工。这也解释了为啥它至今还在大量使用。

SPI 的应用场景

你想想看,哪些设备会用到 SPI?太多了:

  • 传感器:加速度计、陀螺仪、温度传感器——我项目里九成的传感器都跑 SPI,因为速度快,还能一次读多个字节。
  • 存储器:SD 卡、Flash、EEPROM。SPI Flash 几乎是嵌入式标配,存固件、存配置数据。
  • 显示驱动:液晶屏、OLED 屏。我记得有个项目用 SPI 驱动一块 320x240 的 TFT,刷新率完全够用。
  • 无线模块:Wi-Fi、蓝牙、LoRa。这类模块通常自带 SPI 从机接口,跟 MCU 数据交换很快。
  • ADC/DAC:高速模数转换器喜欢用 SPI 传结果,比 I²C 快得多。

我遇到过最头疼的兼容性问题,就是一个 SPI 温湿度传感器,手册上写的 CPOL=0、CPHA=0,实际上必须设成 CPOL=1、CPHA=1 才能读到正确数据。你说坑不坑?

SPI 的基本工作原理

SPI 是主从架构,一主多从。主设备产生时钟,从设备被动接收。它用四根线:

信号名 方向 作用
SCK(串行时钟) 主 → 从 主设备产生的时钟信号,决定数据速率
MOSI(主出从入) 主 → 从 主设备发送数据给从设备
MISO(主入从出) 从 → 主 从设备发送数据给主设备
CS(片选) 主 → 从 选中某个从设备,低电平有效

全双工是 SPI 的一大亮点。每个时钟周期,主设备在 MOSI 上发送一位,同时从设备在 MISO 上返回一位。所以一次传输,双方各发各的,互不干扰。

嗯,这里要注意:SPI 没有标准的数据包格式,没有应答。主设备想读数据,必须主动发送字节把数据“换”回来。很多新人容易误解,以为 SPI 读操作不需要主设备发东西——其实不是,你不发时钟,从设备根本不会送数据出来。

// 伪代码:SPI 读写一个字节
uint8_t spi_transfer(uint8_t tx_byte) {
    // 往数据寄存器写待发送字节
    SPI_DR = tx_byte;
    // 等待传输完成标志
    while(!(SPI_SR & TX_DONE));
    // 读数据寄存器得到接收字节
    return SPI_DR;
}

上面这个函数,你传一个字节进去,拿一个字节回来。看起来是写,其实顺便也读了。我刚开始做 SPI 驱动时,总想分开读写函数,后来发现一个函数搞定反而干净。

时钟极性与相位

这才是咱们课程的核心。SPI 的时钟极性(CPOL)和时钟相位(CPHA)决定了数据在时钟的哪个边沿被采样。

  • CPOL:空闲时 SCK 的电平。CPOL=0 时空闲为低,CPOL=1 时空闲为高。
  • CPHA:第一个时钟边沿(上升沿或下降沿)采样数据还是发送数据。CPHA=0 表示第一个边沿采样,CPHA=1 表示第二个边沿采样。

组合起来就是四种模式:

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

我曾经有个血泪教训:某款 SPI ADC 手册说支持模式 0 和模式 3,我用了模式 0,结果读回来的数据老是错位。用示波器一抓,发现它的采样时序其实符合模式 3。手册没写清楚,只能靠自己猜。

关键点:主设备和从设备的 CPOL 和 CPHA 必须完全一致,否则采样位置对不上,数据全错。这是 SPI 兼容性问题的头号元凶。
我的习惯:调试 SPI 时先用逻辑分析仪抓 CS、SCK 和 MOSI/MISO 的波形。对照对照手册上的时序图,看采样边沿对不对。很多时候一眼就能看出问题。
注意:同一颗从 IC 在不同批次、不同厂商的版本里,SPI 时序细节可能有差异。我遇到过换一批同型号芯片后,必须把时钟频率从 10MHz 降到 5MHz 才稳定。别迷信数据手册,实际测量最靠谱。
SPI 主从通信结构图 主设备 (Master) 从设备 1 (Slave 1) 从设备 2 (Slave 2) 从设备 3 (Slave 3) SCK MOSI MISO CS1 CS2 CS3 关键信号说明 • SCK:时钟由主设备产生 • MOSI/MISO:全双工数据线 • CS:片选,低电平有效

这张图里,主设备通过四根线连接多个从设备。实际硬件上,SCK、MOSI、MISO 是共享总线,只有 CS 是每个从设备独立的。选哪个从设备,就把对应的 CS 拉低。