1. SPI协议基础:从起源到全双工通信

SPI,全称是Serial Peripheral Interface,串行外设接口。这玩意儿是摩托罗拉在80年代搞出来的,初衷很简单——让微控制器能快速跟外设芯片交换数据。我最早接触SPI是在做一款工业传感器采集板的时候,那时候I²C速度跟不上,UART又太浪费引脚,SPI正好卡在中间,又快又灵活。

说白了,SPI就是一条四线制的同步串行总线。同步的意思是,它靠时钟来对齐数据,不像UART那样需要两边约定好波特率。这一点在实际调试中特别省心——你只要把时钟线接对,数据基本不会跑偏。

四线制到底在传什么?

SPI的四根线,每一根都有明确的职责。我见过不少新手把这四根线搞混,结果焊完板子发现通信死活不通。咱们一个一个说清楚。

信号线 全称 方向 一句话职责
SCLK Serial Clock 主机→从机 提供同步节拍,决定通信速率
MOSI Master Out Slave In 主机→从机 主机发数据给从机
MISO Master In Slave Out 从机→主机 从机发数据给主机
CS Chip Select 主机→从机 片选信号,低电平有效,选中谁就跟谁聊

这里有个容易踩的坑——MOSI和MISO的名字已经说清楚了方向。MOSI是主机输出、从机输入;MISO是主机输入、从机输出。我曾经遇到过一块板子,硬件工程师把这两根线画反了,结果主机发出去的数据从机收不到,从机回的数据主机也读不到。查了整整半天才找到原因。

注意:SPI的CS信号通常是低电平有效。也就是说,CS拉低,从机开始工作;CS拉高,从机释放总线。这个习惯跟很多其他协议相反,刚接触时容易搞混。

全双工通信——同时收发才是SPI的灵魂

SPI最让我欣赏的一点,就是它天生支持全双工。什么叫全双工?就是主机在发数据的同时,从机也在往回发数据。一根时钟线,两个方向的数据流,互不干扰。

你想想看,UART虽然也能全双工,但它需要两根独立的数据线,而且两边得各自约定波特率。I²C更惨,它是半双工的,发的时候不能收,收的时候不能发。SPI就不一样了——一个时钟周期内,MOSI上走一位数据给从机,MISO上同时走一位数据回主机。

为什么会这样?因为SPI本质上是一个环形移位寄存器。主机和从机内部各有一个移位寄存器,时钟每跳一次,两个寄存器同时移一位。主机移出去的数据进了从机,从机移出去的数据进了主机。就这么简单。

核心理解:SPI的每一次时钟跳变,都是一次数据交换。主机发出去一个bit,同时收回一个bit。所以从软件角度看,你调用SPI发送函数时,收到的返回值其实就是从机发给你的数据。

我记得有一次调试一个ADC芯片,手册上说读数据之前要先发一个命令字节。我按常规思路先发命令,再单独读数据,结果读回来的全是0。后来仔细看时序图才发现——发命令的那个时钟周期里,ADC已经把转换结果的高位发回来了。我等于把有效数据扔了。从那以后,我写SPI驱动时都会记住:每一次SPI读写,都是同时发生的。

SPI的四种模式——时钟极性那点事

SPI有四种工作模式,由时钟极性(CPOL)和时钟相位(CPHA)组合决定。这俩参数搞错了,通信就会出乱码。我见过最离谱的一次,是两边的工程师各用各的默认模式,结果数据对不上,互相甩锅。

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

实际项目中,绝大多数SPI器件默认用模式0。但千万别想当然——我吃过一次亏,某款国产加速度传感器手册上写的是模式3,我没仔细看,直接用模式0驱动,数据读出来全是乱码。后来用逻辑分析仪抓波形才发现,时钟空闲电平不对。

我的习惯:拿到一个新器件,第一件事就是翻手册里的时序图,确认CPOL和CPHA。别信默认值,信手册。

SPI通信的核心流程

一次完整的SPI传输,大致分三步:

  1. 拉低CS——告诉从机:我要跟你说话了。
  2. 产生SCLK时钟——每来一个时钟,MOSI和MISO上各走一位数据。通常是高位在前(MSB first),但也有少数器件用低位在前。
  3. 拉高CS——传输结束,从机释放总线。

这里有个细节:CS拉低期间,时钟可以连续产生,也可以间断。有些器件要求CS拉低后必须连续发完一整个字节,中间不能停;有些则无所谓。嗯,这个得看具体芯片的手册。

下面这张图是我自己画的SPI全双工通信流程,帮你把整个数据流动看清楚。

SPI全双工通信数据流 主机 (Master) 移位寄存器 从机 (Slave) 移位寄存器 SCLK 时钟线 MOSI 数据线 MISO 数据线 CS 片选线 数据流动说明 ① 主机通过SCLK提供时钟,控制通信节奏 ② 每个时钟周期,主机通过MOSI发1bit,同时通过MISO收1bit ③ CS拉低期间,通信持续;CS拉高,本次传输结束

SPI的优缺点——没有银弹

SPI不是万能的。它有自己的长处,也有明显的短板。我列个表,你一看就明白。

优势 劣势
全双工,收发同时进行 需要4根线,引脚占用多
传输速率高,轻松上几十MHz 没有内置应答机制,丢数据不知道
硬件实现简单,软件驱动容易 多从机时需要额外CS引脚
支持多从机级联(菊花链) 传输距离短,一般不超过几米

我个人觉得,SPI最适合的场景是:板上通信、高速数据采集、显示驱动、存储器读写。如果你要做长距离传输或者需要多设备总线仲裁,那还是考虑CAN或者RS-485更靠谱。

一句话总结:SPI用四根线、一根时钟、全双工、主从结构,实现了简单高效的短距离高速通信。理解它的四线职责和全双工原理,是后面调试多设备级联的基础。