1. SPI协议基础

1.1 SPI总线物理层概述

SPI(Serial Peripheral Interface,串行外设接口)是由Motorola公司推出的一种高速、全双工、同步的串行通信总线。在嵌入式Linux系统中,SPI广泛应用于传感器、ADC/DAC、LCD控制器、Flash存储器、无线收发模块等外设的通信。

SPI总线在物理层采用主从架构(Master-Slave),通常包含1个主设备(Master)和1个或多个从设备(Slave)。主设备负责产生时钟信号并控制片选信号,从设备被动响应。

关键特性:
  • 全双工通信:数据发送和接收同时进行
  • 同步传输:由主设备提供的时钟信号同步
  • 高速率:典型速率可达数十MHz,远高于I²C
  • 无地址机制:通过片选信号(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 片选信号,低电平有效,用于选中目标从设备
调试提示:在驱动调试初期,使用逻辑分析仪或示波器同时抓取SCLK、MOSI、MISO、CS四根信号线,是判断SPI通信是否正常的最直接手段。常见问题包括:CS信号毛刺、SCLK极性错误、MOSI/MISO电平不匹配。

1.3 四线制时序分析

SPI总线的一次完整数据传输过程如下:

  1. 片选阶段:主设备将目标从设备的CS引脚拉低,选中该从设备。
  2. 时钟启动:主设备开始产生SCLK时钟信号。
  3. 数据移位:在每个时钟周期,主设备通过MOSI发送1位数据,同时从设备通过MISO发送1位数据,实现全双工传输。
  4. 传输结束:主设备停止SCLK时钟,并将CS引脚拉高,释放从设备。

下图展示了SPI总线在模式0(CPOL=0, CPHA=0)下的典型时序波形:

SPI四线制时序图(模式0:CPOL=0, CPHA=0) CS 从设备选中(低电平有效) SCLK MOSI D7 D6 D5 D4 D3 D2 D1 D0 MISO D7 D6 D5 D4 D3 D2 D1 D0 ↑ 数据采样点(时钟上升沿)

1.4 时钟极性(CPOL)与相位(CPHA)详解

SPI协议定义了4种工作模式,由时钟极性(CPOL)和时钟相位(CPHA)两个参数组合决定。这两个参数决定了SCLK在空闲状态的电平以及数据采样/移位的边沿。

1.4.1 参数定义

参数 取值 含义
CPOL
(时钟极性)
0 SCLK空闲时为低电平(低电平有效)
1 SCLK空闲时为高电平(高电平有效)
CPHA
(时钟相位)
0 数据在SCLK的第一个边沿(上升沿或下降沿)被采样
1 数据在SCLK的第二个边沿被采样

1.4.2 四种模式对比

模式 CPOL CPHA 空闲时钟电平 数据采样边沿 数据移位边沿 典型应用
模式0 0 0 低电平 上升沿 下降沿 大多数SPI Flash、SD卡
模式1 0 1 低电平 下降沿 上升沿 部分ADC、DAC
模式2 1 0 高电平 下降沿 上升沿 某些传感器
模式3 1 1 高电平 上升沿 下降沿 部分无线收发模块
驱动调试常见陷阱:主设备和从设备的SPI模式必须完全一致,否则会导致数据错位或通信失败。在Linux内核中,SPI设备树节点通过 spi-cpol 和 spi-cpha 属性配置模式。调试时务必核对从设备数据手册中指定的模式。

1.5 四种模式的时序对比SVG

SPI四种模式时序对比 模式0 (CPOL=0, CPHA=0) SCLK空闲低,上升沿采样 模式1 (CPOL=0, CPHA=1) SCLK空闲低,下降沿采样 模式2 (CPOL=1, CPHA=0) SCLK空闲高,下降沿采样 模式3 (CPOL=1, CPHA=1) SCLK空闲高,上升沿采样 图例说明 数据采样点 SCLK时钟信号 注意:主从设备模式必须匹配 否则会导致数据错位或通信失败

1.6 多从设备连接拓扑

SPI总线支持多从设备连接,主要有两种拓扑结构:

拓扑类型 连接方式 优点 缺点
独立片选 每个从设备独占一根CS线,SCLK/MOSI/MISO共享 各从设备独立工作,互不干扰 占用主设备GPIO资源较多
菊花链 从设备串联,数据逐级传递 节省CS线,适合大量同类型设备 延迟累积,驱动实现复杂
Linux内核中的SPI设备树配置示例:
&spi0 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_spi0>;
    cs-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>,
               <&gpio1 1 GPIO_ACTIVE_LOW>;

    flash@0 {
        compatible = "jedec,spi-nor";
        reg = <0>;           /* CS0 */
        spi-max-frequency = <50000000>;
        spi-cpol;             /* CPOL=1 */
        spi-cpha;             /* CPHA=1 */
    };

    sensor@1 {
        compatible = "vendor,spi-sensor";
        reg = <1>;           /* CS1 */
        spi-max-frequency = <10000000>;
        /* 默认模式0,不设置spi-cpol/spi-cpha */
    };
};

1.7 SPI与I²C总线对比

在嵌入式系统中,SPI和I²C是最常用的两种串行总线。下表从多个维度进行对比:

← 上一章📖 返回目录下一章 →
对比维度 SPI I²C
信号线数量 4线(SCLK/MOSI/MISO/CS) 2线(SCL/SDA)
通信方式 全双工 半双工
传输速率 典型10~80MHz,最高可达100MHz+ 标准100kHz,快速400kHz,高速3.4MHz
从设备选择 硬件片选(CS) 软件寻址(7位/10位地址)
硬件复杂度 较高(需要更多引脚) 较低(引脚少,支持多主)
数据确认 无硬件ACK 有硬件ACK/NACK
典型应用 Flash、ADC、LCD、无线模块 传感器、EEPROM、RTC