Linux驱动开发SPI通信调试与常见问题汇总工程 - 第1节

1. SPI协议基础

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

核心特点:
  • 同步通信:由主设备提供时钟信号,所有通信时序与时钟同步。
  • 全双工:数据发送和接收可同时进行,互不干扰。
  • 主从架构:一个主设备(Master)可控制一个或多个从设备(Slave)。
  • 高速率:典型时钟频率从几 MHz 到几十 MHz,远高于 I²C 总线。
  • 无地址机制:通过片选信号(CS)直接选中从设备,无需软件寻址。

SPI 总线在 Linux 内核中作为 SPI 子系统 实现,提供统一的框架来管理 SPI 控制器(Controller)和 SPI 设备(Device),驱动开发者只需按照标准接口编写设备驱动即可。

SPI 总线主从架构 主设备 Master (MCU / SoC) 从设备 1 Slave #1 (传感器) 从设备 2 Slave #2 (Flash) 从设备 3 Slave #3 (ADC) SCLK MOSI MISO CS 线 数据线 (MOSI/MISO) 时钟线 (SCLK) 片选线 (CS)

1.2 四线制信号定义

标准 SPI 总线使用 4 根信号线 实现主从设备之间的通信,每一根线都有明确的角色和方向。

信号名称 全称 方向 功能描述
SCLK Serial Clock Master → Slave 由主设备产生的同步时钟信号,决定数据传输速率和采样时刻。
MOSI Master Out Slave In Master → Slave 主设备输出数据线,用于主设备向从设备发送数据。
MISO Master In Slave Out Slave → Master 从设备输出数据线,用于从设备向主设备返回数据。
CS Chip Select Master → Slave 片选信号,低电平有效(通常),主设备通过拉低 CS 选中目标从设备。
💡 关键点:MOSI 和 MISO 是两条独立的数据线,这是 SPI 能够实现全双工通信的物理基础。与 I²C 的共享数据线不同,SPI 的发送和接收路径完全分离。

1.2.1 信号时序关系

SPI 通信的时序由 时钟极性(CPOL) 和 时钟相位(CPHA) 两个参数共同决定,它们定义了数据在时钟信号的哪个边沿被采样和移位。

模式 CPOL CPHA 时钟空闲电平 数据采样边沿
模式 0 0 0 低电平 上升沿采样
模式 1 0 1 低电平 下降沿采样
模式 2 1 0 高电平 下降沿采样
模式 3 1 1 高电平 上升沿采样
⚠️ 常见问题:主设备和从设备的 SPI 模式必须匹配,否则会导致数据错位或通信失败。在 Linux 驱动中,通过 spi_device->mode 字段设置模式,例如 SPI_MODE_0。
SPI 模式 0 时序图 (CPOL=0, CPHA=0) SCLK ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ 采样 采样 采样 MOSI bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 MISO bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 CS ↓ 拉低选中 ↑ 拉高释放

1.3 全双工通信原理

SPI 的全双工特性是其区别于 I²C、UART 等半双工总线的最显著优势。全双工意味着在同一个时钟周期内,主设备可以通过 MOSI 发送数据,同时从设备可以通过 MISO 返回数据,两者互不干扰。

1.3.1 移位寄存器机制

SPI 通信的核心是 环形移位寄存器 结构。主设备和从设备内部各有一个相同位宽的移位寄存器(通常为 8 位或 16 位),通过 MOSI 和 MISO 连接成一个环形。

通信过程(以 8 位数据为例):
  1. 初始化:主设备将要发送的数据加载到其移位寄存器中,从设备也将要发送的数据加载到其移位寄存器中。
  2. 时钟驱动:主设备产生 8 个 SCLK 时钟脉冲。
  3. 逐位移位:每个时钟脉冲,主设备和从设备各自将移位寄存器中的最高位移出到数据线上,同时从数据线上移入一个比特位。
  4. 数据交换:经过 8 个时钟周期后,主设备发送的数据全部移入从设备的移位寄存器,从设备发送的数据全部移入主设备的移位寄存器。
  5. 完成:主设备从自己的移位寄存器中读取接收到的数据,即为从设备发送的数据。
SPI 全双工移位寄存器原理 主设备移位寄存器 Master Shift Register b7 b6 b5 b4 b3 b2 b1 b0 从设备移位寄存器 Slave Shift Register b7 b6 b5 b4 b3 b2 b1 b0 MOSI MISO 全双工通信过程 每个 SCLK 时钟周期:主设备通过 MOSI 发送 1 bit,同时从设备通过 MISO 返回 1 bit 8 个时钟周期后完成 1 字节的数据交换

1.3.2 全双工 vs 半双工对比

特性 SPI(全双工) I²C(半双工) UART(全双工)
数据线数量 2 条(MOSI + MISO) 1 条(SDA) 2 条(TX + RX)
同时收发 ✅ 支持 ❌ 不支持 ✅ 支持
时钟源 主设备提供 主设备提供 各自独立时钟
典型速率 10~80 MHz