2. SPI 协议基础:四线制工作原理与主从模式
SPI(Serial Peripheral Interface,串行外设接口)是一种由 Motorola 公司推出的全双工、同步、串行通信总线。在驱动小尺寸 LCD 显示屏时,SPI 因其高速、无地址开销、硬件实现简单等优势,成为最常用的接口之一。本节将深入剖析 SPI 四线制的工作原理、主从模式以及时钟极性与相位的配置方法。
2.1 SPI 四线制信号定义
标准 SPI 接口使用四条信号线完成通信,每条线的作用如下表所示:
| 信号线 | 全称 | 方向(主→从) | 功能描述 |
|---|---|---|---|
| SCLK | Serial Clock | 主 → 从 | 由主机产生的同步时钟信号,决定数据传输速率 |
| MOSI | Master Out Slave In | 主 → 从 | 主机输出数据线,从机在该线上接收数据 |
| MISO | Master In Slave Out | 从 → 主 | 从机输出数据线,主机在该线上接收数据 |
| CS | Chip Select | 主 → 从 | 片选信号,低电平有效,选中特定从机设备 |
关键提示: 对于只写不读的 LCD 显示屏(如常见的 SSD1306 OLED、ST7735 TFT),MISO 线可以省略,形成三线制 SPI。但四线制是完整定义,支持全双工通信,在需要读取显示状态或帧缓冲时必不可少。
2.2 主从模式与通信流程
SPI 总线采用 一主多从 的拓扑结构。主机(通常是 MCU)负责产生时钟信号并控制片选,从机(如 LCD 驱动 IC)被动响应。一次完整的 SPI 数据传输包含以下步骤:
- 主机拉低 CS:选中目标从机,通知其准备通信。
- 主机产生 SCLK 时钟:每个时钟周期传输 1 位数据。
- 数据移位传输:在 SCLK 的边沿(上升沿或下降沿),主机通过 MOSI 发送数据,同时从机通过 MISO 返回数据。
- 主机拉高 CS:通信结束,释放从机。
下图展示了 SPI 主从设备之间的数据流与信号连接关系:
2.3 时钟极性与相位(CPOL & CPHA)
SPI 协议通过 时钟极性(CPOL) 和 时钟相位(CPHA) 两个参数定义数据采样与输出的时序关系。这两个参数共同决定了 SPI 的四种工作模式。
- CPOL(Clock Polarity):定义 SCLK 在空闲状态(CS 无效期间)的电平。
- CPOL = 0:空闲时 SCLK 为低电平。
- CPOL = 1:空闲时 SCLK 为高电平。
- CPHA(Clock Phase):定义数据在哪个时钟边沿被采样。
- CPHA = 0:在 SCLK 的第一个边沿(上升沿或下降沿,取决于 CPOL)采样数据。
- CPHA = 1:在 SCLK 的第二个边沿采样数据。
下表列出了四种 SPI 模式的具体配置:
| 模式 | CPOL | CPHA | 空闲时钟电平 | 数据采样边沿 | 数据输出边沿 |
|---|---|---|---|---|---|
| 模式 0 | 0 | 0 | 低电平 | 上升沿 | 下降沿 |
| 模式 1 | 0 | 1 | 低电平 | 下降沿 | 上升沿 |
| 模式 2 | 1 | 0 | 高电平 | 下降沿 | 上升沿 |
| 模式 3 | 1 | 1 | 高电平 | 上升沿 | 下降沿 |
LCD 驱动实践: 绝大多数小尺寸 LCD 驱动 IC(如 ILI9341、ST7735、SSD1306)默认使用 SPI 模式 0(CPOL=0, CPHA=0) 或 模式 3(CPOL=1, CPHA=1)。这两种模式的数据采样边沿都是时钟的上升沿,区别仅在于空闲电平。初始化时务必查阅数据手册确认模式,否则可能导致显示数据错位。
2.4 SPI 时序波形图
为了更直观地理解 CPOL 和 CPHA 对数据采样的影响,下图展示了模式 0 和模式 3 的典型时序波形:
2.5 驱动 LCD 时的 SPI 配置要点
在编写 LCD 驱动时,SPI 的初始化配置直接影响显示稳定性。以下是一个基于 STM32 HAL 库的 SPI 初始化代码示例,配置为模式 0:
// SPI 初始化结构体配置(模式 0:CPOL=0, CPHA=0)
SPI_HandleTypeDef hspi1;
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_4; // 时钟分频
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();
}
}
常见错误: 许多初学者在驱动 LCD 时,只关注了 SPI 的波特率,却忽略了 CPOL 和 CPHA 的匹配。如果 LCD 数据手册要求模式 0,而 MCU 配置成了模式 2,则数据会在错误的时钟边沿被采样,导致显示内容出现“雪花”或完全无响应。务必在初始化前核对 LCD 驱动 IC 的 SPI 时序要求。
2.6 本章小结
- SPI 四线制包括 SCLK(时钟)、MOSI(主出从入)、MISO(主入从出)和 CS(片选)。
- 主从模式中,主机控制时钟和片选,从机被动响应,支持全双工通信。
- 时钟极性(CPOL)决定空闲电平,时钟相位(CPHA)决定采样边沿,两者组合形成四种 SPI 模式。
- 驱动 LCD 时,模式 0 和 模式 3 最为常用,初始化时需严格匹配数据手册。