1. SPI协议基础

1.1 SPI总线简介

SPI(Serial Peripheral Interface,串行外设接口)是由Motorola公司推出的一种高速、全双工、同步的串行通信总线。它被广泛应用于嵌入式系统中连接微控制器与各种外设,如传感器、ADC/DAC、LCD显示屏、SD卡、Flash存储器等。

核心特点: 全双工通信、主从模式、同步时钟、高速传输(可达数十MHz)、硬件流控简单。

与I²C总线相比,SPI没有复杂的设备寻址机制,也不需要应答信号,因此协议开销更小,传输效率更高。但代价是需要更多的信号线(至少4根),且不支持多主设备。

1.2 四线制信号定义

标准的SPI总线使用四根信号线进行通信,下表列出了每根信号线的名称、方向和功能:

信号名称 缩写 方向(主→从) 功能描述
串行时钟 SCLK / SCK 主→从 由主设备产生,决定数据传输速率和同步时刻
主出从入 MOSI 主→从 主设备发送数据给从设备的数据线
主入从出 MISO 从→主 从设备发送数据给主设备的数据线
片选 CS / SS 主→从 主设备选择特定从设备,低电平有效
注意: 有些厂商将CS称为SS(Slave Select),将MOSI称为SDO(Serial Data Out),将MISO称为SDI(Serial Data In)。在驱动开发中,务必查阅芯片数据手册确认引脚命名。

1.3 全双工通信原理

SPI最显著的特性是全双工通信,即在同一时钟周期内,主设备和从设备可以同时发送和接收数据。其工作原理如下:

  • 主设备通过SCLK产生连续的时钟脉冲。
  • 在每个时钟周期,主设备通过MOSI线发送1位数据,同时从设备通过MISO线发送1位数据。
  • 数据在时钟的上升沿或下降沿被采样(取决于SPI模式)。
  • 一次传输通常以8位或16位为单位,高位先行(MSB-first)或低位先行(LSB-first)。

下图展示了SPI全双工通信的数据流:

SPI全双工通信数据流 主设备 (Master) 从设备 (Slave) SCLK(时钟) MOSI:主→从 MISO:从→主 同一时钟周期内,主设备通过MOSI发送数据,从设备通过MISO发送数据 两个方向的数据传输同时进行,互不干扰

1.4 主从模式与多从机拓扑

SPI总线采用主从模式,总线上只有一个主设备(通常是MCU),可以连接一个或多个从设备。主设备负责产生时钟信号并控制片选信号,从设备被动响应。

单从机连接

最简单的拓扑结构:主设备与一个从设备直接连接,四根信号线一一对应。CS线直接连接到从设备的片选引脚。

多从机连接

当需要连接多个从设备时,有两种常见的拓扑方式:

拓扑方式 连接方法 优点 缺点
独立片选 SCLK/MOSI/MISO共享,每个从设备使用独立的CS线 任意时刻只选中一个从设备,无总线冲突;各从设备可独立配置 需要占用主设备多个GPIO作为CS引脚
菊花链 从设备的数据输出连接到下一个从设备的数据输入,形成链式结构 节省CS引脚,适合大量同类型设备 延迟累加,传输效率降低;所有从设备必须支持菊花链模式
驱动开发注意: 在独立片选拓扑中,未选中的从设备必须将其MISO引脚置为高阻态(Hi-Z),否则多个从设备同时驱动MISO线会导致总线冲突,损坏硬件。大多数SPI从设备芯片内部已实现此功能,但驱动开发时仍需确认。

下图展示了独立片选的多从机拓扑结构:

SPI多从机拓扑(独立片选) 主设备 (MCU) 从设备1 (CS1) 从设备2 (CS2) 从设备3 (CS3) SCLK MOSI MISO CS1 CS2 CS3 SCLK、MOSI、MISO三线共享,每个从设备由独立的CS线控制

1.5 SPI模式(时钟极性与相位)

SPI协议定义了4种传输模式,由时钟极性(CPOL)和时钟相位(CPHA)组合决定:

模式 CPOL CPHA 时钟空闲电平 数据采样时刻
模式0 0 0 低电平 上升沿
模式1 0 1 低电平 下降沿
模式2 1 0 高电平 下降沿
模式3 1 1 高电平 上升沿
驱动开发要点: 大多数SPI外设默认使用模式0(CPOL=0, CPHA=0)。在Linux SPI驱动中,通过设置 spi_device->mode 字段的 SPI_CPOL 和 SPI_CPHA 标志位来选择模式。主设备和从设备的模式必须匹配,否则通信将失败。

1.6 本章小结

  • SPI是一种全双工、同步、高速的串行总线,使用SCLK、MOSI、MISO、CS四根信号线。
  • 全双工通信允许主从设备在同一时钟周期内同时收发数据。
  • 多从机拓扑主要有独立片选和菊花链两种方式,驱动开发中常用独立片选。
  • SPI有4种工作模式,由CPOL和CPHA决定,主从设备模式必须一致。
  • 理解SPI协议基础是后续编写Linux SPI驱动的前提,尤其是时钟时序和片选管理。