Skip to content

SPI ​

1. SPI 的核心特点:高速、全双工 ​

SPI 最大的特点就两个字:快。

  • I2C:通常 400kHz(最快几 MHz)。
  • SPI:轻松达到 10MHz - 50MHz 甚至更高(比如用来驱动 TFT 屏幕、读写 SD 卡、Flash 芯片)。

它之所以快,是因为它不搞那些“握手、应答、寻址”的复杂动作,直接由**主机(Master)**强行驱动时钟,推着数据走。


2. 四根线的作用 ​

标准 SPI 通常需要 4 根线(I2C 只要 2 根):

  1. SCK (Serial Clock):时钟线。
    • 由主机产生。主机敲一下鼓,大家就传一位数据。
  2. MOSI (Master Output Slave Input):
    • 主机发,从机收的数据线。
  3. MISO (Master Input Slave Out):
    • 从机发,主机收的数据线。
  4. CS / SS (Chip Select / Slave Select):片选线。
    • 这是 SPI 的灵魂。 I2C 靠地址选人,SPI 靠这根线选人。
    • 平时是高电平。主机把谁的 CS 拉低,谁就开始干活。其他没被拉低的设备就装聋作哑(高阻态)。

3. 最核心的机制:交换(Shift Register) ​

这是理解 SPI 最最关键的一点,请务必记住:

SPI 的本质不是“发送”和“接收”,而是“交换”。

想象一下,主机和从机内部各有一个 8 位的 圆盘(移位寄存器),这两个圆盘通过 MOSI 和 MISO 连成了一个 闭环传送带。

当主机产生 8 个时钟脉冲时,发生的是**“乾坤大挪移”**:

  • 主机的最高位(Bit 7)被推出去,顺着 MOSI 跑到了从机的最低位。
  • 同时,从机的最高位(Bit 7)被推出去,顺着 MISO 跑到了主机的最低位。

后果:

当 8 个时钟结束后,主机里的数据跑到了从机里,从机里的数据跑到了主机里。它们互换了手中的牌。

代码启示:

这就是为什么在 STM32 的 HAL 库或者底层代码中,SPI 的读写通常合并成一个函数:

received_data = SPI_Transfer(send_data);

你想读数据? 你必须先扔出去一个垃圾数据(Dummy Byte,通常是 0xFF 或 0x00),把对方的数据“挤”进来。


4. 只有 SPI 有的麻烦事:4 种模式 (CPOL & CPHA) ​

I2C 和 UART 的时序基本是固定的,但 SPI 比较随性。它有两个配置项,组合起来就有 4 种模式。如果你连不上设备,90% 是模式选错了。

A. CPOL (Clock Polarity) - 时钟极性 ​

  • CPOL = 0:空闲时 SCK 是 低电平。
  • CPOL = 1:空闲时 SCK 是 高电平。

B. CPHA (Clock Phase) - 时钟相位 ​

  • CPHA = 0:在 第 1 个 跳变沿(上升或下降)采样数据。
    • 比喻:鼓槌举起来还没敲下去的时候,就要拍照。
  • CPHA = 1:在 第 2 个 跳变沿采样数据。
    • 比喻:鼓槌敲下去的一瞬间拍照。

怎么选?

不用背!直接看从机(传感器/屏幕)的数据手册(Datasheet)里的时序图。

  • 如果图上 CS/SS 拉低时 SCK 是低的,那就是 CPOL=0。
  • 如果数据是在 SCK 的边缘中间变化的,那就是 CPHA=1;如果数据在 SCK 变化前就准备好了,那就是 CPHA=0。
  • (最常用的通常是 模式0 或 模式3)

5. 三大协议终极对比 ​

特性UART (串口)I2CSPI
线数2 (TX, RX)2 (SCL, SDA)4 (SCK, MOSI, MISO, CS)
速度慢 (115200 bps)中 (400 kHz)极快(几十 MHz)
通信方式异步 (靠波特率)同步 (半双工)同步 (全双工)
多设备点对点 (通常)靠地址区分靠CS引脚区分
流控无 (容易丢包)有 (ACK应答)无 (发了就不管,不论死活)
应用场景打印调试、GPS传感器、EEPROM屏幕(LCD)、SD卡、Flash

6. 总结 ​

SPI 就是一个**“暴力传输”**协议:

  1. 拉低 CS:指定你要和谁说话。
  2. 开始时钟:主机疯狂打拍子。
  3. 数据交换:主机的数据冲向从机,从机的数据冲向主机(不想发也要发个 0x00 或 0xFF 去把数据换回来)。
  4. 拉高 CS:结束。