QSPI 协议基础:四个阶段

QSPI 全称是 Queued Serial Peripheral Interface,说白了就是比普通 SPI 多了一条数据线——一条变四条,速率噌噌往上涨。但传输过程中,它依然用着 SPI 的老骨架:每个传输事务拆成几个固定相位,咱们叫它「四阶段」。

我刚开始搞 QSPI Flash 启动时,就被这四阶段绕晕过。总以为跟 SPI 一样,扔个命令就行。结果调了好几天 Flash 读出来全是 0xFF,后来才发现空周期数配错了。嗯,今天就把这四阶段掰开揉碎了讲清楚,你跟着我走一遍,后面配置初始化就顺了。

命令阶段

命令阶段是事务的开始。主控通过 QSPI 总线发一个 8 位的指令码,告诉 Flash 你要干什么。比如读数据用 0xEB(快速读),写使能用 0x06,擦除用 0x20 或 0xD8。

注意:虽然是 QSPI,但命令阶段通常只走单线模式(1-bit 传输),四条线中的第 0 条(IO0)负责传命令字节。我见过一些初学者误以为 QSPI 全程都四线并跑,结果在命令阶段就拉了四条线——Flash 根本认不出来。

个人习惯: 调试时先用逻辑分析仪抓命令阶段,确认 Flash 收到了正确的指令码。这一步卡住,后面全白搭。

地址阶段

地址阶段紧跟在命令之后。QSPI Flash 的地址宽度常见两种:24 位(最大 16MB)或 32 位(超过 16MB 的大容量 Flash)。地址按 MSB 先传,每个时钟传输 4 个比特——因为 QSPI 四线并行,一个 clock 就能移 4 位数据。

举个例子:24 位地址需要 6 个时钟周期(24 位 ÷ 4 线 = 6 个 clock),32 位就需要 8 个时钟。有些 Flash 允许地址阶段也走单线,但 QSPI 模式下为了提速,主流都是四线地址。

避坑提醒: 我曾经在切换项目时,把一款 16MB Flash 的地址阶段配成了 32 位,结果 Flash 一直返回错误数据。查半天发现那片 Flash 只支持 24 位地址,高 8 位会被忽略。所以务必先看数据手册里 Address Width 字段。

空周期(Dummy Cycles)

空周期是四阶段里最容易出 bug 的地方。命令和地址发完后,Flash 需要一段内部时间把数据从存储阵列搬到缓存里。这段时间主控不能传有效数据,必须发几个「幽灵时钟」——也就是空周期。

空周期数一般由 Flash 的配置寄存器和工作频率决定。常见值是 2 到 10 个 cycles。比如 W25Q64 在 104MHz 下通常要 8 个 dummy cycles,低了就读不准。空周期内数据线通常保持高阻,或者由 Flash 输出一些无关数据,主控直接忽略。

我记得有一次做上电自检,读 Flash 身份信息反复失败。最后用示波器一看,发现我配的空周期比手册要求少了 2 个,Flash 内部没准备好,出来的数据全是乱的。所以,空周期数一定要跟 Flash 手册里的“Dummy Cycles for Fast Read”对上。

数据阶段

空周期结束后,Flash 开始在 QSPI 四线上并行输出数据。每个时钟输出 4 位,8 个时钟出一个字节。主控读够需要的字节数后,拉高片选信号结束本次事务。

数据阶段也有方向之分:读操作时数据从 Flash 流向主控;写操作时数据从主控流向 Flash(不过写操作通常还需要额外的命令,比如页编程)。QSPI 的四线读数据非常快,一个 8 字节 burst 只需要 16 个时钟(算上前面的阶段也就几十个 clock)。

波形分析要点

把四个阶段串起来,一个完整的 QSPI Fast Read 事务就是:命令 → 地址 → 空周期 → 数据。每个阶段都有明确的时钟数,波形图上能清晰看到片选拉低后的第几个时钟做什么事。

我个人习惯用逻辑分析仪抓取 CS、CLK、IO0~IO3 四根线。然后对着手册里的时序图,数出命令、地址、空周期的 clock 位置。一旦有偏差,基本就是配置参数错了。

Flash 命令命令码地址宽度空周期数数据线宽
Fast Read (QSPI)0xEB24-bit84-bit
Quad Output Read0x6B24-bit84-bit
Read ID0x9F无01-bit
Page Program0x0224-bit无1-bit
核心记忆法: 除了 Read ID 等特殊命令,读写 Flash 几乎都走“命令→地址→(可能的空周期)→数据”这个流水线。空周期是区分 Fast Read 和普通 Read 的关键点。
QSPI 四阶段事务流程 事务开始 命令阶段(8clk×1线) 地址阶段(6~8clk×4线) 空周期(2~10clk) 数据阶段(N×8clk×4线) 事务结束(片选拉高) 注意 命令阶段只用单线(IO0) 后续阶段才切为4线
实操建议: 画波形图时,先标出四个阶段的边界。我每次都在图纸上写:CMD @ clock 1-8,ADDR @ clock 9-14,DUMMY @ clock 15-22,DATA from clock 23。这样配置寄存器时就能直接知道每个字段该填多少。

学完这四个阶段,基本上 QSPI 协议就不怕了。后面咱们会用到这些概念去配置 Flash 的初始化序列,尤其是设置空周期和地址宽度时,一定要回头翻这节内容。你想想看,一个 Flash 命令报文就那么几个字节,但每个位都在哪个阶段、走几根线,搞清楚了,所有 Flash 驱动都能看懂。