SPI接口时序分析与逻辑分析仪故障定位实战 - 第1节
1.1 SPI 总线概述
SPI,全称 Serial Peripheral Interface,串行外设接口。这玩意儿是 Motorola 公司在八十年代搞出来的,到现在快四十年了,依然活跃在各种嵌入式系统里。为什么?说白了就三个字——简单、快。
我刚开始做嵌入式那会儿,接触的第一个同步串行总线就是 SPI。当时觉得这协议也太直白了,不像 I2C 还有地址、应答那些弯弯绕。SPI 就是主设备发时钟,数据随时钟走,一收一发,干净利落。
SPI 是同步、全双工、主从结构的串行通信总线。同步意味着有独立的时钟线;全双工意味着同一时刻既能发也能收;主从结构则意味着总线上只有一个主设备控制时钟,其他都是小弟。
- 同步串行通信——有时钟线同步
- 全双工——同时收发
- 主从模式——一个 Master,多个 Slave
- 无设备地址——靠片选线选通
- 传输速率高——通常可达几十 MHz
你想想看,SPI 为什么能跑那么快?因为它没有 I2C 那种开漏输出和上拉电阻的限制,用的是推挽输出,信号边沿陡峭,速率自然就上去了。我见过 SPI 跑到 80MHz 的场景,当然那是短距离板内通信。
1.2 四线制功能详解
标准的 SPI 是四根线,名字分别是 SCLK、MOSI、MISO、CS。每一根线都有明确的职责,咱们一条一条说。
SCLK —— 串行时钟
SCLK 由主设备产生,决定了数据传输的节奏。每一个时钟脉冲,主从设备之间就交换一个比特。时钟频率直接决定了 SPI 的传输速率。我个人习惯在设计时先看从设备支持的最高时钟频率,再留 20%~30% 的余量。
MOSI —— 主出从入
MOSI 全称 Master Output Slave Input。主设备通过这根线向从设备发送数据。记住这个名字的逻辑——主设备输出,从设备输入,所以叫 MOSI。
MISO —— 主入从出
MISO 全称 Master Input Slave Output。从设备通过这根线向主设备回传数据。SPI 是全双工的,所以 MOSI 和 MISO 可以同时传输数据,互不干扰。
CS —— 片选
CS 也叫 SS(Slave Select),由主设备控制,低电平有效。当 CS 拉低时,对应的从设备被选中,开始参与通信;CS 拉高时,从设备释放总线,MISO 变为高阻态。
这里有个坑,我踩过。多个从设备共用 MOSI、MISO、SCLK 时,CS 必须严格互斥。如果两个从设备的 CS 同时被拉低,它们的 MISO 输出会打架,数据就全乱了。嗯,这个一定要注意。
| 信号线 | 全称 | 方向 | 功能 |
|---|---|---|---|
| SCLK | Serial Clock | 主→从 | 提供同步时钟 |
| MOSI | Master Out Slave In | 主→从 | 主设备发送数据 |
| MISO | Master In Slave Out | 从→主 | 从设备回传数据 |
| CS | Chip Select | 主→从 | 选通从设备 |
1.3 SPI 的 4 种工作模式
SPI 的四种模式,是很多新手容易搞混的地方。其实没那么复杂,核心就两个参数:CPOL(时钟极性)和 CPHA(时钟相位)。
CPOL —— 时钟极性
CPOL 决定了 SCLK 在空闲状态时的电平:
- CPOL = 0:空闲时 SCLK 为低电平
- CPOL = 1:空闲时 SCLK 为高电平
CPHA —— 时钟相位
CPHA 决定了数据采样发生在哪个时钟边沿:
- CPHA = 0:在第一个时钟边沿采样数据
- CPHA = 1:在第二个时钟边沿采样数据
CPOL 和 CPHA 组合起来,就是四种模式。我刚开始做 SPI 驱动时,经常搞混 Mode 0 和 Mode 3,后来总结了一个记忆方法:Mode 0 是默认模式,CPOL=0、CPHA=0,空闲低电平,第一个边沿采样。大多数 SPI 器件默认都支持 Mode 0。
| 模式 | CPOL | CPHA | 空闲时钟电平 | 数据采样边沿 |
|---|---|---|---|---|
| Mode 0 | 0 | 0 | 低电平 | 上升沿(第一个边沿) |
| Mode 1 | 0 | 1 | 低电平 | 下降沿(第二个边沿) |
| Mode 2 | 1 | 0 | 高电平 | 下降沿(第一个边沿) |
| Mode 3 | 1 | 1 | 高电平 | 上升沿(第二个边沿) |
1.4 SPI 时序与模式图解
光说理论不够直观,咱们画个图看看。下面这张 SVG 展示了 Mode 0 和 Mode 3 的时序差异,这是实际调试中最容易搞混的两个模式。
从图上可以看得很清楚:Mode 0 和 Mode 3 的时钟极性相反,但采样边沿都是第二个边沿。Mode 0 在上升沿采样,Mode 3 在下降沿采样。如果你把主设备配成 Mode 0,从设备配成 Mode 3,那采样点就完全错位了,数据肯定不对。
1.5 SPI 通信流程
一次完整的 SPI 通信,流程其实很简单:
- 主设备拉低 CS,选通目标从设备
- 主设备产生 SCLK 时钟,同时通过 MOSI 发送数据
- 从设备在 SCLK 驱动下,从 MOSI 接收数据,同时通过 MISO 回传数据
- 数据传输完成后,主设备拉高 CS,释放从设备
这里有个细节很多人会忽略:SPI 是全双工的,所以每次传输,主设备发出去一个字节的同时,也会收到一个字节。如果你只想读从设备的数据,主设备必须发送一个 dummy byte(通常是 0x00 或 0xFF)来产生时钟。我见过有人忘了发 dummy byte,结果 MISO 上一直没数据,折腾了半天才发现。