深入解析SPI/QSPI时序、寄存器配置与调试实战
1. 项目概述与核心价值
搞嵌入式开发,尤其是和微控制器、传感器、闪存芯片打交道,SPI(Serial Peripheral Interface)这个协议你肯定绕不开。它就像嵌入式世界里的“普通话”,简单直接,速度快,还能全双工聊天(同时收发数据),是连接各种外设的基石。但很多朋友在用SPI库函数调通了通信后,往往就止步于此,对底层那些时钟边沿、建立保持时间、主从模式下的信号流向这些“硬核细节”一知半解。等到项目遇到通信不稳定、数据出错,或者需要极致优化速度时,就抓瞎了。
更进阶一点,当你需要从外部QSPI Flash快速启动系统,或者驱动高带宽的显示屏时,标准SPI那单进单出的数据线就显得力不从心了。这时,QSPI(Quad SPI)就该登场了。它本质上还是SPI,但把数据车道从一条拓宽到了四条,数据传输速率直接翻了几番。不过,能力越强,配置也越复杂,什么单线、双线、四线模式,还有那一堆用于定义命令、地址、 dummy cycle 的寄存器,没点真功夫还真容易配置错。
所以,今天我不打算只复述数据手册里的定义,而是结合我这些年调试TI、ST、NXP等多家芯片SPI/QSPI外设的实际经验,带你深入SPI/QSPI的“时序森林”和“寄存器迷宫”。我们会从最根本的时钟极性与相位(CPOL/CPHA)讲起,拆解主从模式下的每一个关键时序参数,然后重点攻克QSPI的寄存器配置逻辑。目标很明确:让你不仅知道寄存器某个位要填0还是1,更明白为什么这么填,以及填错了信号波形会变成什么样。下次再遇到SPI通信问题,你就能像个老中医一样,看着示波器波形,心里门儿清问题出在哪儿。
2. SPI核心时序与工作模式深度解析
SPI通信的基石是同步时钟。不同于UART靠双方约定好的波特率各自计时,SPI通信完全由主设备产生的时钟(SPICLK)来同步节奏。这就引出了两个最核心的概念:时钟极性(CPOL, Clock Polarity)和时钟相位(CPHA, Clock Phase)。它们的四种组合,构成了SPI的四种工作模式(Mode 0-3)。这个知识点看似基础,但却是理解一切时序问题的钥匙。
2.1 时钟极性(CPOL)与时钟相位(CPHA)的本质
你可以把SPICLK信号想象成一条不断起伏的波浪。CPOL决定的是这条波浪在空闲状态(没有数据传输时)时,是趴着的(低电平,CPOL=0)还是站着的(高电平,CPOL=1)。
而CPHA决定的是数据在波浪的哪个“坡”上被采样(捕获)和哪个“坡”上被推出(输出)。这里有个关键:采样和输出是发生在同一个边沿,还是交替的边沿?
- CPHA = 0:数据在第一个时钟边沿被采样。对于输出方(通常是主设备),数据在时钟边沿之前就需要准备好(建立时间),并在该边沿被锁存。对于输入方,它在这个边沿去读取数据线上的值。
- CPHA = 1:数据在第二个时钟边沿被采样。输出方在第一个时钟边沿改变数据,然后在第二个边沿被采样。
那么,第一个边沿是上升沿还是下降沿呢?这由CPOL决定。组合起来就是:
- Mode 0 (CPOL=0, CPHA=0):时钟空闲为低。第一个边沿是上升沿,第二个是下降沿。因此,数据在上升沿被采样(捕获),在下降沿被改变(输出)。这是最常用的模式。
- Mode 1 (CPOL=0, CPHA=1):时钟空闲为低。数据在下降沿被采样,在上升沿被改变。
- Mode 2 (CPOL=1, CPHA=0):时钟空闲为高。第一个边沿是下降沿,第二个是上升沿。数据在下降沿被采样,在上升沿被改变。
- Mode 3 (CPOL=1, CPHA=1):时钟空闲为高。数据在上升沿被采样,在下降沿被改变。
注意:很多数据手册(包括你提供的TI文档)会特别指出,Mode 1和Mode 2在其特定硬件上可能不被支持或不应使用。这通常与芯片内部时钟树和IO pad的设计有关。在配置前,务必查阅你所使用芯片的最新数据手册,确认支持的模式。盲目使用不支持的模式会导致通信彻底失败。
2.2 主从模式下的引脚角色与关键时序参数
理解了模式,我们再看信号线。一个典型的SPI接口包含以下引脚:
- SPICLK (SCK): 串行时钟,永远由主设备驱动。
- SPISIMO (MOSI): 主设备输出,从设备输入。
- SPISOMI (MISO): 主设备输入,从设备输出。
- SPISCS (CS/SS): 片选信号,低有效,由主设备驱动,用于选择目标从设备。
主从模式下的根本区别在于引脚方向:
- 主模式: SPICLK、SPISIMO、SPISCS 为输出;SPISOMI 为输入。
- 从模式: SPICLK、SPISIMO、SPISCS 为输入;SPISOMI、SPIENA(如果支持)为输出。
这里出现了一个你可能陌生的引脚:SPIENA。这是一个可选的“从设备就绪”信号。在4线或5线配置中,从设备可以通过拉低SPIENA来告诉主设备:“我准备好接收/发送数据了”。主设备会等待这个信号有效后才开始产生时钟。这对于连接速度较慢的从设备非常有用,是实现流控的一种简单方式。
现在,我们结合时序图来理解几个关键的时序参数。这些参数决定了通信的稳定性和最高速度。
建立时间(Setup Time, t_su)与保持时间(Hold Time, t_h):
- 对于输入数据(主设备读MISO,从设备读MOSI):数据信号(SPISOMI/SPISIMO)必须在SPICLK的采样边沿之前稳定一段时间,这就是建立时间(t_su);在采样边沿之后还需要继续保持稳定一段时间,这就是保持时间(t_h)。如果数据在这两个窗口内变化,就可能被误采样。
- 对于输出数据(主设备写MOSI,从设备写MISO):主设备必须在SPICLK的对应边沿(根据CPHA决定)之前就将数据驱动到MOSI线上,确保从设备有足够的建立时间。这个时间通常由主设备控制器硬件保证。
时钟到输出延迟(Clock-to-Output Delay, t_co):
- 指从SPICLK的边沿(通常是数据改变的边沿)到数据引脚(SPISIMO/SPISOMI)上出现新数据的延迟。这个参数会影响从设备输出数据的时序,如果延迟太大,可能无法满足主设备的建立时间要求。
片选有效到时钟有效时间(CS to CLK Active):
- 主设备拉低片选(SPISCS)后,需要等待一段时间(t_css)再发出第一个SPICLK边沿。这段时间是留给从设备识别片选并做好准备的。
时钟空闲时间(Clock Idle Time):
- 在两个字节或帧传输之间,SPICLK需要保持一段时间的空闲状态(由CPOL决定)。这保证了从设备内部移位寄存器有足够时间处理数据。
实操心得:调试SPI通信,示波器或逻辑分析仪是必备工具。抓取SPICLK、SPISCS、SPISIMO、SPISOMI四路信号,对照你配置的模式(CPOL/CPHA),检查:
- 采样边沿是否正确?数据在采样边沿是否稳定(建立/保持时间足够)?
- 片选信号在整帧数据传输期间是否保持有效(低电平)?
- 主从设备的数据输出边沿是否匹配?例如,主设备在下降沿输出,从设备也必须在下降沿输出,否则数据会错位。 很多“玄学”通信问题,根源都在于主从设备模式配置不一致,或者物理线路过长导致时序裕量不足。
3. QSPI架构、工作模式与核心机制
当标准SPI的速度成为瓶颈时,QSPI通过增加数据线数量来提升吞吐量,其核心思想是“拓宽车道”而非单纯“提高车速”。QSPI模块通常作为系统启动的加速器,用于快速读取外部SPI Flash中的代码(XiP, eXecute in Place)。
3.1 QSPI与标准SPI的核心区别
标准SPI是“单车道”通信:一根数据线输出(MOSI),一根数据线输入(MISO)。QSPI则拥有最多四根双向数据线(通常称为IO0, IO1, IO2, IO3),它们可以根据指令被灵活配置为输入或输出。
- 单线模式: 仅使用IO0(相当于MOSI)和IO1(相当于MISO),完全兼容标准SPI。
- 双线模式: 在读取数据时,同时使用IO0和IO1作为输入,理论带宽翻倍。
- 四线模式: 在读取数据时,同时使用IO0, IO1, IO2, IO3作为输入,理论带宽是单线模式的四倍。
一个至关重要的限制:QSPI通常只支持双线和四线读取(Read),不支持双线/四线写入(Write)。写入操作一般仍使用单线模式。这是因为大多数SPI Flash芯片的底层物理接口设计如此,写入需要更复杂的电压控制,难以并行化。此外,QSPI也不支持“直通模式”(Pass-Through),即不能简单地将输入数据回显到输出。
3.2 QSPI模块的双重身份:SPI核心与内存映射接口
从你提供的TI文档框图可以看出,一个典型的QSPI模块(如QSPI)内部包含两大核心部分:
- SPI_CORE: 这是通用的SPI引擎。它负责生成时钟、控制数据移位、管理片选等所有底层的、与协议相关的操作。你可以通过配置它的寄存器(如
SPI_DC_REG,SPI_CMD_REG,SPI_DATA_REG)来执行任意自定义的SPI传输,就像操作一个增强型标准SPI外设一样。 - SFI_MM_IF: 这是串行闪存内存映射接口。它是一个更高层的抽象,专门为简化与SPI Flash的交互而设计。它内部包含一个“翻译器”(SFI Translator),能够将CPU发起的普通内存读/写请求(访问某个内存地址),自动转换成一整套符合SPI Flash协议的序列:激活片选 -> 发送读命令码 -> 发送地址 -> 发送Dummy周期 -> 连续读取数据 -> 取消片选。
这两个部分通过一个“开关”(SPI_SWITCH_REG[0] MMPT_S位)来切换对SPI_CORE的控制权:
- 当
MMPT_S = 0时,配置端口(Configuration Port)连接到SPI_CORE。此时,软件需要直接操作SPI_CORE的所有寄存器来发起传输,灵活性高,但编程复杂。 - 当
MMPT_S = 1时,内存映射端口(Memory-Mapped Port)连接到SPI_CORE。此时,CPU可以将一片外部地址空间(例如0x6000_0000-0x63FF_FFFF)映射到外部SPI Flash。当CPU读取这个地址范围内的数据时,SFI_MM_IF会自动完成上述复杂的Flash读序列,对软件来说就像读取内部RAM一样简单,这是实现XiP的关键。
3.3 QSPI时钟模式与数据移位机制
QSPI的SPI_CORE同样支持四种时钟模式(Mode 0-3),其定义与标准SPI完全一致,由SPI_DC_REG寄存器中的CKPi和CKPHi位控制(i对应不同的片选)。
数据移位是SPI通信的核心。QSPI内部有一个最大128位的移位寄存器,由SPI_DATA_REG_3到SPI_DATA_REG四个寄存器级联而成。SPI_CMD_REG中的WLEN位域定义了本次传输的字长(1-128位)。
这里有一个关键细节:数据在寄存器中是右对齐的。例如,你要发送一个8位数据0xA5,字长WLEN应设置为7(表示8位),然后将0xA5写入SPI_DATA_REG的最低字节。硬件会自动从最高位(MSB)或最低位(LSB)开始移位,这通常由另一个配置位控制。对于超过32位的数据,你需要依次填充SPI_DATA_REG,SPI_DATA_REG_1等。
帧传输:QSPI支持连续传输多个“字”构成一“帧”。SPI_CMD_REG中的FLEN位域定义了帧中的字数(1-4096)。传输启动后,每完成一个字(WLEN定义的位数),状态寄存器中的WC(Word Complete)标志会置位。当整个帧传输完毕,FC(Frame Complete)标志置位。通过使能相应中断(WIRQ,FIRQ),可以实现高效的中断驱动传输。
4. QSPI寄存器配置详解与实战流程
理解了架构,我们进入最实战的部分:如何配置这些寄存器,让QSPI按照我们的意愿工作。我们以通过内存映射接口读取SPI Flash这个最常用的场景为例,拆解配置流程。
4.1 配置流程总览
- 基础时钟与引脚复用配置: 首先通过系统时钟控制器使能QSPI模块的时钟,并通过引脚复用功能将对应的MCU引脚配置为QSPI功能。
- 切换至配置端口模式: 设置
SPI_SWITCH_REG[0] MMPT_S = 0,以便我们能配置SPI_CORE和SFI_MM_IF的所有寄存器。 - 配置SPI_CORE基础参数: 设置时钟分频、SPI模式、片选极性等。
- 配置SFI_MM_IF的Flash参数: 设置读/写命令码、地址字节数、Dummy周期数、读模式(单/双/四线)等。这些配置与具体型号的SPI Flash相关。
- 切换至内存映射端口模式: 设置
SPI_SWITCH_REG[0] MMPT_S = 1。 - 进行内存映射访问: CPU直接读取映射后的地址空间,硬件自动完成Flash读取。
4.2 关键寄存器逐位解析
1. QSPI_SPI_DC_REG (SPI Device Configuration Register)这个寄存器为每个片选(CS0-CS3)独立配置SPI协议相关参数。
CSPi(i=0~3): 片选极性。0=低有效,1=高有效。绝大多数SPI设备是低有效。CKPi,CKPHi: 如前所述,组合决定SPI时钟模式(Mode 0-3)。对于大多数SPI Flash,使用Mode 0 (CPOL=0, CPHA=0)。DDi: 数据延迟。定义片选有效后,延迟多少个QSPI时钟周期才开始输出数据。用于满足某些Flash芯片的t_CSH(片选保持时间)要求。
2. QSPI_SPI_CLOCK_CNTRL_REG (SPI Clock Control Register)
DCLK_DIV: 时钟分频因子。QSPI模块工作时钟QSPI_FCLK经过(DCLK_DIV + 1)分频后,产生输出时钟qspi1_sclk。例如,QSPI_FCLK=100MHz,DCLK_DIV=4,则qspi1_sclk = 100MHz / (4+1) = 20MHz。CLKEN: QSPI时钟使能位。必须置1,SPI命令才会被执行。
3. QSPI_SPI_SETUPx_REG (x=0~3, SPI Setup Registers)这是配置Flash读写的核心。每个寄存器对应一个片选,可以预先定义好连接在该片选上的Flash的访问参数。
RCMD[7:0]:读命令字节。例如,标准SPI Flash的普通读命令是0x03,快速读(Fast Read)命令是0x0B。WCMD[23:16]:写命令字节。如页编程命令0x02。NUM_A_BYTES[9:8]:地址字节数。SPI Flash的地址通常是3字节(24位)或4字节(32位)。NUM_D_BYTES[11:10]&NUM_D_BITS[28:24]:Dummy周期数/位数。在“快速读”模式下,发送地址后,Flash需要几个时钟周期的处理时间才能输出数据,这段时间内主设备需要发送“哑元”时钟周期。NUM_D_BYTES以字节为单位(0-3),NUM_D_BITS以位为单位,两者结合可以配置非整字节的Dummy周期。例如,NUM_D_BYTES=1,NUM_D_BITS=0,表示1个字节(8个时钟周期)的Dummy。READ_TYPE[13:12]:读类型。定义使用单线、双线还是四线模式进行数据读取。例如,0x1代表双线读,0x2代表四线读。这必须与Flash芯片支持的模式以及你硬件连接的数据线数量匹配。
4. QSPI_SPI_CMD_REG (SPI Command Register)这是触发传输的命令寄存器。
CMD[18:16]:命令字段。0x0: 保留。0x1: 仅接收(从MISO或QIO线读数据)。0x2: 仅发送(向MOSI线写数据)。0x3: 发送后接收(全双工)。0x4: 保留。0x5: 停止当前帧传输。
WLEN[25:19]:字长。定义单次传输的位数减1。要传8位,则设置为7;传32位,设置为31。FLEN[11:0]:帧长。定义一次帧传输包含多少个“字”。WIRQ,FIRQ:字完成中断使能、帧完成中断使能。置1后,当WC或FC状态位有效时,如果全局中断使能也打开,则会触发中断。
5. QSPI_SPI_STATUS_REG (SPI Status Register)
BUSY[0]:忙标志。当CMD被写入一个有效命令后,此位置1。传输完成后,硬件自动清零。在BUSY=1时,写入SPI_CMD_REG等关键寄存器是无效的。WC[1]:字传输完成。每传输完一个字(WLEN定义的位数),此位置1。读此寄存器或写SPI_CMD_REG会清零此位。FC[2]:帧传输完成。整个帧(FLEN定义的字数)传输完成后,此位置1。清除方式同WC。
4.3 实战配置示例:配置QSPI在四线模式读取Flash
假设我们使用一片支持四线快速读(Quad Fast Read)的SPI Flash,其命令如下:
- 四线快速读命令码:
0xEB(也可能是0x6B,具体查Flash手册) - 地址:3字节
- Dummy周期:8个(1字节)
- SPI模式:Mode 0 (CPOL=0, CPHA=0)
- 期望QSPI_SCLK频率:50MHz (假设
QSPI_FCLK=200MHz)
步骤一:基础配置(配置端口模式)
- 设置
SPI_SWITCH_REG[0] MMPT_S = 0。 - 配置
SPI_DC_REG:对于CS0,设置CSP0=0(低有效),CKP0=0,CKPH0=0(Mode 0),DD0=0(无延迟)。 - 配置
SPI_CLOCK_CNTRL_REG:计算分频,DCLK_DIV = (200MHz / 50MHz) - 1 = 3。设置DCLK_DIV=3,CLKEN=1。
步骤二:配置Flash访问参数(SFI_MM_IF)
- 配置
SPI_SETUP0_REG(对应CS0):RCMD = 0xEBNUM_A_BYTES = 2(表示3字节地址,通常编码为地址字节数-1)NUM_D_BYTES = 1(1字节Dummy)READ_TYPE = 2(四线读)- (
WCMD根据写操作需要配置,此处暂不设置)
步骤三:切换至内存映射模式并访问
- 设置
SPI_SWITCH_REG[0] MMPT_S = 1。 - 假设内存映射起始地址为
0x60000000。要读取Flash物理地址0x1000处的数据,CPU只需执行uint32_t data = *(volatile uint32_t*)(0x60001000);。硬件会自动发起包含命令0xEB、地址0x1000、1字节Dummy周期和四线数据读取的完整序列。
注意事项:在通过内存映射端口访问前,必须确保Flash存储区域已被擦除(全为0xFF)。Flash写入操作只能将位从1改为0,从0改为1需要先进行扇区/块擦除。擦除操作通常需要通过配置端口发送专门的擦除命令序列来完成,无法通过内存映射写自动完成。
5. 高级话题:时序优化、中断与DMA应用
5.1 时序裕量分析与优化
在高频(如50MHz以上)或长走线情况下,时序问题会凸显。你需要计算并验证关键路径的时序裕量。
- 主设备输出时序: 主设备的
t_co(时钟到输出延迟)加上PCB走线延迟,必须满足从设备的t_su(输入建立时间)。如果裕量为负,数据在从设备采样时可能不稳定。优化方法:降低时钟频率、缩短走线、在QSPI模块中启用输出延迟(如果支持,即DDi位)、选择t_co更小的主控或t_su要求更宽松的从设备。 - 从设备输出时序: 从设备的
t_co加上走线延迟,必须满足主设备的t_su。优化方法:同上,或检查从设备是否有“保持输出”模式,可以提前输出数据。 - 时钟抖动: 高频下的时钟抖动会侵蚀建立和保持时间窗口。选择低抖动的时钟源,优化电源和地平面设计。
一个实用的调试技巧:用示波器测量从设备MISO引脚相对于主设备SCK采样边沿的时序。如果发现建立时间不足,可以尝试调整SPI模式。例如,从Mode 0切换到Mode 3,相当于将采样边沿从时钟的第一个边沿移到了第二个边沿,这给了从设备多半个时钟周期的时间来准备数据,有时能解决临界时序问题。
5.2 中断与DMA配置实战
对于大数据量传输,使用查询方式(Polling)会大量占用CPU。利用中断和DMA可以解放CPU。
中断配置:
- 在
SPI_CMD_REG中使能WIRQ(字完成中断)或FIRQ(帧完成中断)。 - 在中断使能寄存器(如
QSPI_INTR_ENABLE_SET_REG)中使能对应的中断源。 - 在NVIC中使能QSPI全局中断。
- 在中断服务程序(ISR)中:
- 检查
SPI_STATUS_REG的WC或FC标志。 - 如果是字完成中断,且采用“发送-等待-再发送”的流式传输,则写入下一个字的数据到
SPI_DATA_REG,然后再次写入CMD字段启动下一次传输。 - 清除中断状态标志(通过写
QSPI_INTR_STATUS_ENABLED_CLEAR寄存器)。
- 检查
DMA配置: QSPI通常可以与DMA控制器联动,实现数据在内存和SPI_DATA_REG之间的自动搬运。
- 配置DMA通道:源/目标地址设为
SPI_DATA_REG的地址,数据宽度与SPI字长匹配。 - 将QSPI的“传输完成”事件(如
WC)映射到DMA的硬件请求源。 - 在SPI传输开始时,启动DMA。
- QSPI每完成一个字的传输,就会触发DMA请求,DMA自动搬运下一个字的数据到QSPI(发送)或从QSPI搬运到内存(接收)。
- 当DMA传输完成整个缓冲区后,产生DMA完成中断,再结束SPI帧传输。
常见问题:使能了中断但一直不触发?首先检查
BUSY位,确保上一次传输已完成。其次,检查MMPT_S位。在内存映射端口模式下,SPI_CMD_REG中的WIRQ/FIRQ可能被忽略,需要同时使能SPI_SWITCH_REG[1] MM_INT_EN位。最后,确认NVIC的中断通道已正确使能并设置了优先级。
6. 典型问题排查与避坑指南
在实际项目中,我踩过不少SPI/QSPI的坑。这里总结几个最常见的问题和排查思路,希望能帮你节省时间。
问题一:通信完全无反应,示波器上看不到任何时钟和数据信号。
- 检查清单:
- 时钟和电源: 确认QSPI外设的时钟是否使能?相关GPIO的时钟呢?芯片的供电电压是否在正常范围?
- 引脚复用: 这是最常见的原因!确认MCU的对应引脚是否已正确配置为SPI/QSPI功能,而不是普通的GPIO。
- 片选信号: 片选引脚配置是否正确(输出模式)?极性是否正确(通常是低有效)?程序里有没有在传输前拉低片选?传输期间是否一直保持有效?
- 软件锁: 某些芯片的QSPI模块在复位后可能有写保护锁,需要先向特定密钥寄存器写入解锁序列才能配置。
问题二:能抓到时钟和数据波形,但数据内容错误。
- 检查清单:
- 模式匹配:这是头号嫌疑犯!用示波器对照波形,严格检查主从设备的CPOL和CPHA设置是否完全一致。一个在上升沿采样,另一个在下降沿采样,数据必然错位。
- 字节序(Endianness): 你发送的数据
0xAABB,对方收到的是0xBBAA吗?检查SPI是MSB先发还是LSB先发,并与从设备的数据手册核对。 - 字长匹配: 主设备配置为发送8位数据,但从设备期望16位?这会导致数据帧错位。确保双方约定的数据帧长度一致。
- 电气问题: 波形是否有严重的过冲、振铃或毛刺?这可能导致误采样。检查阻抗匹配,必要时在信号线上串联一个小电阻(如22-33欧姆)。
问题三:QSPI内存映射读取成功,但写入数据失败或数据异常。
- 检查清单:
- 写使能(Write Enable): SPI Flash在每次页编程或擦除操作前,必须先发送写使能命令(通常是
0x06)。这个操作需要通过配置端口(MMPT_S=0)手动发送命令序列来完成,内存映射写操作不会自动发送此命令。 - 擦除状态: 你写入的地址所在的扇区/块是否已经被擦除(全为0xFF)?Flash只能写0,不能写1。尝试写入前,先通过配置端口发送扇区擦除命令。
- 忙状态检查: Flash在执行写或擦除操作时,需要一定时间(ms级)。操作发起后,需要通过读状态寄存器命令(如
0x05)轮询忙状态位,直到操作完成才能进行下一步。 - 地址对齐: 某些Flash的页编程操作要求地址和数据的起始位置与页边界对齐。检查是否违反了这些限制。
- 写使能(Write Enable): SPI Flash在每次页编程或擦除操作前,必须先发送写使能命令(通常是
问题四:使用双线/四线模式读取Flash,速度没有提升或数据错误。
- 检查清单:
- Flash是否支持: 确认你的Flash芯片型号确实支持双线或四线读取模式。并非所有SPI Flash都支持。
- 模式使能: 许多Flash在出厂时处于标准的单线SPI模式。要使用双线/四线模式,通常需要先向Flash的配置寄存器写入特定的值来使能该模式。这个操作同样需要通过配置端口手动完成。
- QSPI配置: 检查
SPI_SETUPx_REG中的READ_TYPE是否已正确设置为双线(1)或四线(2)模式。 - 硬件连接: 确认所有用到的数据线(IO0-IO3)都已正确连接到Flash芯片,并且上拉电阻配置正确(通常需要上拉)。
调试是一个系统工程,从电源、时钟、引脚,到软件配置、协议匹配,再到硬件信号质量,层层递进。养成先看波形,再分析代码的习惯,大部分问题都能迎刃而解。希望这篇结合了理论、手册解读和实践经验的总结,能成为你下次调试SPI/QSPI时的得力参考。
