3. SPI 总线详解:四线制、全双工通信与时钟极相

SPI(Serial Peripheral Interface,串行外设接口)是嵌入式系统中使用最广泛的同步串行总线之一。在 SPI 转 UART 扩展方案中,SPI 作为主控端的高速接口,承担着向 UART 扩展芯片下发数据、读取接收缓冲区的核心任务。理解 SPI 的四线制结构、全双工机制以及时钟极性与相位配置,是正确驱动扩展芯片的前提。

3.1 四线制信号定义

标准 SPI 总线使用四条信号线完成主从设备间的同步通信。下表列出了每条信号线的名称、方向与功能:

信号线 全称 方向(主→从) 功能描述
SCK Serial Clock 主→从 由主机产生的同步时钟,决定数据传输速率
MOSI Master Out Slave In 主→从 主机输出数据线,从机在该线上接收数据
MISO Master In Slave Out 从→主 从机输出数据线,主机在该线上接收数据
CS Chip Select 主→从 片选信号,低电平有效,选中特定从机
设计要点:在 SPI 转 UART 芯片(如 WK2124、SC16IS752)中,CS 引脚通常连接主控 GPIO,用于在发送或接收数据前选中芯片。多从机共享 SCK/MOSI/MISO 总线时,必须确保同一时刻只有一个从机的 CS 被拉低。

3.2 全双工通信机制

SPI 最显著的特性是全双工:在每个时钟周期内,主机通过 MOSI 发送一位数据的同时,从机通过 MISO 返回一位数据。这意味着一次 SPI 传输在物理上总是同时完成一个字节的发送和一个字节的接收。

下图展示了 SPI 全双工传输的数据流结构:

SPI 全双工通信数据流 SPI 全双工通信数据流 SPI 主机 (MCU 主控) 发送缓冲区 → 移位寄存器 SPI 从机 (UART 扩展芯片) 移位寄存器 → 接收缓冲区 MOSI(主机→从机) MISO(从机→主机) SCK 时钟(主机驱动,同步移位) 全双工特性 每个 SCK 时钟沿同时移出 MOSI 位和移入 MISO 位,收发同步完成
实战理解:当主控向 SPI 转 UART 芯片发送一个字节的待发送数据时,芯片会同时返回一个字节——通常是当前接收 FIFO 的状态或已接收数据。因此,每次 SPI 读写操作都必须同时处理发送和接收两个方向的数据。

3.3 时钟极性与相位(CPOL & CPHA)

SPI 协议没有规定固定的时钟空闲电平与数据采样时刻,而是通过时钟极性(CPOL)和时钟相位(CPHA)两个参数来定义四种工作模式。主从设备必须使用相同的模式才能正确通信。

3.3.1 参数定义

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

3.3.2 四种模式对照

模式 CPOL CPHA 空闲电平 数据采样边沿 数据输出边沿
模式 0 0 0 低 上升沿 下降沿
模式 1 0 1 低 下降沿 上升沿
模式 2 1 0 高 下降沿 上升沿
模式 3 1 1 高 上升沿 下降沿
常见错误:多数 SPI 转 UART 芯片(如 WK2124、SC16IS752)默认工作在模式 0(CPOL=0,CPHA=0)。如果主控 SPI 配置为模式 3,会导致数据采样错位,通信完全失败。调试时务必先确认芯片数据手册中指定的 SPI 模式。

3.4 时钟极相时序图

下图以模式 0 和模式 3 为例,展示 SCK、MOSI、MISO 在传输一个字节时的时序关系:

SPI 模式 0 与模式 3 时序对比 SPI 模式 0(CPOL=0, CPHA=0)与模式 3(CPOL=1, CPHA=1)时序对比 模式 0: SCK 采样 MOSI b7 b6 b5 b4 b3 b2 b1 b0 模式 3: SCK 采样 MOSI b7 b6 b5 b4 b3 b2 b1 b0 关键区别 模式 0:SCK 空闲低,上升沿采样;模式 3:SCK 空闲高,上升沿采样 两种模式的数据采样边沿都是上升沿,但空闲电平相反,不能混用

3.5 软件配置示例

以下代码展示在 STM32 HAL 库中配置 SPI 为模式 0(CPOL=0,CPHA=0),时钟分频为 8 分频:

// SPI 句柄定义
SPI_HandleTypeDef hspi1;

// SPI 初始化函数
void MX_SPI1_Init(void)
{
    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_MASTER;          // 主机模式
    hspi1.Init.Direction = SPI_DIRECTION_2LINES; // 全双工
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT;     // 8 位数据
    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;   // CPOL = 0
    hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;       // CPHA = 0
    hspi1.Init.NSS = SPI_NSS_SOFT;               // 软件 CS 控制
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; // 8 分频
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;      // MSB 先发
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi1.Init.CRCPolynomial = 10;

    if (HAL_SPI_Init(&hspi1) != HAL_OK)
    {
        Error_Handler();
    }
}
配置检查清单:
  • 确认主控 SPI 的 CPOL/CPHA 与扩展芯片数据手册一致
  • 时钟频率不超过从机支持的最大 SCK(常见 SPI 转 UART 芯片上限为 20~40 MHz)
  • 使用软件 CS 控制时,每次传输前拉低 CS,传输完成后拉高 CS
  • 全双工模式下,每次发送后必须读取接收寄存器,避免 RX 溢出

3.6 多从机扩展架构

当系统需要扩展多路 UART 时,可以使用多个 SPI 转 UART 芯片共享同一 SPI 总线,通过独立的 CS 引脚进行片选。下图展示典型的多从机连接架构:

SPI 多从机扩展架构(共享总线,独立 CS) SPI 主机 MCU SCK / MOSI / MISO SPI 从机 1 UART 扩展芯片 CS1 SPI 从机 2 UART 扩展芯片 CS2 SPI 从机 3 UART 扩展芯片 CS3 CS1 CS2 CS3 总线共享规则 SCK / MOSI / MISO 三线并联连接 每个从机独立 CS 同一时刻仅一个 CS 有效 ← 上一章 📖 返回目录 下一章 →