SPI外设驱动开发与Linux内核spi子系统 - 第1节
1.1 SPI总线简介
SPI(Serial Peripheral Interface,串行外设接口)是一种由Motorola公司提出的高速、全双工、同步的串行通信总线。它广泛应用于嵌入式系统中连接微控制器与各种外设,如传感器、ADC/DAC、LCD显示器、存储器(Flash/SD卡)等。
SPI总线的主要特点包括:
- 全双工通信:数据发送和接收可同时进行。
- 主从架构:一个主设备(Master)控制多个从设备(Slave)。
- 同步传输:由主设备提供时钟信号(SCLK)驱动数据传输。
- 高速率:典型速率可达数十MHz,远高于I²C和UART。
- 无地址帧:通过片选信号(CS)直接选择从设备,协议开销小。
应用场景提示:在Linux嵌入式系统中,SPI常用于驱动LCD触摸屏、无线模块(如CC1101)、MEMS传感器(如MPU9250)、EEPROM(如W25Q64)等外设。理解SPI协议是编写SPI设备驱动的基础。
1.2 四线制信号定义
标准SPI总线使用四根信号线进行通信,各信号定义如下表所示:
| 信号名称 | 缩写 | 方向(主设备视角) | 功能描述 |
|---|---|---|---|
| 串行时钟 | SCLK | 输出 | 由主设备产生,用于同步数据传输。每个时钟周期传输1位数据。 |
| 主出从入 | MOSI | 输出 | 主设备发送数据到从设备的数据线。 |
| 主入从出 | MISO | 输入 | 从设备发送数据到主设备的数据线。 |
| 片选 | CS | 输出 | 主设备选择从设备的控制信号,低电平有效。每个从设备占用一个独立的CS引脚。 |
关键点:MOSI和MISO是两条独立的数据线,使得SPI能够实现全双工通信。CS信号用于多从设备选择,避免总线冲突。
下图展示了SPI主设备与单个从设备之间的四线制连接关系:
1.3 全双工通信原理
SPI的全双工通信意味着在同一个时钟周期内,主设备通过MOSI线发送一位数据到从设备,同时从设备通过MISO线发送一位数据到主设备。这种并行传输机制使得SPI的通信效率远高于半双工协议(如I²C)。
全双工通信的实现依赖于以下硬件特性:
- 独立的发送和接收数据线:MOSI和MISO物理上分离,互不干扰。
- 移位寄存器:主设备和从设备内部各有一个移位寄存器,在时钟边沿触发下同步移位。
- 同步时钟:SCLK由主设备控制,确保双方数据采样的时序一致。
常见误区:虽然SPI支持全双工,但并非所有SPI外设都同时使用MOSI和MISO。例如,某些只写设备(如LED驱动器)可能只连接MOSI,而只读设备(如温度传感器)可能只连接MISO。驱动开发时需要根据外设数据手册确认实际使用的数据线。
下图展示了SPI全双工通信的数据传输过程:
1.4 时钟极性与相位(CPOL/CPHA)配置
SPI协议定义了四种不同的工作模式,通过配置时钟极性(CPOL)和时钟相位(CPHA)来确定数据采样和输出的时序关系。这两个参数直接影响主设备和从设备之间的通信兼容性。
1.4.1 参数定义
| 参数 | 取值 | 含义 |
|---|---|---|
| CPOL(时钟极性) | 0 | SCLK空闲时为低电平 |
| 1 | SCLK空闲时为高电平 | |
| CPHA(时钟相位) | 0 | 数据在SCLK的第一个边沿(上升沿或下降沿)被采样 |
| 1 | 数据在SCLK的第二个边沿被采样 |
1.4.2 四种SPI模式
| 模式 | CPOL | CPHA | SCLK空闲电平 | 数据采样边沿 | 数据输出边沿 |
|---|---|---|---|---|---|
| 模式0 | 0 | 0 | 低电平 | 上升沿 | 下降沿 |
| 模式1 | 0 | 1 | 低电平 | 下降沿 | 上升沿 |
| 模式2 | 1 | 0 | 高电平 | 下降沿 | 上升沿 |
| 模式3 | 1 | 1 | 高电平 | 上升沿 | 下降沿 |
驱动开发要点:在Linux内核SPI子系统中,通过
spi_device->mode 字段设置SPI模式,例如 SPI_MODE_0、SPI_MODE_1 等。必须与外设数据手册要求的模式严格匹配,否则通信将失败。
下图展示了四种SPI模式的时序波形对比:
1.4.3 模式选择注意事项
- 数据手册优先:始终以外设数据手册中指定的CPOL和CPHA值为准。
- 模式0最常用:大多数SPI外设默认支持模式0(CPOL=0, CPHA=0),兼容性最好。
- Linux内核配置:在设备树中通过
spi-cpol和spi-cpha属性设置,或在驱动代码中通过spi->mode设置。 - 时序验证:使用逻辑分析仪或示波器抓取SCLK和MOSI/MISO波形,确认采样边沿与数据输出边沿符合预期。
调试技巧:如果SPI通信出现数据错位或乱码,首先检查CPOL和CPHA配置是否与外设要求一致。可以尝试切换四种模式,观察哪种模式能正确读取外设的ID寄存器或状态寄存器。