通信协议 SPI 总结
SPI(Serial Peripheral Interface,串行外设接口)是一种高速、全双工、同步的串行通信协议,由 Motorola 公司于 20 世纪 80 年代开发,广泛用于嵌入式系统中连接微控制器(MCU)与各种外围设备(如传感器、存储器、显示屏、ADC/DAC、WiFi/蓝牙模块等)。
🔧 SPI 协议特点
| 特性 | 说明 |
|---|---|
| 同步通信 | 使用时钟信号(SCLK)同步数据传输,主从设备共享同一个时钟。 |
| 全双工 | 可以同时发送和接收数据(MOSI 和 MISO 分开)。 |
| 高速 | 传输速率通常可达几十 MHz(部分可达 100 MHz 以上),远高于 I²C 和 UART。 |
| 主从架构 | 一个主设备(Master)控制多个从设备(Slave)。 |
| 无地址机制 | 通过片选信号(SS/CS)选择从设备,不依赖地址。 |
| 灵活 | 数据长度、时钟极性、时钟相位均可配置。 |
📡 SPI 信号线(4 根基本线)
| 信号线 | 全称 | 方向 | 说明 |
|---|---|---|---|
| SCLK | Serial Clock | Master → Slave | 主设备产生的时钟信号,同步数据传输。 |
| MOSI | Master Out Slave In | Master → Slave | 主设备发送数据到从设备的线路。 |
| MISO | Master In Slave Out | Slave → Master | 从设备发送数据到主设备的线路。 |
| SS / CS | Slave Select / Chip Select | Master → Slave | 片选信号,低电平有效,用于选择特定的从设备。 |
✅ 注意:每个从设备都需要独立的 SS/CS 线,因此连接多个从设备时,主设备需要多个 GPIO 引脚作为 CS。
📐 SPI 通信时序(关键概念)
SPI 的时序由两个参数控制:
1. CPOL(Clock Polarity,时钟极性)
- CPOL = 0:时钟空闲时为低电平
- CPOL = 1:时钟空闲时为高电平
2. CPHA(Clock Phase,时钟相位)
- CPHA = 0:数据在时钟的第一个边沿(上升或下降)采样
- CPHA = 1:数据在时钟的第二个边沿采样
✅ 因此,SPI 有 4 种工作模式(Mode 0 ~ Mode 3),主从设备必须配置一致才能通信。
| 模式 | CPOL | CPHA | 采样边沿 | 数据更新边沿 |
|---|---|---|---|---|
| Mode 0 | 0 | 0 | 上升沿 | 下降沿 |
| Mode 1 | 0 | 1 | 下降沿 | 上升沿 |
| Mode 2 | 1 | 0 | 下降沿 | 上升沿 |
| Mode 3 | 1 | 1 | 上升沿 | 下降沿 |
💡 常见设备(如SD卡、FLASH)常使用 Mode 0,需查阅数据手册确认。
🔄 数据传输过程(以 Mode 0 为例)
- 主设备拉低目标从设备的 SS/CS 信号,选中该设备。
- 主设备在 SCLK 上产生时钟脉冲。
- 在每个时钟周期的 上升沿,主设备从 MOSI 发送一位数据。
- 在每个时钟周期的 上升沿,主设备从 MISO 读取从设备发送的一位数据。
- 一个字节(8 位)传输完毕后,主设备拉高 SS/CS,结束通信。
✅ 同时发送和接收使得 SPI 非常高效,常用于高吞吐量场景(如 TFT 屏幕、SD 卡读写)。
✅ SPI 优点
- 传输速率高(可达 100+ Mbps)
- 无地址冲突(每个从设备独立选通)
- 硬件实现简单(多数 MCU 内置 SPI 模块)
- 全双工通信,利用率高
❌ SPI 缺点
- 引脚多(每个从设备需一根 CS,占用 GPIO)
- 不支持多主设备(通常只有一个主)
- 无应答机制(通信可靠性依赖上层协议)
- 无内置错误校验(如 CRC 需软件添加)
- 传输距离短(通常 < 1 米,易受干扰)
📌 应用场景
| 应用设备 | 说明 |
|---|---|
| Flash / EEPROM | 如 SPI Flash(W25Qxx)、AT25 系列 |
| 温度/加速度传感器 | 如 MPU6050(部分型号)、BMP280 |
| TFT/LCD 显示屏 | 触摸屏控制器、图形显示 |
| SD 卡 | SPI 模式(与 SDIO 模式区分) |
| WiFi/蓝牙模块 | ESP8266/ESP32(可选 SPI 模式) |
| ADC/DAC 芯片 | ADS1115、DAC8552 等 |
🆚 SPI vs I²C vs UART
| 比较项 | SPI | I²C | UART |
|---|---|---|---|
| 速度 | ⚡ 很高(MHz级) | 🐢 较低(通常 < 1 Mbps) | 🐢 中等(最高 ~1 Mbps) |
| 引脚数 | 4+(每个从设备需CS) | 2(SCL + SDA) | 2(TX + RX) |
| 多从设备 | ✔(需多个 CS) | ✔(地址寻址) | ❌(点对点) |
| 多主 | ❌ | ✔ | ❌ |
| 数据校验 | ❌(需软件) | ✔(ACK/NACK) | ✔(停止位、校验位) |
| 通信方式 | 全双工 | 半双工 | 半双工(异步) |
| 适用场景 | 高速设备通信 | 多设备、低速、节省引脚 | 串口调试、PC通信 |
💡 总结
SPI 是一种高性能、简单、可靠的短距离点对多设备通信协议,特别适合嵌入式系统中主控与外设之间高速数据交换。
虽然它需要更多引脚、不支持多主,但在对速度和实时性要求高的场景下(如显示驱动、存储读写、高速传感器),SPI 通常是首选方案。
在实际开发中,只需正确配置时钟模式(CPOL/CPHA)、选择正确的 CS 线,并遵循数据手册的时序要求,即可稳定通信。
如果你正在使用 STM32、Arduino、Raspberry Pi 等平台,它们都提供了内置的 SPI 硬件模块,配合官方库(如 SPI.h)可轻松实现通信。