2. SPI 协议基础与时序
2.1 为什么 QSPI 还要从 SPI 讲起?
很多人觉得 SPI 简单,四个信号线一接就能跑数据。我在项目里见过不少新手上来就调 QSPI,结果死活读写不正常,最后发现是 SPI 最基本的时钟极性和相位没搞对。你说冤不冤?
QSPI 本质上是 SPI 的扩展——多了一根数据线变成了四根,但控制逻辑、时序约束、主从关系,全都从 SPI 继承下来。所以想把 QSPI Flash 引导搞明白,先得把 SPI 的底裤看穿。
核心观点: QSPI = SPI 的并行版本。SPI 的每一个时序细节,都在 QSPI 里原封不动地保留了。
2.2 SPI 总线:四根线的故事
标准 SPI 有四个信号,你肯定背得出来:
- SCLK(Serial Clock)—— 主设备产生的时钟,决定传输速率
- MOSI(Master Out Slave In)—— 主设备发,从设备收
- MISO(Master In Slave Out)—— 主设备收,从设备发
- CS(Chip Select)—— 片选,低电平有效
嗯,注意 CS 是低有效。我见过有人把这个搞反,然后折腾了一整天。
还有个东西叫 SS(Slave Select),和 CS 是同一个意思。不同的芯片手册叫法不一样,别被绕晕。
2.3 时钟极性和相位:CPOL 和 CPHA
这才是 SPI 最容易踩坑的地方。
| 模式 | CPOL | CPHA | 时钟空闲电平 | 数据采样沿 |
|---|---|---|---|---|
| Mode 0 | 0 | 0 | 低电平 | 上升沿 |
| Mode 1 | 0 | 1 | 低电平 | 下降沿 |
| Mode 2 | 1 | 0 | 高电平 | 上升沿 |
| Mode 3 | 1 | 1 | 高电平 | 下降沿 |
QSPI Flash 绝大多数都工作在 Mode 0。我建议你拿到新芯片时,第一件事就去翻数据手册里的时序图,找到 CPOL 和 CPHA 的约定,否则连 Read ID 都读不出来。
我曾经在一个项目里把主控的 SPI 配成了 Mode 3,Flash 芯片支持 Mode 0 和 Mode 3,但那个国产 Flash 的数据手册写得不清楚。结果读出来的 JEDEC ID 一直 0xFF,折腾两周才发现是时钟极性配反了……嗯,从那以后我每次建项目第一件事就是配 SPI 模式。
2.4 SPI 传输时序:一帧数据怎么走?
简单来说,一个 SPI 传输由以下步骤组成:
- 拉低 CS —— 通知从设备:我要跟你通信了
- 发送时钟 + 数据 —— 每来一个时钟沿,主从各移出一位数据,同时锁存一位数据
- 拉高 CS —— 结束本次传输
注意 SPI 是全双工的。你可以想想看:主设备发一个字节出去的同时,从设备也在发一个字节回来。所以 SPI 的每一笔传输,其实都是同时收发的。
举个例子,你要从 Flash 读数据:
- 主设备先发命令字节(比如 0x03 读命令)
- 紧接着发地址字节(通常是三字节地址)
- 然后主设备继续发 dummy 字节(0x00),从设备在 MISO 上返回数据
实际上,主设备发 dummy 字节的同时,从设备才把数据送出来。这个过程没有“空闲”,每一拍都有数据流动。
2.5 SPI 的关键时序参数
别光看频率,别的参数也重要。我列出几个必须关注的:
| 参数 | 含义 | 典型值(SPI Flash) |
|---|---|---|
| f_SCK | 最大时钟频率 | 50 MHz~104 MHz(QSPI 更高) |
| t_SU | 数据建立时间 | 几 ns |
| t_H | 数据保持时间 | 几 ns |
| t_CSH | CS 撤销到下一帧 CS 有效的时间 | 几十 ns |
| t_CLQV | 时钟到数据输出有效时间 | 8~15 ns |
我个人习惯是在设计 PCB 时给 SPI 信号线留等长布线,尤其是高频场景(>50 MHz)。不然信号歪了,时序就崩了。
2.6 SPI 与 QSPI 的异同
说白了,QSPI 就是把标准 SPI 的单根数据线变成了两根或四根(分别是 Dual SPI 和 Quad SPI)。
看这个对比表:
| 特性 | 标准 SPI | QSPI(Quad SPI) |
|---|---|---|
| 数据线数量 | MOSI + MISO(2根) | IO0~IO3(4根,双向) |
| 每拍传输位数 | 1 bit | 4 bit |
| 全双工 | 是 | 半双工(同一时刻只能发或收) |
| 典型时钟 | ≤ 50 MHz | ≤ 104 MHz(单倍率) |
| 吞吐率(理论) | 50 Mbps | 416 Mbps(DDR 模式可更高) |
这里有个要点:QSPI 的数据线是双向的。标准 SPI 的 MOSI 和 MISO 是固定方向的,而 QSPI 的 IO0~IO3 在发送阶段是输出,在接收阶段是输入。所以主控和 Flash 之间需要做方向切换,这给软件和硬件都增加了复杂度。
2.7 时序对比:标准 SPI 读 vs QSPI 读
拿读操作来对比最直观。
标准 SPI 读(命令 0x03)
CS# \____________________________/
SCLK _¯_¯_¯_¯_¯_¯_¯_¯_¯_¯_¯_¯_¯_
MOSI [CMD][ADDR] [0x00][0x00]...
MISO xxxxxxxx [D0][D1][D2]...
QSPI 读(命令 0xEB,四线模式)
CS# \____________________________/
SCLK _¯_¯_¯_¯_¯_¯_¯_¯_¯_¯_¯_¯_¯_
IO0 [CMD][ADDR][D0][D4][D8]...
IO1 [CMD][ADDR][D1][D5][D9]...
IO2 [ADDR][D2][D6][D10]...
IO3 [ADDR][D3][D7][D11]...
// 注意:命令阶段仍只用 IO0,地址阶段用四线,数据阶段四线并行输出
看到差别了吗?QSPI 读操作中,地址和数据都用四根线并行传输,但命令阶段通常还是单线(为了兼容性好)。这样每拍能传 4 位,速度直接翻四倍。
小技巧: 调试 QSPI 时,如果数据读出来全是 0xFF,先检查 CS 是否被正确拉低;如果读出来全是 0x00,检查时钟极性;如果数据错位,检查字节序(MSB first / LSB first)。我个人的“三板斧”屡试不爽。
2.8 SPI 协议核心知识结构图
下面这张图把 SPI 协议的基础要素、时序参数、以及向 QSPI 的延伸画在了一起。你可以把它当作本章的小结。
2.9 本章小结
SPI 不是什么高深的东西,但基础不牢地动山摇。你想想看,如果连 CPOL 和 CPHA 都搞错,后面 QSPI 的 DDR 模式就更别想调通。我建议你打开开发板,用逻辑分析仪抓一次 SPI 读 Flash 的波形,对照着这章的内容看一遍,理解会深很多。
记住几个关键点:
- SPI 是全双工,但 QSPI 是半双工(方向需切换)
- 大多数 QSPI Flash 默认是 Mode 0
- 时序参数要关注建立时间、保持时间和 CS 间隔时间
- QSPI 的每根 IO 线都能在特定阶段当输入或输出