VxWorks SPI驱动DMA传输与吞吐量优化 - 第1节
1.1 SPI 总线工作原理
SPI(Serial Peripheral Interface,串行外设接口)是一种全双工、同步、主从结构的串行通信协议,由 Motorola 公司于 20 世纪 80 年代提出。在嵌入式系统中,SPI 因其硬件开销低、传输速率高(可达数十 MHz)而被广泛用于传感器、ADC/DAC、存储器、显示驱动等外设。
SPI 通信的核心思想是主设备(Master)通过移位寄存器与从设备(Slave)构成一个环形移位链路。主设备主动产生时钟信号,并在每个时钟周期内同时发送和接收一个比特位,从而实现全双工传输。
关键特性:SPI 是同步协议,所有数据交换由主设备产生的时钟信号驱动;从设备不产生时钟,仅被动响应。
1.1.1 环形移位寄存器模型
下图展示了 SPI 主从设备之间通过移位寄存器实现数据交换的底层机制。主设备与从设备各自包含一个移位寄存器,通过 MOSI 和 MISO 数据线连接,构成一个 16 位的环形移位链路。
理解要点:SPI 的“全双工”特性来源于此环形结构——主设备发送数据的同时也在接收数据。即使主设备只关心从设备返回的数据,也必须发送一个字节来驱动时钟。
1.2 四线制信号与时序
标准 SPI 接口使用四条信号线,每条线承担唯一的角色。下表总结了四线制的名称、方向和功能定义。
| 信号线 | 全称 | 方向 | 功能描述 |
|---|---|---|---|
| SCLK | Serial Clock | 主→从 | 由主设备产生的同步时钟信号,决定数据传输速率 |
| MOSI | Master Out Slave In | 主→从 | 主设备输出数据线,从设备在该线上接收数据 |
| MISO | Master In Slave Out | 从→主 | 从设备输出数据线,主设备在该线上接收数据 |
| CS | Chip Select | 主→从 | 片选信号,低电平有效,选中特定从设备开始通信 |
1.2.1 基本时序流程
一次完整的 SPI 传输事务遵循以下步骤:
- 片选拉低:主设备将目标从设备的 CS 引脚从高电平拉至低电平,激活从设备。
- 时钟启动:主设备开始在 SCLK 线上产生连续的时钟脉冲。
- 数据移位:在每个时钟周期,主设备通过 MOSI 发送一个比特,同时从设备通过 MISO 返回一个比特。
- 传输完成:主设备停止时钟,并将 CS 拉回高电平,结束本次事务。
注意:CS 的拉低和释放必须在时钟稳定状态下进行。在 CS 跳变期间,SCLK 应保持空闲电平,否则可能导致从设备误判起始或结束条件。
1.3 时钟极性 (CPOL) 与相位 (CPHA) 配置
SPI 协议定义了四种工作模式,由时钟极性(CPOL)和时钟相位(CPHA)两个参数组合决定。这两个参数决定了数据采样和输出的时钟边沿,是主从设备匹配的关键。
1.3.1 CPOL 与 CPHA 定义
| 参数 | 取值 | 含义 |
|---|---|---|
| CPOL | 0 | SCLK 空闲状态为低电平(低电平有效) |
| CPOL | 1 | SCLK 空闲状态为高电平(高电平有效) |
| CPHA | 0 | 数据在 SCLK 的第一个边沿(上升沿或下降沿)被采样 |
| CPHA | 1 | 数据在 SCLK 的第二个边沿被采样 |
1.3.2 四种 SPI 模式
CPOL 和 CPHA 组合产生四种标准 SPI 模式。主设备和从设备必须工作在相同的模式下才能正确通信。
| 模式 | CPOL | CPHA | 空闲时钟电平 | 数据采样边沿 | 数据输出边沿 |
|---|---|---|---|---|---|
| 模式 0 | 0 | 0 | 低电平 | 上升沿(第一个边沿) | 下降沿 |
| 模式 1 | 0 | 1 | 低电平 | 下降沿(第二个边沿) | 上升沿 |
| 模式 2 | 1 | 0 | 高电平 | 下降沿(第一个边沿) | 上升沿 |
| 模式 3 | 1 | 1 | 高电平 | 上升沿(第二个边沿) | 下降沿 |
工程经验:大多数 SPI 外设默认使用模式 0(CPOL=0, CPHA=0)。在 VxWorks SPI 驱动开发中,应首先查阅从设备数据手册确认其支持的 SPI 模式,然后通过 SPI 控制器寄存器配置 CPOL 和 CPHA 位。
1.3.3 四种模式时序对比图
下图直观展示了四种 SPI 模式下 SCLK 波形与数据采样/输出边沿的关系。图中以发送一个字节 0xA5(二进制 1010_0101)为例,MSB 优先传输。
1.4 SPI 模式配置在 VxWorks 中的实现
在 VxWorks 中,SPI 控制器的模式配置通常通过 SPI 总线控制器的寄存器操作完成。以下是一个典型的 SPI 模式配置代码片段,展示了如何通过设置控制寄存器来配置 CPOL 和 CPHA。
/* VxWorks SPI 模式配置示例 */
#include <vxWorks.h>
#include <hwif/spi/spiLib.h>
/* SPI 控制寄存器位定义 */
#define SPI_CR_CPOL (1 << 3) /* 时钟极性位 */
#define SPI_CR_CPHA (1 << 2) /* 时钟相位位 */
/* 配置 SPI 模式 */
STATUS spiModeConfig
(
UINT32 baseAddr, /* SPI 控制器基地址 */
UINT32 mode /* SPI 模式: 0-3 */
)
{
UINT32 regVal;
UINT32 cpol, cpha;
/* 根据模式计算 CPOL 和 CPHA */
cpol = (mode >> 1) & 0x01;
cpha = mode & 0x01;
/* 读取当前控制寄存器值 */
regVal = REG_READ(baseAddr + SPI_CR_OFFSET);
/* 清除 CPOL 和 CPHA 位 */
regVal &= ~(SPI_CR_CPOL | SPI_CR_CPHA);
/* 设置新的 CPOL 和 CPHA */
regVal |= (cpol << 3) | (cpha << 2);
/* 写回控制寄存器 */
REG_WRITE(baseAddr + SPI_CR_OFFSET, regVal);
return OK;
}
配置检查:在 VxWorks 驱动开发中,配置完 SPI 模式后,建议通过回读寄存器验证配置是否生效。部分 SoC 的 SPI 控制器还要求在主设备使能之前完成模式配置,否则行为不可预测。
1.5 本章小结
本章介绍了 SPI 协议的核心基础,包括:
- 环形移位寄存器模型:解释了 SPI 全双工通信的底层硬件机制。
- 四线制信号定义:SCLK、MOSI、MISO、CS 各自的功能和时序关系。
- CPOL 与 CPHA 配置:四种 SPI 模式的区分方法、采样边沿和输出边沿的对应关系。
- VxWorks 配置示例:通过寄存器操作实现 SPI 模式选择的典型代码。