通信协议篇三:SPI 通信原理详解之时钟模式、时序与W25Q32示例
- 嵌入式开发
- 14小时前
- 25热度
- 0评论
SPI 是嵌入式开发里最常见的高速串行总线之一。相比 I2C 和 UART,SPI 结构更直接、速度更高,也更适合和 Flash、ADC、DAC、显示屏等板级外设通信。本文从底层原理、时钟模式、通信时序到 W25Q32 读 ID 实验,系统讲清 SPI 到底是怎么工作的。
一、SPI 是什么
SPI 的典型特点可以直接概括为:
- 速度高:常见工作频率为 几 MHz 到几十 MHz
- 协议简单:无地址、无统一 ACK、无总线仲裁
- 全双工:主从可在同一时钟下同时收发数据
- 片选通信:通过
CS/SS选择目标从设备
SPI 通常采用单主多从结构:
- 主设备负责发起通信
- 主设备负责提供时钟
SCLK - 从设备在主设备给出的时钟下完成数据输入与输出
- 多个从设备通常共享时钟线和数据线,靠不同的片选线区分
SPI 常用于 MCU 与 Flash、ADC、DAC、显示屏、传感器等外设之间进行板级数据交换,特别适合以下场景:
- 屏幕刷新
- Flash 连续读写
- ADC / DAC 数据搬运
- 高频率寄存器访问
- 板内短距离高速通信
常见连接如下。

四根核心信号线分别是:
- SCLK(Serial Clock):主设备输出的同步时钟
- MOSI(Master Out Slave In):主发从收
- MISO(Master In Slave Out):主收从发
- CS / SS(Chip Select / Slave Select):片选信号,通常低电平有效
拓展来看,某些器件也支持 Daisy Chain(菊花链)。多个从机串联,时钟与片选共用,数据按链式依次传递,常见于移位寄存器、LED 驱动器等。
其特点是:
SCLK / MOSI / MISO共用- 每个从机独立使用一根
CS - 任意时刻通常只选中一个从机
二、SPI 通信原理及示例
2.1 底层原理
SPI 的核心思想是:每个设备内部都有一个移位寄存器,可以用来发送或接收一个字节的数据。这两个移位寄存器首尾相连,形成一个环,一个寄存器的输出接到另一个寄存器的输入,反过来也一样。其中一方作为主机,负责控制公共时钟信号,确保当一侧移出 1 位时,另一侧也恰好同步移入 1 位。SPI 的底层原理几乎已经简单到不能再简单了。
SPI 不是单向发射器,而是同步移位交换器。

大多数 SPI 外设默认使用 MSB First,主从双方位序必须一致,否则数据就会错位。
每来一个时钟:
- 主机向
MOSI移出 1 位 - 从机采样
MOSI上的 1 位 - 从机向
MISO移出 1 位 - 主机采样
MISO上的 1 位
重复 8 次,就完成 1 个字节交换。
SPI 的本质就是两个移位寄存器在同一时钟下同步移位。也正是这种简单性,让 SPI 具有很高的速度。异步串口通信通常工作在几十万 bit/s 量级,而 SPI 往往可以达到 10 Mbit/s 甚至更高。
2.2 SPI 的四种时钟模式
上面讲的是 SPI 如何在时钟驱动下完成一位一位的数据交换,而要想让主机和从机在正确的时刻发送、在正确的时刻采样,就必须进一步约定时钟的空闲状态以及在哪个边沿采样数据,这就是 SPI 的时钟模式。
- CPOL(Clock Polarity):时钟空闲电平
- CPHA(Clock Phase):数据在第几个边沿采样
记忆方法可以直接记:
- CPOL 管空闲高低
- CPHA 管第几个边沿采样
四种模式如下:
| 模式 | CPOL | CPHA | 空闲电平 | 采样边沿 |
|---|---|---|---|---|
| Mode 0 | 0 | 0 | 低 | 上升沿采样 |
| Mode 1 | 0 | 1 | 低 | 下降沿采样 |
| Mode 2 | 1 | 0 | 高 | 下降沿采样 |
| Mode 3 | 1 | 1 | 高 | 上升沿采样 |
之所以有这 4 种模式,本质上是为了兼容不同器件内部的数据输出与锁存时序,确保“数据变化边沿”和“数据采样边沿”能够错开,留出足够的时序裕量。
通常可以从芯片厂商手册中找到对应的时钟模式说明:

2.3 SPI 通信时序
SPI 通信的核心逻辑其实很直接:
- 主机先选择目标从机(拉低对应
CS) - 主机输出时钟
SCLK - 主机和从机按照时钟同步移位
- 主机从
MOSI发数据给从机 - 从机同时通过
MISO回数据给主机 - 一帧结束后,主机释放
CS
可简化理解为:
CS拉低 -> 时钟开始 -> 双方边移位边采样 -> 传完一帧 -> CS拉高
2.3.1 用一次 W25Q32 读 ID 看懂 SPI 通信
以 W25Q32 的 0x9F 读 JEDEC ID 为例,下面这段代码就是一次完整的 SPI 通信。
手册说明文档:C179173_5BBD793D2D7B3672E140BC7AE85C11FF.pdf (szlcsc.com)

这里使用 MicroPython + ESP32-C3,因为实验起来比较简单。本例使用的是 SPI Mode 0(CPOL=0,CPHA=0)。
from machine import Pin, SPI
import time
cs = Pin(4, Pin.OUT)
cs.value(1)
spi = SPI(1,
baudrate=200000,
polarity=0,
phase=0,
sck=Pin(2),
mosi=Pin(3),
miso=Pin(10))
def read_id():
cs.value(0)
time.sleep_us(5)
spi.write(b'\x9F')
data = spi.read(3)
time.sleep_us(5)
cs.value(1)
return data
从波形上看,几个关键引脚可以这样对应:
- CS:低电平包住整次事务
- SCLK:每传 1 位就会有 1 个时钟脉冲
- MOSI:先看到命令
0x9F,后面通常是 3 个占位字节 - MISO:命令阶段往往没有有效返回,随后输出 3 个 ID 字节
在逻辑分析仪里看波形,通常可以对应成:
CS 拉低 -> MOSI 发命令 -> 主机继续发 dummy -> MISO 回数据 -> CS 拉高

单次 SPI 通信可以拆成 6 步:
- CS 拉低:选中 W25Q32,本次通信开始
- MOSI 发送
0x9F:主机发出“读取 JEDEC ID”命令 - SCLK 输出 8 个时钟:从机在这些时钟下接收命令
- 主机继续发送 3 个 dummy byte:底层就是
spi.read(3)期间主机继续打时钟 - MISO 返回 3 个 ID 字节:例如厂商 ID、存储类型、容量信息
- CS 拉高:本次通信结束
第二步:主机发送 0x9F 命令,对应的逻辑分析仪与示波器波形如下:


- SPI 不是“请求-响应”,而是一边发,一边收
- 主机每发 1 位的同时,也会同步收到 1 位
- SPI 没有真正的“只读”操作,所谓“读”,本质上是主机发送占位数据,再把从机的数据换回来
dummy byte 就是占位字节。它本身通常没有业务含义,作用只是让主机继续产生时钟,好让从机把数据从 MISO 推出来,常见取值是 0x00 或 0xFF。
三、SPI 优点与局限
SPI 的主要优点:
- 无起始位和停止位开销:片选有效期间可连续传输数据,适合流式交换
- 协议简单:无统一地址、无仲裁、无固定 ACK 机制,总线控制直接
- 速率高:常见工作频率可达几 MHz 到几十 MHz,通常高于 I2C
- 支持全双工:
MOSI和MISO分离,可在同一时钟下同时发送和接收 - 帧宽灵活:常见为 8 位,也可支持 16 位、32 位或连续流式传输
- 硬件实现直接:从机使用主机提供的时钟,不需要像 UART 那样做独立时钟恢复
SPI 的主要局限:
- 信号线较多:标准四线 SPI 至少需要
SCLK、MOSI、MISO、CS,多从机还需要更多片选线 - 无总线级接收确认:不像 I2C 那样有统一 ACK/NACK 机制
- 无统一错误检测机制:总线层通常没有奇偶校验、CRC、重传、仲裁等标准机制
- 通常采用单主结构:工程上最常见的是单主多从
- 不适合长距离通信:更适合 PCB 板内或短距离连接
- 器件协议差异大:不同芯片的命令格式、时序要求和返回规则往往不统一
四、SPI 与 I2C / UART / CAN 对比
| 接口 | 关键特点 | 典型场景 |
|---|---|---|
| SPI | 高速、全双工、靠片选、线较多 | 板级高速外设通信 |
| I2C | 省线、地址寻址、适合多器件 | 低速传感器、EEPROM |
| UART | 异步、点对点、实现简单 | 调试串口、模块通信 |
| CAN | 高可靠、多节点、支持仲裁 | 工业控制、汽车电子 |
SPI 常用于高速外设通信,原因也很直接:它没有地址仲裁、逐字节 ACK 这类额外开销,又通常用于板内短距离连接,所以更容易做到更高频率。
- UART 常见在
115200bps到1Mbps左右 - I2C 常见在
100kHz、400kHz、1MHz - SPI 常见在
1MHz、10MHz、20MHz、40MHz
一句话概括:
- SPI:快、简单、全双工,但线多
- I2C:省线、适合多器件,但速度较低
- UART:最简单,适合点对点异步通信
- CAN:强调可靠性和多节点仲裁
五、速记版与总结
- 主机提供时钟,控制整个通信节奏
MOSI / MISO支持同时发送和接收CS用于选择目标从机CPOL / CPHA决定时钟模式- SPI 本质上是移位寄存器在时钟驱动下做同步交换
如果只记住一句话,那就是:SPI 是一种面向板级高速外设通信的同步、全双工、主从式串行接口,特点是快、直接、灵活,但线多且更依赖具体器件手册。
六、常见问题与速答
SPI 调不通时,优先检查这几类问题:
- 片选时序错误:常见现象是芯片无响应、数据错位、命令执行失败;重点看
CS是否正确拉低、整帧期间是否保持有效、拉高时机是否符合手册要求 - 模式或位序不匹配:常见现象是有波形但数据不对;重点看
CPOL / CPHA是否一致,以及主从双方是否都使用MSB First或LSB First - 读操作忘记发送 dummy:SPI 读数据时主机必须继续提供时钟,因此通常要发送空字节来换取从机返回数据
- 多从机 MISO 冲突:多个从机共用
MISO时,必须保证只有被选中的从机驱动MISO,其他从机处于高阻态 - 频率过高导致不稳定:可能出现偶发错码、固定字节异常、波形边沿不干净等问题;工程上通常先降频验证,再逐步提高频率
Q:SPI 是什么?
SPI 是一种同步、全双工、主从式串行通信协议。主机通过时钟线控制通信节奏,通过 MOSI 和 MISO 实现数据交换,通过片选线选择目标从机。它常用于 MCU 与 Flash、显示屏、ADC、传感器等高速外设之间的板级通信。
Q:SPI 为什么比 I2C 快?
因为 SPI 有独立时钟线,没有地址仲裁和逐字节 ACK 这类额外开销,通常又用于短距离板级通信,所以更容易工作在更高频率下。
Q:SPI 为什么需要片选线?
因为 SPI 通常没有地址机制。多个从机共享总线时,主机需要通过片选线明确指定本次通信的目标设备。
Q:SPI 四种模式怎么理解?
SPI 四种模式由 CPOL 和 CPHA 组合而来。CPOL 决定时钟空闲电平,CPHA 决定数据在第几个边沿采样。主从双方模式必须一致,否则容易出现采样错误。
Q:SPI 读数据时为什么还要发送数据?
因为 SPI 是时钟驱动的同步移位通信。从机不会主动输出数据,主机必须继续提供时钟,因此通常要发送 dummy byte 来换取从机返回的数据。