一、什么是 SPI?
SPI(Serial Peripheral Interface,串行外设接口)是一种同步串行通信。它有一根专门的时钟线,主机发出节拍,双方在节拍的约定边沿上读写数据。因为有时钟,它不需要像 UART 那样事先约定速率,也更容易做到高速。
类比:UART 像两个人各自数拍子说话,要事先约定速度;SPI 像一个乐队,指挥(主机)举起指挥棒,每一下都是一个节拍,所有乐手(双方)都跟着这一下来演奏。节拍一到,大家同时交换一个音符。
全双工的含义:SPI 的两根数据线(MOSI、MISO)是分开的,主机发送的同时也在接收。每一个时钟脉冲,都在交换 1 位数据,发送与接收同时进行。
二、四根线的含义
| 信号 | 全称 | 方向 | 作用 |
| SCK | Serial Clock | 主机 → 从机 | 时钟线,由主机产生,决定每一位的节拍 |
| MOSI | Master Out Slave In | 主机 → 从机 | 主机发送数据给从机 |
| MISO | Master In Slave Out | 从机 → 主机 | 从机把数据返回给主机 |
| CS / SS | Chip Select / Slave Select | 主机 → 从机 | 片选,低电平有效,表示"现在和我说话的是这一台" |
SPI 主机与从机 同名信号连接;芯片的实际命名可能不同
同名引脚直接相连,不是交叉:主机的 MOSI 接从机的 MOSI,主机的 MISO 接从机的 MISO(与 UART 的 TX/RX 交叉不同)。很多芯片的手册写的是 SDI / SDO,对应关系是:从机的 SDI 就是 MOSI,SDO 就是 MISO。
三、主机与从机:片选 CS
SPI 的结构是一主多从:主机控制时钟,从机只能被动响应。当总线上挂了多个从机时,主机用 CS(片选)来决定和谁通信:
- 主机把某个从机的 CS 拉低(选中它)。
- 主机发送时钟和数据,与被选中的从机交换数据。
- 通信结束后,把 CS 拉回高电平(释放它)。
CS 的重要性:没有 CS,多个从机会同时响应总线,数据就混在一起了。CS 也是 SPI 中最容易出问题的地方:忘了拉低,从机根本不响应;拉低的时间不对,数据就不完整。
四、时钟极性 CPOL 与相位 CPHA
SPI 没有统一的"哪一个边沿采样"的规定,而是用两个参数来定义,一共四种组合,叫模式 0 ~ 3:
| 参数 | 含义 | 取值 |
| CPOL | 时钟空闲(不传输时)的电平 | 0:空闲为低;1:空闲为高 |
| CPHA | 数据在哪个边沿采样 | 0:在第一个边沿采样;1:在第二个边沿采样 |
| 模式 | CPOL | CPHA | 采样发生在 |
| 模式 0 | 0 | 0 | 第一个边沿(上升沿)采样,下降沿改变数据 |
| 模式 1 | 0 | 1 | 第二个边沿(下降沿)采样,上升沿改变数据 |
| 模式 2 | 1 | 0 | 第一个边沿(下降沿)采样,上升沿改变数据 |
| 模式 3 | 1 | 1 | 第二个边沿(上升沿)采样,下降沿改变数据 |
怎么记?模式 0 最常见,"空闲为低,第一个上升沿采样"。其它模式就是把空闲电平或采样边沿翻转。关键是:主机与从机必须使用相同的模式,否则数据会错位,表现为读出来的数字完全不对。
CPOL 决定时钟"空闲在哪里";CPHA 决定"在哪个边沿读数据"
查手册时,看到 SPI_MODE 或 CPOL/CPHA,就是这两个参数
五、动手看波形:四种模式
选择模式和要发送的字节(MSB 在前,即先发最高位)。图中红色虚线是采样时刻,观察 MOSI 上的数据在哪个边沿被读取。
红色虚线 = 从机在此刻采样 MOSI
读图的方法:先看 SCK 的空闲电平(CPOL),再看红色采样线落在 SCK 的哪个边沿上(CPHA)。数据线在采样线之前就要稳定下来,这是 SPI 的建立时间要求。
六、速率与传输时间
SPI 的速率就是 SCK 的频率。每一个时钟周期传 1 位,所以传 1 个字节需要 8 个周期:
每字节时间 = 8 / f_SCK
每秒字节数(理论)= f_SCK / 8
例:SCK = 10 MHz 时,每秒理论可传 1.25 MB。实际还要加上片选切换、从机处理等开销
-
速率不是越高越好:SCK 太快,导线的电容、从机的建立时间可能跟不上,表现为偶尔读错。短线(板内)可以用高速,但接线变长、加了杜邦线后,要适当降低速率。以从机数据手册的最大 SCK 为上限。
七、多从机连接
SPI 挂多个从机有两种常见方式:
| 方式 | 接法 | 优缺点 |
| 独立片选(最常用) | SCK、MOSI、MISO 并联到所有从机,每个从机有自己的 CS 线 | 简单可靠,每增加一个从机就多占一个 IO 脚 |
| 菊花链(Daisy chain) | 前一个从机的 MISO 接后一个从机的 MOSI,整条链共用一个 CS | 省 IO 脚,但所有从机要一起收发,数据要一级一级移位 |
类比:独立片选像一个老师分别叫每个学生回答问题(每人一个名字);菊花链像一排学生,老师只能对第一排喊,数据从前往后一个接一个传下去。
注意:多个从机的 MISO 不能直接并联在一起。未被选中的从机必须让 MISO 进入高阻态(三态输出),否则会和被选中的从机"打架"。大多数从机在 CS 为高时会自动释放 MISO。
八、常见问题排查
| 现象 | 最可能的原因 | 怎么查 |
| 读回全是 0 或全是 1 | MISO 没接好,或从机没有选中(CS 没拉低) | 用示波器看 CS 是否真的拉低;查 MISO 连线 |
| 读回的数据位序颠倒或错位 | CPOL/CPHA 模式不一致;或 MSB/LSB 顺序设错 | 对照从机手册确认模式和位序,两边统一 |
| 偶尔读错 | SCK 太快,或线路干扰、接线过长 | 降低 SCK;缩短连线;加串联小电阻抑制振铃 |
| 多个从机互相干扰 | 未选中的从机没有释放 MISO,或 CS 没有正确分开 | 检查每个 CS 的控制逻辑;确认只有一个 CS 同时为低 |
| 写入后从机没反应 | 写入时序不对(如 CS 释放太早) | 查从机手册的命令时序,CS 要在整个命令期间保持低 |
十、本节小结
- SPI 是同步、全双工的串行通信,有 SCK、MOSI、MISO、CS 四根线,一主多从。
- CS 低电平选中从机,通信期间必须保持低。
- CPOL 决定时钟空闲电平,CPHA 决定采样边沿,组合成模式 0 ~ 3。主从两边必须一致。
- 每个字节需要 8 个时钟周期,理论吞吐量为 f_SCK / 8 字节每秒。
- 多从机用独立片选最常见;未选中的从机要释放 MISO。
下一页:第9课(四):I²C,两根线挂很多器件
上一页:第9课(二):RS485