1. SPI 总线概述
1.1 SPI 协议简介
SPI(Serial Peripheral Interface,串行外设接口) 是由 Motorola 公司推出的一种高速、全双工、同步的串行通信总线。它广泛应用于嵌入式系统中连接微控制器与各种外设,如传感器、ADC/DAC、LCD 显示屏、SD 卡、Flash 存储器等。
SPI 总线的主要特点包括:
- 主从架构:通信由主设备(Master)发起并控制时钟,从设备(Slave)响应。
- 全双工通信:数据发送和接收可同时进行,互不干扰。
- 同步传输:由主设备提供的串行时钟(SCLK)同步数据位流。
- 高速率:典型时钟频率可达数十 MHz,远高于 I²C 总线。
- 无应答机制:相比 I²C,SPI 没有内置的应答信号,协议开销更低。
提示: SPI 总线没有像 I²C 那样的设备地址寻址机制,而是通过独立的片选信号(CS)来选择从设备。这意味着每增加一个从设备,主设备就需要多占用一个 GPIO 引脚作为片选。
1.2 四线制工作原理
标准 SPI 总线使用四根信号线进行通信,下表总结了每根信号线的名称与功能:
| 信号线 | 全称 | 方向(主→从) | 功能描述 |
|---|---|---|---|
| SCLK | Serial Clock | 主 → 从 | 由主设备产生的串行时钟信号,同步数据传输的每一位。 |
| MOSI | Master Out Slave In | 主 → 从 | 主设备输出数据,从设备接收数据。 |
| MISO | Master In Slave Out | 从 → 主 | 从设备输出数据,主设备接收数据。 |
| CS | Chip Select | 主 → 从 | 片选信号,低电平有效,用于选中特定的从设备。 |
四线制的工作流程如下:
- 片选阶段:主设备将目标从设备的 CS 引脚拉低,激活该从设备。
- 时钟产生:主设备在 SCLK 线上产生连续的时钟脉冲。
- 数据移位:在每个时钟周期,主设备通过 MOSI 线发送 1 位数据,同时通过 MISO 线接收 1 位数据。
- 传输结束:主设备将 CS 引脚拉高,释放从设备,完成一次数据帧传输。
关键点: SPI 的时钟极性(CPOL)和时钟相位(CPHA)决定了数据采样和输出的具体时序。CPOL 定义时钟空闲时的电平(0 或 1),CPHA 定义数据在时钟的上升沿还是下降沿被采样。两者组合形成四种 SPI 模式(Mode 0~3),驱动开发时必须确保主从设备配置一致。
1.3 全双工通信模式
SPI 最显著的优势之一是其 全双工(Full-Duplex) 通信能力。在同一个时钟周期内,主设备通过 MOSI 发送数据,同时从设备通过 MISO 返回数据,两者互不干扰。
全双工通信的底层原理基于 移位寄存器 结构:
- 主设备和从设备内部各有一个 8 位(或更多位)的移位寄存器。
- 两者通过 MOSI 和 MISO 线连接成一个 环形移位回路。
- 每来一个时钟脉冲,主从双方的寄存器同时左移一位:主设备移出一位到 MOSI,同时从设备移出一位到 MISO。
- 经过 8 个时钟周期后,主设备的 8 位数据完全移入从设备,同时从设备的 8 位数据完全移入主设备。
下图展示了 SPI 全双工通信的环形移位寄存器结构:
全双工模式在实际驱动开发中带来的影响:
- 发送与接收必须成对出现:每次调用 SPI 传输函数时,即使只关心发送数据,也必须提供一个接收缓冲区来接收从设备返回的数据。
- 虚拟数据:当主设备只希望接收从设备的数据时,必须在 MOSI 线上发送虚拟字节(通常为 0x00 或 0xFF)来产生时钟脉冲。
- 性能优势:相比 I²C 的半双工模式,SPI 的全双工特性使吞吐量翻倍,特别适合高速数据采集和实时控制场景。
常见误区: 初学者常误以为 SPI 可以像 UART 那样只发送不接收。实际上,由于 SPI 的时钟由主设备产生,从设备无法主动发起传输。即使主设备只发送数据,MISO 线上仍然会有从设备返回的数据,驱动必须处理这些数据,否则可能导致接收缓冲区溢出。
1.4 SPI 总线拓扑结构
SPI 总线支持两种常见的拓扑连接方式:
| 拓扑类型 | 连接方式 | 优点 | 缺点 |
|---|---|---|---|
| 独立片选 | 每个从设备独占一根 CS 线,SCLK/MOSI/MISO 共享 | 从设备完全独立,支持任意数量 | 占用主设备 GPIO 引脚较多 |
| 菊花链 | 从设备的 MISO 连接到下一个从设备的 MOSI,共享 CS | 节省 GPIO 引脚 | 延迟累积,传输效率降低,驱动复杂 |
在嵌入式 Linux 驱动开发中,独立片选 是最常用的拓扑方式,每个从设备在设备树中作为一个独立的 SPI 子节点注册,驱动框架天然支持这种结构。