1. 项目概述
在嵌入式系统开发中,与外部存储设备(如SPI Flash)或高速外设进行高效通信是核心需求之一。传统的SPI接口虽然简单可靠,但其单线数据输入输出的模式在追求更高带宽的应用中逐渐显得力不从心。这时,QSPI(Quad SPI)接口就成为了一个关键的技术升级。它不仅仅是SPI的简单扩展,更是一种通过增加数据线数量来成倍提升传输效率的硬件设计思想。对于需要快速启动、执行就地执行(XIP)或频繁读写大块数据的嵌入式设备来说,深入理解并掌握QSPI的底层工作机制,尤其是其寄存器配置、中断驱动和内存映射访问模式,是进行高性能、高可靠性驱动开发的基石。
本文将以德州仪器(TI)某款处理器中的QSPI控制器模块为具体案例,抛开抽象的理论,直接切入工程师最关心的实战层面。我们将一起拆解其数据手册中的关键寄存器,还原一个完整的QSPI驱动初始化、数据传输和中断处理的配置流程。你会看到,从时钟分频、SPI模式设置,到如何巧妙地利用字完成中断实现流式数据传输,再到如何配置内存映射端口将外部Flash“映射”成一块可直接寻址的内存区域,每一个步骤背后都有其硬件逻辑和设计考量。无论你是正在调试一块新的核心板,还是希望优化现有Flash的访问性能,这篇基于寄存器手册的深度解析都将为你提供清晰的路径和可落地的代码参考。
2. QSPI核心架构与双端口模式解析
在深入寄存器之前,我们必须先理解TI QSPI模块一个非常关键的设计:双端口架构。这直接决定了我们有两种截然不同的方式来操作它,适用于不同的场景。
2.1 配置端口与内存映射端口
根据手册,QSPI关联了两个独立的内存区域,这对应了两种访问模式:
配置端口(Configuration Port):
- 地址:
0x4790 0000(L3_Slow 起始地址)。 - 功能:这是对QSPI控制器进行“编程”的接口。通过这个端口,我们可以访问所有的QSPI内部寄存器,包括
QSPI_CMD_REG、QSPI_DATA_REG等。同时,这里也提供了四个数据寄存器(QSPI_DATA_REG到QSPI_DATA_REG_3),用于与外部SPI设备进行数据交换。 - 使用场景:当你需要与一个通用的SPI设备(如传感器、ADC芯片)通信时,必须使用配置端口。你需要像操作传统SPI一样,手动配置命令、写入数据、读取状态,完成每一次传输的调度。
- 地址:
内存映射端口(Memory-Mapped Port):
- 地址:
0x3000 0000到0x33FF FFFF(L3_Slow 地址空间)。 - 功能:这是一个更高级的“直通”接口。当控制器配置为内存映射模式时,CPU对这片地址区域的读写访问,会被QSPI模块的“内存映射协议转换器”自动转换为对外部SPI Flash设备的读写操作序列。
- 使用场景:这是为SPI Flash量身定做的模式。配置好后,你可以像读写片上RAM一样,直接用指针(如
*(volatile uint32_t*)0x30000000)访问Flash中的数据,极大简化了代码,并使得XIP成为可能。
- 地址:
手册中一句非常关键的话点明了二者的关系:“to read from an external SPI flash memory, first configure the QSPI through the configuration port and then perform a read through the memory-mapped port.” 这揭示了标准工作流:先用配置端口完成硬件初始化,然后切换到内存映射端口进行高效的数据访问。
2.2 中断机制概览
QSPI模块提供了两个核心的中断事件源,用于在数据传输过程中通知CPU:
- 字完成中断(Word Complete Interrupt, WIRQ):在每个“字”(Word)传输完成后触发。这里的“字”长度由
QSPI_CMD_REG中的WLEN字段定义,可以是1到128位。这个中断适用于需要精细控制每个数据块的场景,例如流式传输或与不支持DMA的系统配合。 - 帧完成中断(Frame Complete Interrupt, FIRQ):在一整“帧”(Frame)数据传输完成后触发。一帧包含的“字”数由
QSPI_CMD_REG中的FLEN字段定义(1到4096个字)。这个中断适用于批量数据传输,当传输大量连续数据时,可以减少中断频率,提高效率。
中断的使能逻辑是“与”关系。以字完成中断为例,要使其有效,必须同时满足两个条件:在QSPI_INTR_EN_SET_REG[1]位使能全局中断,并且在QSPI_CMD_REG[14]位(配置端口模式)或QSPI_SWITCH_REG[1]位(内存映射模式)使能特定模式下的中断。
2.3 寄存器地图总览
在地址0x4790 0000开始的配置端口空间,分布着控制QSPI所有行为的寄存器。下表是它们的快速索引:
| 偏移地址 | 寄存器缩写 | 全称 | 核心功能简述 |
|---|---|---|---|
| 0x40 | QSPI_CLOCK_CNTRL_REG | 时钟控制寄存器 | 使能时钟并设置分频系数,决定SCK频率。 |
| 0x44 | QSPI_DC_REG | 设备控制寄存器 | 为每个片选(CS0-CS3)独立配置SPI模式(极性、相位)、数据延迟。 |
| 0x48 | QSPI_CMD_REG | 命令寄存器 | 核心:发起传输、选择片选、设置字长/帧长、选择命令模式(单线/双线/四线读写)、使能中断。 |
| 0x4C | QSPI_STS_REG | 状态寄存器 | 查询传输状态:忙(BUSY)、字完成(WC)、帧完成(FC)、当前字计数(WDCNT)。 |
| 0x50 | QSPI_DATA_REG | 数据寄存器0 | 用于读写传输数据的32位寄存器(128位移位寄存器的第一部分)。 |
| 0x54-0x60 | QSPI_SETUP_REG_0-3 | 内存映射设置寄存器 | 为内存映射模式下的每个片选区域,配置读/写命令码、地址字节数、 dummy cycles等。 |
| 0x64 | QSPI_SWITCH_REG | 切换寄存器 | 控制权切换(配置端口 vs. 内存映射转换器)和内存映射模式中断使能。 |
| 0x20-0x2C | QSPI_INTR_* | 中断状态与控制寄存器组 | 管理中断的原始状态、使能状态、清除中断标志。 |
3. 关键寄存器配置详解与实战指南
理解了架构,我们就可以动手配置了。配置的核心目标是让QSPI控制器以我们期望的时序和模式与外部设备“对话”。
3.1 时钟配置:QSPI_CLOCK_CNTRL_REG
通信速率的基础。SCK时钟由输入时钟SPI_CLK分频得到。
- DCLK_DIV (位[15:0]):分频系数。输出时钟频率 = 输入时钟频率 / (DCLK_DIV + 1)。例如,输入时钟为100MHz,希望SCK为25MHz,则
DCLK_DIV = (100 / 25) - 1 = 3。 - CLKEN (位[31]):时钟使能位。必须置1,SPI时钟才会产生。手册特别强调,只有在SPI不忙(
QSPI_STS_REG[0] BUSY == 0)时才能写此寄存器。一个安全的做法是,在初始化流程的最后一步才置位CLKEN。
实操心得:在调试初期,建议将分频系数设大一些(降低SCK频率),用逻辑分析仪抓取波形,确认时序正确后,再逐步提高频率。这能有效排除因时钟过快导致的时序不稳定问题。
3.2 设备控制:QSPI_DC_REG
这个寄存器为每个片选信号(CS0-CS3)提供了独立的时序配置,非常灵活。每个片选占用8个位,控制4个参数:
- CKPx (时钟极性):决定SCK线在空闲时的电平。
0:空闲时SCK为低电平。1:空闲时SCK为高电平。
- CKPHx (时钟相位):决定数据在SCK的哪个边沿采样。
0:在第一个时钟边沿采样数据(具体是上升沿还是下降沿,结合CKP决定)。1:在第二个时钟边沿采样数据。
- CSPx (片选极性):决定片选信号的有效电平。
0:低电平有效(常见)。1:高电平有效。
- DDx (数据延迟):在片选有效后,延迟多少个DCLK周期才开始输出数据。用于满足某些外设的
t_CS2DO(片选到数据输出有效)时序要求。
CKP和CKPH的组合构成了经典的SPI模式:
- 模式0: CKP=0, CKPH=0
- 模式1: CKP=0, CKPH=1
- 模式2: CKP=1, CKPH=0
- 模式3: CKP=1, CKPH=1
绝大多数SPI Flash支持模式0和模式3。你需要查阅你的Flash数据手册来确定。
注意事项:手册明确指出,此寄存器也必须在SPI不忙(
BUSY==0)时才能写入。在初始化阶段,确保在发起任何传输前完成此寄存器的配置。
3.3 命令与状态核心:QSPI_CMD_REG与QSPI_STS_REG
这是发起和控制每一次传输的核心寄存器对。
QSPI_CMD_REG– 下达指令
- CSNUM (位[29:28]):选择本次传输使用哪个片选(0-3)。这让你可以挂接多个SPI设备。
- WLEN (位[25:19]):设置字长。值 = 位数 - 1。例如,要传输8位数据,则设置
WLEN = 7;传输32位数据,则设置WLEN = 31。手册提到最大支持128位(WLEN=0x7F)。 - CMD (位[18:16]):传输命令,决定数据线用法。这是QSPI精髓所在。
1(0x1): 4线单路读(标准SPI, DIN输入)2(0x2): 4线单路写(标准SPI, DOUT输出)3(0x3): 4线双路读(QSPI, DIN和DOUT同时作为输入)5(0x5): 3线单路读(半双工,单根数据线)6(0x6): 3线单路写(半双工,单根数据线)7(0x7): 6线四路读(Quad SPI,使用全部4根数据线输入)
- WIRQ/FIRQ (位[14:15]):分别使能字完成和帧完成中断。仅当此位置1,且对应的全局中断使能位也置1时,中断才会产生。
- FLEN (位[11:0]):帧长度。值 = 字数 - 1。例如,要连续传输100个字,则设置
FLEN = 99。
QSPI_STS_REG– 查询状态
- BUSY (位[0]):只读。为1表示控制器正在传输数据。在写入
CMD、DATA等寄存器前,必须检查此位为0。 - WC (位[1]):字完成标志。每个字传输完成后置1,读取本寄存器后自动清零。可用于轮询。
- FC (位[2]):帧完成标志。所有字传输完成后置1,读取本寄存器后自动清零。
- WDCNT (位[27:16]):当前传输的字计数器,可用于监控长帧传输的进度。
工作流程示例(轮询方式写数据):
- 等待
BUSY == 0。 - 将数据写入
QSPI_DATA_REG。 - 配置
QSPI_CMD_REG(选择片选、字长、写命令、帧长)。 - 写入
CMD字段的瞬间,控制器启动传输,BUSY置1。 - 循环查询
WC或BUSY,直到一个字传输完成。 - 重复步骤1-5,直到所有字发送完毕,或查询
FC标志。
3.4 内存映射模式专用配置
为了高效访问SPI Flash,需要配置内存映射相关的寄存器。
QSPI_SETUP_REG_0-3– Flash访问协议配置每个寄存器对应一个片选区域(CS0-CS3)。当CPU访问内存映射端口(0x3000_0000开始)的某个地址空间时,转换器会根据MAddrSpace(内存地址空间)选择对应的SETUP_REG来生成Flash命令。
- RCMD/WCMD (位[7:0]/[23:16]):读/写命令码。例如,多数Flash的“普通读”命令是0x03,“快速读”是0x0B,“页编程”写命令是0x02。必须严格按照Flash数据手册填写。
- NUM_A_BYTES (位[9:8]):发送的地址字节数。24位地址(16MB)的Flash填2(表示3字节),32位地址的Flash填3。
- NUM_D_BYTES (位[11:10]):“哑元字节”(Dummy Bytes)数量。在“快速读”等命令中,发送地址后需要等待几个时钟周期,Flash才能准备好数据,这几个周期就是Dummy Cycles,通常由几个空字节构成。
- READ_TYPE (位[13:12]):内存映射模式下的读类型。
0-单线读,1-双线读,3-四线读。这需要Flash本身支持相应的Quad/Dual Read命令。
QSPI_SWITCH_REG– 模式切换
- MMPT_S (位[0]):模式切换开关。
0-CPU通过配置端口控制QSPI核心;1-CPU通过内存映射端口访问,控制权交给内存映射协议转换器。要从配置模式切换到内存映射模式,必须将此位置1。 - MM_INT_EN (位[1]):在内存映射模式下,是否使能字完成中断。
4. 中断机制深度剖析与驱动实现
使用中断可以解放CPU,避免在数据传输期间忙等待。QSPI的中断逻辑稍显复杂但非常典型,理解了它,就能写出高效的异步驱动。
4.1 中断使能的双重条件
中断产生的路径是:事件发生 -> 原始状态位置位 -> 若事件已使能,则触发中断线。 对应的寄存器有三组:
- 原始状态寄存器:
QSPI_INTR_STS_RAW_SET。只要事件发生(字/帧完成),对应位(WIRQ_RAW/FIRQ_RAW)就会置1,无论中断是否使能。你可以通过读取它来了解发生了什么。 - 使能设置/清除寄存器:
QSPI_INTR_EN_SET_REG和QSPI_INTR_EN_CLR_REG。这是全局中断使能。向SET寄存器的对应位写1使能中断,向CLR寄存器写1则禁用。 - 事件使能位:位于
QSPI_CMD_REG(配置端口模式)或QSPI_SWITCH_REG(内存映射模式)。这是针对当前操作模式的中断使能。
因此,一个完整的中断使能配置如下:
- 配置端口模式下发中断:
- 全局使能字中断:
QSPI_INTR_EN_SET_REG[1] = 1。 - 在发起传输的命令中使能字中断:
QSPI_CMD_REG[14] = 1。
- 全局使能字中断:
- 内存映射模式下发中断:
- 全局使能字中断:
QSPI_INTR_EN_SET_REG[1] = 1。 - 切换到内存映射模式并使能其中断:
QSPI_SWITCH_REG = (1 << 1) | (1 << 0)。(位1=MM_INT_EN, 位0=MMPT_S)
- 全局使能字中断:
4.2 中断服务程序(ISR)处理流程
当中断触发后,ISR需要正确处理以清除中断标志,防止重复进入。
- 判断中断源:读取
QSPI_INTR_STS_EN_CLR寄存器。该寄存器显示的是已使能且已发生的中断状态。通过判断WIRQ_ENA或FIRQ_ENA位,可以确定是哪个事件触发了中断。 - 处理事务:如果是
WIRQ,意味着一个“字”传输完成,你可以准备下一个字的数据(对于发送)或读取当前字的数据(对于接收)。如果是FIRQ,意味着一帧传输全部结束,可以进行后续处理(如通知任务、开始下一帧)。 - 清除中断标志:向
QSPI_INTR_STS_EN_CLR寄存器的对应位写1。例如,清除字中断:QSPI_INTR_STS_EN_CLR = (1 << 1)。这一步至关重要,目的是告知中断控制器该中断已被处理,否则会一直触发。 - (可选)发送EOI:有些中断控制器需要发送中断结束命令。向
QSPI_INTC_EOI_REG写入0即可。
避坑指南:务必区分
QSPI_INTR_STS_RAW_SET和QSPI_INTR_STS_EN_CLR。前者是原始状态,后者是使能后的状态。清除中断标志必须操作后者(EN_CLR)。操作前者(RAW_SET)的对应位是“设置”该状态,会导致中断持续触发,造成系统死锁。这是一个常见的驱动Bug来源。
4.3 实战:基于中断的块数据发送示例
假设我们需要通过CS0,以SPI模式0,8位字长,向一个设备发送一段数据缓冲区tx_buffer中的内容。
// 伪代码,展���流程 void QSPI_SendBuffer_IRQ(uint8_t *tx_buffer, uint32_t length) { // 1. 确保QSPI空闲 while(QSPI_STS_REG & 0x01); // 等待BUSY==0 // 2. 配置全局中断使能 (假设已配置好系统中断向量) QSPI_INTR_EN_SET_REG = (1 << 1); // 使能WIRQ全局中断 // 3. 配置设备参数 (时钟、模式等,假设已提前初始化) // QSPI_DC_REG 已配置为模式0,CS0低有效等... // 4. 设置传输参数并启动第一次传输 current_tx_ptr = tx_buffer; tx_remaining = length; // 写入第一个数据字 QSPI_DATA_REG = *current_tx_ptr++; tx_remaining--; // 配置命令寄存器:CS0, 字长=8bit(7), 写命令(2), 使能字中断,帧长=1(单字传输) uint32_t cmd = (0 << 28) | // CSNUM = 0 (7 << 19) | // WLEN = 7 (8 bits) (2 << 16) | // CMD = 2 (Write Single) (1 << 14) | // WIRQ = 1 (Enable word interrupt) (0 << 0); // FLEN = 0 (1 word per frame) QSPI_CMD_REG = cmd; // 写入命令,传输立即开始,BUSY置1 } // QSPI中断服务程序 void QSPI_IRQ_Handler(void) { // 1. 读取使能状态寄存器,判断中断源 uint32_t status = QSPI_INTR_STS_EN_CLR; if (status & (1 << 1)) { // 字完成中断 // 2. 处理事务:如果还有数据要发送,准备下一个字 if (tx_remaining > 0) { // 等待当前传输结束(BUSY变低),准备下一个字 while(QSPI_STS_REG & 0x01); // 简单轮询BUSY,实际可优化 QSPI_DATA_REG = *current_tx_ptr++; tx_remaining--; // 重新写入CMD寄存器以启动下一次传输(FLEN=0,每次发一个字) // 注意:需要重新配置CMD寄存器,因为每次传输后需要重新触发 uint32_t cmd = (0 << 28) | (7 << 19) | (2 << 16) | (1 << 14) | (0 << 0); QSPI_CMD_REG = cmd; } else { // 所有数据发送完毕 transfer_complete = true; // 可以禁用中断 QSPI_INTR_EN_CLR_REG = (1 << 1); } // 3. 清除中断标志 (向对应位写1) QSPI_INTR_STS_EN_CLR = (1 << 1); } // 4. 发送EOI (如果需要) QSPI_INTC_EOI_REG = 0; }5. 内存映射模式实战:将SPI Flash变为线性内存
这是QSPI最强大的功能之一。配置成功后,你可以像访问RAM一样读取Flash,代码可以直接在Flash中运行(XIP)。
5.1 初始化与切换流程
通过配置端口进行基础初始化:
- 配置
QSPI_CLOCK_CNTRL_REG设置SCK时钟。 - 配置
QSPI_DC_REG为Flash设置正确的SPI模式(通常模式0或3)。 - 关键:配置对应的
QSPI_SETUP_REG_x。例如,如果你的Flash连接在CS0,且映射到地址空间0x3000 0000,则配置QSPI_SETUP_REG_0。RCMD:填入Flash的“快速读”命令码(如0x0B)。NUM_A_BYTES:根据Flash容量选择(24位地址填2,即3字节)。NUM_D_BYTES:根据Flash数据手册的“快速读”时序要求填写(常见为1或2)。READ_TYPE:如果你希望使用Quad模式读取,且Flash支持,则填3。WCMD:填入“页编程”命令码(如0x02)。NUM_D_BITS:如果NUM_D_BYTES为0,但需要几个dummy bits,在此设置。
- 配置
切换到内存映射模式:
- 向
QSPI_SWITCH_REG寄存器写入0x00000003。即MMPT_S=1(切换控制权),MM_INT_EN=1(如果需要内存映射模式下的中断,否则为0)。
- 向
验证与访问:
- 切换后,对地址
0x3000 0000开始的区域进行读操作,QSPI硬件会自动发起包含命令、地址、dummy cycles和读数据的完整SPI序列,并将数据返回。 - 注意:内存映射模式通常只用于读操作。写操作(编程、擦除)仍然需要通过配置端口,按照Flash的特定命令序列(如写使能、页编程、扇区擦除)来执行。你不能简单地通过向映射地址写入数据来修改Flash。
- 切换后,对地址
5.2 性能优化与注意事项
- 启用Quad/Dual模式:在
QSPI_SETUP_REG中设置READ_TYPE为1(双线)或3(四线),并在QSPI_CMD_REG中使用对应的读命令(CMD=3或7),可以大幅提升读取带宽。前提是Flash已通过写状态寄存器等命令使能了Quad/Dual输出模式。 - Cache与预取:当CPU通过内存映射端口读取Flash时,访问延迟远高于RAM。务必使能处理器的指令/数据Cache,并可能需要在MMU中配置该区域为“Device”或“Normal Non-cacheable”属性(具体取决于芯片设计)。有些芯片的QSPI模块还集成硬件预取器(Prefetcher),需要根据手册配置以提升连续访问性能。
- 地址对齐:虽然可以按字节访问,但为了最佳性能,建议尽量使用32位或64位对齐的访问。硬件的一次传输可能就是一个字长。
- 并发访问冲突:当CPU通过内存映射端口访问Flash时,不能再通过配置端口去访问QSPI寄存器,因为控制权已交给MMPT。如需切换回来进行写操作,需要先将
QSPI_SWITCH_REG的MMPT_S位清零。
6. 常见问题与调试技巧实录
在实际开发中,QSPI驱动不工作或行为异常是常事。以下是我在多个项目中总结的排查清单。
6.1 问题排查速查表
| 现象 | 可能原因 | 排查步骤 |
|---|---|---|
| 无SCK时钟输出 | 1. 时钟未使能。 2. 时钟分频系数 DCLK_DIV设置过大(输出频率为0)。3. 外设时钟门控未打开。 | 1. 检查QSPI_CLOCK_CNTRL_REG[31] (CLKEN)是否为1。2. 计算 DCLK_DIV = (输入频率 / 期望输出频率) - 1。3. 检查芯片系统控制模块,确认QSPI模块时钟已使能。 |
| 片选信号无动作 | 1.QSPI_DC_REG中片选极性CSPx设置错误。2. QSPI_CMD_REG中CSNUM选择错误。3. 硬件连接问题。 | 1. 用逻辑分析仪确认片选信号线电平。通常低有效,应看到低脉冲。 2. 确认 CMD寄存器中的CSNUM与你硬件连接的片选号一致。3. 检查PCB走线。 |
| 能抓到SCK和CS,但数据线无波形 | 1. SPI模式(CKP,CKPH)与从设备不匹配。 2. 数据线方向配置错误(如写操作时DIN上有数据)。 3. 未在 BUSY==0时写入数据或命令。 | 1.首要检查:对照从设备手册,确认QSPI_DC_REG的CKPx和CKPHx设置正确。2. 确认 QSPI_CMD_REG中的CMD字段选择正确(写单线是2,读单线是1等)。3. 在写 DATA_REG和CMD_REG前,循环检查QSPI_STS_REG[0] (BUSY)位。 |
| 数据传输错位或数据错误 | 1. 字长WLEN设置错误。2. 数据在寄存器中没有右对齐。 3. 字节序(Endianness)问题。 | 1. 确认WLEN = 位数 - 1。8位数据对应WLEN=7。2. 手册强调数据应“right justified”。写入 DATA_REG时,确保数据在低位,高位补0。3. 如果设备是MSB先行,而你的数据是LSB,需要在软件中做位反转。 |
| 内存映射模式读取失败 | 1.QSPI_SETUP_REG配置错误(命令码、地址字节、dummy cycles)。2. 未切换 MMPT_S位。3. Flash本身未处于可读状态(如处于写保护、深度省电模式)。 | 1.逐项核对:RCMD、NUM_A_BYTES、NUM_D_BYTES必须与Flash数据手册的“Fast Read”命令完全一致。2. 确认 QSPI_SWITCH_REG[0]已置1。3. 先通过配置端口发送Flash的“Release from Deep Power-down”或“Read Status Register”命令,确认Flash可响应。 |
| 中断无法触发或连续触发 | 1. 中断使能条件不满足(缺少全局或局部使能)。 2. ISR中未正确清除中断标志。 3. 系统级中断未配置(NVIC)。 | 1. 检查双重使能:INTR_EN_SET_REG和CMD_REG/SWITCH_REG。2.重点检查:ISR中是否向 INTR_STS_EN_CLR对应位���1清除,而不是误操作了RAW_SET寄存器。3. 确认处理器NVIC中已使能对应的QSPI中断源。 |
6.2 调试技巧与心得
- 逻辑分析仪是你的最佳伙伴:配置好SPI解码器,抓取SCK、CS、DIO0-3的波形。这是验证时序、命令、数据是否正确的唯一可靠方法。重点关注第一个字节(通常是命令码)是否正确。
- 从最低速开始:将
DCLK_DIV设到最大,以最低时钟频率开始调试。排除时序问题后,再逐步提高频率。 - 善用状态寄存器:在关键操作前后,读取并打印
QSPI_STS_REG的值。观察BUSY、WC、FC、WDCNT的变化是否符合预期。 - 内存映射模式的“探针”:在切换到内存映射模式前,先通过配置端口,用“读状态寄存器”等简单命令验证Flash通信正常。然后再配置
SETUP_REG并切换。 - 注意电源与上电顺序:有些SPI Flash需要特定的上电时序或电压。确保在初始化QSPI前,Flash的供电已稳定。复杂的系统可能还需要控制Flash的硬件复位引脚或写保护引脚。
- 文档版本与勘误:始终使用芯片最新版的数据手册和技术参考手册。仔细阅读“Known Advisories”或“Errata”章节,里面可能有关于QSPI模块的重要硬件Bug和工作限制,这些往往是踩坑的根源。