2. SPI 总线协议基础

SPI(Serial Peripheral Interface,串行外设接口)是一种由 Motorola 公司推出的高速、全双工、同步通信总线。在车载 MCU 系统中,SPI 广泛用于连接传感器(如加速度计、陀螺仪)、ADC/DAC 转换器、外部存储器(如 Flash、EEPROM)、显示驱动芯片以及 CAN/LIN 收发器的配置接口。理解 SPI 的物理层特性、工作模式与拓扑结构,是编写正确、稳定驱动的前提。

2.1 SPI 物理层信号定义

SPI 总线使用 4 根信号线进行通信,相较于 I2C 的两线制,SPI 以更多引脚换取更高的传输速率和更简单的协议逻辑。

信号线 全称 方向(主→从) 功能描述
SCK Serial Clock 主→从 由主机产生的同步时钟信号,决定数据传输速率
MOSI Master Out Slave In 主→从 主机输出数据线,从机在该线上接收数据
MISO Master In Slave Out 从→主 从机输出数据线,主机在该线上接收数据
CS Chip Select 主→从 片选信号,低电平有效,用于选中目标从机设备
车载设计要点: 在车载环境中,SPI 信号线通常需要串联 22Ω~47Ω 的阻尼电阻以抑制过冲;CS 线建议使用 GPIO 控制而非硬件自动控制,以便在异常复位时强制释放从机。

2.2 全双工通信原理

SPI 的核心优势在于全双工(Full-Duplex)通信。在一个时钟周期内,主机通过 MOSI 发送一位数据的同时,从机通过 MISO 返回一位数据。这种机制使得 SPI 的通信效率极高,尤其适合需要同时读写寄存器的场景(如读取 ADC 转换结果时写入下一通道配置)。

全双工的数据流模型如下:

  • 主机发送移位寄存器 → 通过 MOSI 逐位移出 → 从机接收移位寄存器
  • 从机发送移位寄存器 → 通过 MISO 逐位移出 → 主机接收移位寄存器

在 MCU 驱动层面,一次 SPI 传输通常表现为:

// 伪代码:SPI 全双工单字节传输
uint8_t spi_transfer_byte(uint8_t tx_data) {
    SPIx->DR = tx_data;          // 写入发送寄存器,启动传输
    while (!(SPIx->SR & SPI_SR_RXNE)); // 等待接收非空标志
    return (uint8_t)(SPIx->DR);  // 读取接收数据
}
常见误区: 初学者常误以为 SPI 的读操作和写操作是分开的。实际上,每次 SPI 传输都是“写一个字节,同时读一个字节”。如果只需要读取从机数据,主机必须发送一个虚拟字节(通常为 0x00 或 0xFF)来产生时钟。

2.3 4 种工作模式(CPOL / CPHA)

SPI 协议通过时钟极性(CPOL,Clock Polarity)和时钟相位(CPHA,Clock Phase)的组合,定义了 4 种不同的工作模式。主从设备必须在同一模式下才能正常通信。

模式 CPOL CPHA 时钟空闲电平 数据采样边沿 数据变化边沿
模式 0 0 0 低电平 上升沿(第一个边沿) 下降沿
模式 1 0 1 低电平 下降沿(第二个边沿) 上升沿
模式 2 1 0 高电平 下降沿(第一个边沿) 上升沿
模式 3 1 1 高电平 上升沿(第二个边沿) 下降沿

CPOL 决定时钟空闲状态:

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

CPHA 决定数据采样时刻:

  • CPHA = 0:在 SCK 的第一个边沿采样数据
  • CPHA = 1:在 SCK 的第二个边沿采样数据
车载选型建议: 绝大多数车载 SPI 外设(如 MMC5883MA 磁力计、TLE5012B 角度传感器)默认使用模式 0(CPOL=0, CPHA=0)。在驱动开发时,建议优先查阅目标芯片数据手册的 SPI Timing Diagram 确认模式。
SPI 四种工作模式时序对比(CPOL / CPHA) 模式 0 (CPOL=0, CPHA=0) SCK MOSI ↑ 上升沿采样 模式 1 (CPOL=0, CPHA=1) SCK MOSI ↑ 下降沿采样 模式 2 (CPOL=1, CPHA=0) SCK MOSI ↑ 下降沿采样 模式 3 (CPOL=1, CPHA=1) SCK MOSI ↑ 上升沿采样 图例说明 ● 红色箭头表示数据采样时刻(接收端锁存数据) ● 蓝色竖线表示时钟边沿位置 ● 模式 0 和模式 3 在第一个边沿采样;模式 1 和模式 2 在第二个边沿采样 ● 空闲电平:CPOL=0 为低,CPOL=1 为高 ● 车载外设最常用模式 0(CPOL=0, CPHA=0)

2.4 主从机拓扑结构

SPI 总线采用主从式(Master-Slave)拓扑结构。系统中只有一个主机(通常是 MCU),可以连接一个或多个从机。根据从机数量与 CS 线的控制方式,SPI 拓扑分为以下两种常见形式:

2.4.1 独立片选(多从机)

  • 每个从机使用独立的 CS 引脚,由主机 GPIO 分别控制。
  • SCK、MOSI、MISO 三根线并联到所有从机。
  • 优点:从机之间完全独立,通信互不干扰。
  • 缺点:占用主机 GPIO 资源较多。

2.4.2 菊花链(Daisy-Chain)

  • 所有从机共享同一 CS 和 SCK,但 MOSI 依次串联:主机 MOSI → 从机 1 SI → 从机 1 SO → 从机 2 SI → 从机 2 SO → 主机 MISO。
  • 优点:节省主机 GPIO 引脚。
  • 缺点:传输延迟累积,数据帧长度增加,驱动逻辑复杂。
  • 车载应用:较少使用,仅在移位寄存器类设备(如 LED 驱动、GPIO 扩展)中偶见。
SPI 主从机拓扑结构 独立片选(多从机) MCU 主机 从机 1 从机 2 从机 3 CS1 CS2 CS3 SCK, MOSI, MISO 共享总线 菊花链(Daisy-Chain) MCU 主机 从机 1 从机 2 从机 3 MOSI MISO SCK / CS 共享 ● 独立片选:每个从机独立 CS,适合高速、随机访问场景,是车载 SPI 最常用拓扑 ● 菊花链:节省引脚,但延迟累积,仅适用于移位寄存器类设备

2.5 车载 SPI 驱动开发关键要点

驱动开发 Checklist:
  1. 确认从机工作模式: 查阅数据手册中的 Timing Diagram,确定 CPOL/CPHA 组合。
  2. 配置时钟频率: 从机支持的 SCK 最大频率通常低于主机,需确保分频后不超过从机上限。
  3. 数据帧格式: 确认是 MSB-first 还是 LSB-first,以及数据位宽(8位/16位/32位)。
  4. CS 控制策略: 建议使用 GPIO 软件控制 CS,确保在异常情况下能强制拉高释放从机。
  5. DMA 传输: 对于大数据块(如 Flash 页写入),使用 DMA 可大幅降低 CPU 负载。
车载环境特殊考虑: SPI 总线在车规级设计中需注意信号完整性。建议在 PCB 布局时保持 SCK 线长最短,MOSI/MISO 等长,并在靠近 MCU 引脚处放置 ESD 保护器件(如 NUP2105L)。对于长距离 SPI(超过 10cm),可考虑使用 SPI 转差分接口(如 MAX14890)以增强抗干扰能力。