1. 项目概述深入Tiva QSSI的SPI通信核心在嵌入式开发尤其是基于德州仪器Tiva™系列微控制器的项目中SPI串行外设接口几乎是连接外部传感器、存储器和显示模块的“标配”。但很多开发者包括我早期都曾有过这样的困惑明明按照标准SPI时序写了驱动为什么和某些特定芯片通信就是不稳定甚至完全不通问题往往就出在“帧格式”和“时钟模式”的配置细节上。Tiva微控制器内部的Quad同步串行接口QSSI模块功能强大它不仅仅支持我们常说的“标准SPI”还完整兼容Freescale现NXP和TI自家的同步串行帧格式。这两种格式在信号行为特别是片选信号SSInFss和时钟SSInClk的空闲状态、启动时序上有着根本性的区别。更关键的是在Freescale SPI模式下通过SPO时钟极性和SPH时钟相位这两个比特位的组合可以衍生出四种不同的数据采样时序模式。如果配置与外设芯片的要求不匹配数据采样边沿对不上通信自然失败。这篇文章我就结合手册和实际调试经验为你彻底拆解Tiva QSSI模块的这两种帧格式以及Freescale SPI的四种工作模式。我会用示波器抓取的实际波形图虽然这里用文字描述和寄存器配置代码片段让你不仅知道怎么配更明白为什么要这样配以及在不同场景下如何做出最合适的选择。2. 核心概念解析SPI通信的基石在深入QSSI模块的具体实现之前我们必须先统一几个核心概念的理解。这些概念是理解后续所有配置差异和时序图的基础。2.1 信号线定义与角色Tiva QSSI模块的SPI接口通常由四根线构成理解每根线的角色至关重要SSInClk (Serial Clock): 串行时钟线由主机产生用于同步主从设备之间的数据移位。它的频率、极性和相位是本文讨论的核心。SSInFss (Frame Select): 帧选择信号在SPI语境下通常作为片选Chip Select, CS或从机选择Slave Select, SS信号。它的行为模式是区分Freescale和TI格式的关键。SSInTx/SSInDAT0 (Master Out Slave In, MOSI): 主机输出、从机输入数据线。主机通过此线向从机发送数据。SSInRx/SSInDAT1 (Master In Slave Out, MISO): 主机输入、从机输出数据线。主机通过此线接收从机数据。注意在高级的Bi-SSI或Quad-SSI模式下DAT0-DAT3所有引脚都可能被用作双向数据线但这超出了基础SPI讨论范围。本文聚焦于标准四线SPI模式。2.2 时钟极性(CPOL)与时钟相位(CPHA)这是SPI配置中最容易混淆也最核心的两个参数。在QSSI的寄存器中它们对应SPO (SSICR0[6])和SPH (SSICR0[7])位。时钟极性 SPO (Clock Polarity):SPO 0: 时钟空闲时为低电平。这意味着在数据传输的间隙SSInClk线保持为低。SPO 1: 时钟空闲时为高电平。在数据传输间隙SSInClk线保持为高。关键影响它决定了时钟信号在空闲时的静态电平是波形的基础。时钟相位 SPH (Clock Phase):SPH 0: 数据在第一个时钟边沿被采样捕获。对于SPO0第一个边沿是上升沿对于SPO1第一个边沿是下降沿。SPH 1: 数据在第二个时钟边沿被采样。对于SPO0第二个边沿是下降沿对于SPO1第二个边沿是上升沿。关键影响它决定了数据采样发生的时刻直接关系到数据建立Setup和保持Hold时间是否满足从机要求。SPH位对传输的第一个数据位影响最大因为它决定了在第一个数据位有效之前是否有一个额外的半个时钟周期的延迟。这两个位的四种组合SPO/SPH: 0/0, 0/1, 1/0, 1/1构成了常说的SPI Mode 0, 1, 2, 3。具体对应关系为Mode 0 (CPOL0, CPHA0), Mode 1 (CPOL0, CPHA1), Mode 2 (CPOL1, CPHA0), Mode 3 (CPOL1, CPHA1)。你所连接的外设数据手册中一定会明确指定其工作在哪种Mode。2.3 帧格式Freescale vs. TI这是Tiva QSSI模块提供的两种底层协议格式选择通过FRF (SSICR0[5:4])位域进行选择。Freescale SPI Frame Format (FRF 0x0):这是我们最常接触的“经典”SPI格式。在此格式下SSInFss信号作为纯粹的低有效片选信号。其行为与SPO/SPH的配置紧密相关。在空闲时SSInFss通常被拉高无效。当主机要发起传输时先将SSInFss拉低选中从机然后根据SPO/SPH的配置产生时钟并收发数据。它支持全部四种SPO/SPH模式提供了最大的灵活性以适配各种外设。Texas Instruments Synchronous Serial Frame Format (FRF 0x1):这是TI定义的一种格式。在此格式下SSInFss信号的行为更像一个帧同步脉冲而非持续的片选。在空闲时SSInClk和SSInFss都被强制为低电平。当发送FIFO中有数据时SSInFss会先产生一个时钟周期的高电平脉冲然后在下一个时钟上升沿数据帧的最高位MSB开始移出。重要限制在TI格式下SPO和SPH位必须为0即SPO0 SPH0且不可配置。它固定了一种时序模式。选择哪种格式完全取决于你要通信的从设备要求。绝大多数SPI外设如Flash、ADC、传感器都遵循Freescale SPI格式。而一些TI自家的或其他特定协议的芯片可能会要求使用TI同步串行帧格式。3. 帧格式与工作模式深度对比理解了基本概念后我们进入实战分析环节。手册中的Table 20-4提供了一个高层次的特性对比但我们需要结合时序图来理解这些特性在信号电平上的具体表现。3.1 特性对比总览特性 (Feature)Freescale SPI 模式TI 模式说明与影响帧保持 (Frame Hold)可用不可用在Freescale格式下可通过FSSHLDFRM位控制SSInFss是在整个数据帧期间保持有效1还是每字节产生一个脉冲0。TI格式下SSInFss固定为单周期脉冲。高速模式 (仅主机接收)可用不可用在Freescale格式下主机接收时可使用更高速度的内部时钟提升吞吐量。通过HSCLKEN位使能。SPO/SPH配置完全可配置(0/0, 0/1, 1/0, 1/1)固定为 SPO0, SPH0这是两种格式最根本的差异之一。Freescale格式的灵活性使其能适配绝大多数SPI从机。TI格式则固定了一种时序。频率 (系统时钟:SSInClk)主机 1:2从机 1:12主机 1:2从机 1:12分频器设置相同最大通信速率理论值一致。但实际最高速率受限于GPIO速度、板级布线等因素。高级/Bi-/Quad-SSI模式支持支持但有限制支持但有限制在这些增强模式下两种格式都支持帧保持和高速模式。但关键限制是SPO和SPH必须配置为0。这意味着在增强模式下只能使用Freescale格式的Mode 0 (SPO0, SPH0)。实操心得这个对比表是你选型的快速参考。如果你的项目需要使用Bi-SSI或Quad-SSI模式例如驱动QSPI Flash以提升速度那么无论从机支持哪种模式你都只能将其配置为Freescale SPI格式且SPO0 SPH0。这是硬件限制软件无法绕过。3.2 Texas Instruments (TI) 同步串行帧格式详解当FRF位设置为0x1时QSSI工作在TI格式下。这种格式的时序相对简单固定。核心特点空闲状态SSInClk和SSInFss均被强制为低电平。发送数据线SSInTx为高阻态。启动传输当发送FIFO中有数据时硬件自动将SSInFss拉高一个SSInClk周期。这个上升沿和下降沿构成了一个同步脉冲。数据移出在SSInFss脉冲的下一个时钟上升沿数据帧的最高位MSB开始从SSInTx引脚移出。同时从机也应在此刻将其数据的MSB放到SSInRx引脚上。数据采样主从双方都在每个时钟的下降沿将数据采样到各自的移位寄存器中。这是一个固定的“上升沿变化下降沿采样”的模式对应SPO0 SPH0。连续传输在背靠背连续传输时SSInFss会在每帧数据之间再次产生一个单周期的高脉冲作为下一帧的起始信号。配置示例与代码 假设我们需要在TI格式下以主模式、1Mbps速率、8位数据长度进行通信。系统时钟为20MHz。 根据公式SSInClk SysClk / (CPSDVSR * (1 SCR))我们需要CPSDVSR * (1 SCR) 20MHz / 1MHz 20。 一个典型配置是CPSDVSR 2SCR 9。因为2 * (19) 20。// 假设使用QSSI0模块 void QSSI0_TI_Mode_Init(void) { // 1. 确保SSE位为0禁用QSSI以进行配置 SSI0_CR1_R 0x00000000; // 清除SSE // 2. 配置为主机模式 (MS0) // 此时SSE0所以可以直接写SSICR1的MS位但通常我们直接写整个寄存器更清晰 // 实际上在初始化序列中我们会在最后一步才设置SSE所以这里可以先不管CR1 // 3. 配置时钟预分频器 CPSDVSR 2 SSI0_CPSR_R 0x00000002; // 4. 配置控制寄存器0 (SSICR0) // DSS 0x7 (8-bit data) // FRF 0x1 (TI format) // SPO 0, SPH 0 (TI格式固定为此值) // SCR 0x9 // 计算: DSS7, FRF1, SPO0, SPH0, SCR9 // 位域: DSS[3:0]0x7, FRF[5:4]0x1, SPO[6]0, SPH[7]0, SCR[15:8]0x09 // 寄存器值: (SCR8) | (SPH7) | (SPO6) | (FRF4) | DSS // (0x098) | (07) | (06) | (14) | 0x07 // 0x0900 | 0x00 | 0x00 | 0x10 | 0x07 0x0917 SSI0_CR0_R 0x00000917; // 5. 最后使能QSSI模块 (设置SSE位) // 同时确认MS位为主机模式(0) SSI0_CR1_R 0x00000002; // SSE1, MS0, 其他位为0 }这个配置产生的时序将严格遵循上文描述的TI格式。注意在这种格式下你无法通过修改SPO/SPH来调整采样边沿。3.3 Freescale SPI格式的四种模式详解当FRF位设置为0x0时QSSI工作在Freescale SPI格式下。此时SPO和SPH位的配置将决定四种不同的时序模式。这是调试SPI驱动时最需要关注的部分。通用空闲状态对于所有Freescale模式SSInFss被强制为高电平无效。SSInTx为高阻态。SSInClk的电平由SPO位决定SPO0时为低SPO1时为高。3.3.1 模式0SPO0 SPH0这是最常用的SPI模式之一。时序特点空闲时时钟SSInClk为低片选SSInFss为高。传输开始时主机先将SSInFss拉低选中从机。第一个数据捕获边沿发生在SSInClk的第一个上升沿。也就是说在SSInFss变低后数据线SSInTx和SSInRx上的数据必须在第一个时钟上升沿到来之前就已经稳定满足建立时间。数据在时钟上升沿被采样在下降沿发生变化。连续传输的坑当SPH0时从机的移位寄存器在片选有效期间会被“冻结”。这意味着在背靠背连续传输时主机必须在每个数据字传输结束后将SSInFss拉高至少一个时钟周期然后再拉低开始下一个字的传输以便从机内部能锁存当前数据并准备下一个数据。如果SSInFss一直保持低电平从机将无法更新其发送数据寄存器导致主机连续读到同一个数据。配置代码片段// 配置为Freescale SPI, Mode 0 (SPO0, SPH0), 8-bit data // SCR 和 CPSDVSR 根据所需波特率计算 SSI0_CR0_R (SCR 8) | (0 7) /*SPH*/ | (0 6) /*SPO*/ | (0 4) /*FRF0*/ | 0x07 /*DSS8-bit*/;3.3.2 模式1SPO0 SPH1时序特点空闲状态同模式0。传输开始时主机拉低SSInFss。关键区别在第一个时钟边沿上升沿到来时数据线尚未准备好有效数据。数据是在第一个上升沿之后才被放到数据线上的。第一个数据捕获边沿发生在SSInClk的第一个下降沿。即数据在时钟下降沿被采样在上升沿发生变化。连续传输的优势由于SPH1从机在片选有效期间可以更新其数据寄存器。因此在背靠背连续传输时SSInFss可以始终保持低电平无需在字与字之间插入高电平脉冲从而实现真正的全速连续流传输。配置代码片段// 配置为Freescale SPI, Mode 1 (SPO0, SPH1) SSI0_CR0_R (SCR 8) | (1 7) /*SPH*/ | (0 6) /*SPO*/ | (0 4) /*FRF0*/ | 0x07;3.3.3 模式2SPO1 SPH0时序特点空闲时时钟SSInClk为高这是与模式0/1的主要视觉区别。传输开始时主机拉低SSInFss。第一个数据捕获边沿发生在SSInClk的第一个下降沿。因为空闲时钟为高第一个边沿是下降沿。数据在时钟下降沿被采样在上升沿发生变化。连续传输的限制与模式0相同由于SPH0在背靠背传输时SSInFss需要在字间置高。重要硬件配置当设置SPO1时空闲时钟为高。为了防止时钟线浮空导致的不确定状态必须将对应的GPIO引脚即SSInClk配置为内部上拉。这是手册中明确强调的一点否则可能导致从机在空闲时误采样到时钟边沿。// 在GPIO初始化中除了配置AFSEL、PCTL、DEN外还需要使能上拉 GPIO_PORTA_PUR_R | (1 2); // 假设SSI0Clk在PA2配置代码片段// 配置为Freescale SPI, Mode 2 (SPO1, SPH0) SSI0_CR0_R (SCR 8) | (0 7) /*SPH*/ | (1 6) /*SPO*/ | (0 4) /*FRF0*/ | 0x07;3.3.4 模式3SPO1 SPH1时序特点空闲时时钟SSInClk为高。传输开始时主机拉低SSInFss。第一个时钟边沿下降沿到来时数据尚未有效。第一个数据捕获边沿发生在SSInClk的第一个上升沿。数据在上升沿采样在下降沿变化。连续传输的优势与模式1相同由于SPH1支持SSInFss保持低电平的背靠背连续传输。同样需要上拉与模式2相同必须配置SSInClk对应GPIO的上拉电阻。配置代码片段// 配置为Freescale SPI, Mode 3 (SPO1, SPH1) SSI0_CR0_R (SCR 8) | (1 7) /*SPH*/ | (1 6) /*SPO*/ | (0 4) /*FRF0*/ | 0x07;调试经验当SPI通信不通时第一个要检查的就是模式匹配。用逻辑分析仪或示波器抓取SSInClk、SSInFss和SSInTx的波形。首先看空闲时SSInClk的电平确定SPO然后看第一个数据位的变化是发生在SSInFss有效后的第一个时钟边沿之前还之后确定SPH。将抓到的波形与外设数据手册的时序图对比就能立刻发现问题。4. 初始化配置流程与实战示例理解了原理我们来看如何一步步正确配置QSSI模块。手册第20.4节给出了标准的初始化步骤我结合自己的经将其细化并补充关键细节。4.1 标准初始化步骤拆解使能模块时钟通过RCGCSSI寄存器使能目标QSSI模块的时钟。这是访问任何外设寄存器的前提。SYSCTL-RCGCSSI | (1 0); // 使能 SSI0 模块时钟 __asm__ volatile(nop); // 插入少量延时等待时钟稳定 __asm__ volatile(nop);使能GPIO时钟与引脚复用通过RCGCGPIO使能连接QSSI信号的GPIO端口时钟。查询芯片数据手册的“引脚复用表”例如Table 30-5确定SSInClk、SSInFss、SSInTx、SSInRx具体复用到哪个GPIO引脚。设置对应GPIO引脚的AFSEL交替功能选择位为1。配置PCTL端口控制寄存器将引脚功能映射到对应的SSI数字功能编号。设置DEN数字使能位为1使能数字功能。// 假设SSI0使用PA2(Clk), PA3(Fss), PA5(Tx), PA4(Rx) SYSCTL-RCGCGPIO | (1 0); // 使能 GPIO Port A 时钟 while(!(SYSCTL-PRGPIO (1 0))); // 可选等待就绪 GPIOA-LOCK 0x4C4F434B; // 解锁GPIO Commit寄存器如果芯片需要 GPIOA-CR | 0x3C; // 允许修改PA2-PA5 GPIOA-AFSEL | (12)|(13)|(14)|(15); // 使能PA2-PA5的复用功能 GPIOA-PCTL ~0x00FF0000; // 清除PA2-PA5的旧复用设置 GPIOA-PCTL | 0x00222200; // 配置PA2-PA5为SSI0功能 (0x2) GPIOA-DEN | (12)|(13)|(14)|(15); // 使能数字功能 // 如果SPO1必须使能SSInClk引脚的上拉 // GPIOA-PUR | (1 2);配置QSSI控制寄存器核心禁用SSI确保SSICR1寄存器中的SSE位为0。在Legacy模式下大部分配置必须在SSE0时进行。设置主从模式配置SSICR1的MS位。0为主机1为从机。选择时钟源通过SSICC寄存器选择系统时钟或精确内部时钟等。设置时钟分频写入SSICPSR寄存器设置CPSDVSR值2-254的偶数。配置SSICR0这是最关键的一步。设置数据长度DSS、帧格式FRF、时钟极性SPO、时钟相位SPH以及时钟速率因子SCR。SCR和CPSDVSR共同决定波特率SSInClk SysClk / (CPSDVSR * (1 SCR))。通常先确定CPSDVSR一个较小的偶数如2然后计算SCR。SCR的范围是0-255。可选配置DMA如果需要使用DMA搬运数据配置μDMA通道并设置SSIDMACTL寄存器中的TXDMAE或RXDMAE位。使能QSSI最后将SSICR1寄存器中的SSE位置1模块开始工作。4.2 完整配置示例1 Mbps Freescale SPI Mode 3假设系统时钟为20MHz我们需要配置QSSI0为主机使用Freescale SPI格式Mode 3 (SPO1, SPH1)波特率1Mbps8位数据。计算分频SSInClk SysClk / (CPSDVSR * (1 SCR)) 1 MHzCPSDVSR * (1 SCR) 20 MHz / 1 MHz 20取CPSDVSR 2偶数且在2-254范围内则1 SCR 10所以SCR 9。寄存器值计算DSS 0x7(8-bit)FRF 0x0(Freescale)SPO 1SPH 1SCR 0x09SSICR0值 (0x09 8) | (1 7) | (1 6) | (0x0 4) | 0x07 0x09C0 | 0x0047 0x09C7。这里注意(17)0x0080(16)0x00400x09C0 0x0080 0x0040 0x07 0x09C7。初始化代码void SSI0_Master_Mode3_Init(void) { // 1. 使能SSI0时钟 SYSCTL-RCGCSSI | (1 0); // 2. 使能GPIOA时钟并配置引脚 (PA2, PA3, PA4, PA5) SYSCTL-RCGCGPIO | (1 0); // 简短延时等待时钟稳定 volatile uint32_t delay SYSCTL-RCGCGPIO; GPIOA-LOCK 0x4C4F434B; // 解锁针对TM4C129等型号 GPIOA-CR 0xFF; // 允许修改所有引脚 GPIOA-AFSEL | (12)|(13)|(14)|(15); GPIOA-PCTL ~0x00FF0000; GPIOA-PCTL | 0x00222200; // PA2-PA5复用为SSI0 GPIOA-DEN | (12)|(13)|(14)|(15); // Mode 3 (SPO1)必须使能时钟线上拉 GPIOA-PUR | (1 2); // 3. 禁用SSI0以进行配置 SSI0-CR1 0x00000000; // 4. 配置为主机模式 (MS0)先写CR1的低位SSE稍后使能 // SSI0-CR1 0x00000000; // 默认就是0可省略 // 5. 配置时钟预分频器 CPSDVSR 2 SSI0-CPSR 0x00000002; // 6. 配置SSICR0: SCR9, SPH1, SPO1, FRF0, DSS8-bit SSI0-CR0 0x000009C7; // 0x09C7 // 7. 使能SSI0模块 SSI0-CR1 | (1 1); // 设置SSE位为1 }4.3 高级/Bi-/Quad-SSI模式配置要点当需要使用增强模式时例如与QSPI Flash通信配置流程有额外限制和步骤关键限制在SSICR1的MODE位设置为非0即01Bi-SSI, 10Quad-SSI, 11Advanced SSI时SSICR0中的FRF必须为0Freescale且SPO和SPH必须为0。这是硬件强制要求。配置顺序手册示例展示了如何在一次通信中切换模式。基本流程是先配置SSICR1的MODE和FSSHLDFRM等位。向发送FIFO写入数据。在写入最后一个数据包或想结束帧时的数据前设置EOMEnd of Message位。如果需要切换模式例如从Advanced切到Bi-SSI需要重新配置MODE位并再次设置EOM来标记新模式的帧结束。DMA注意事项手册提到在Bi/Quad-SSI模式下当SSICLK频率高于系统时钟的1/6时使用μDMA会在每个字节传输间插入等待状态。这是因为DMA访问SRAM的仲裁开销和SSI输出吞吐量增加导致的。在设计高速QSPI通信时需要评估此性能影响。5. 常见问题排查与调试技巧即使按照手册配置在实际硬件调试中也可能遇到问题。以下是我总结的一些常见坑点和排查方法。5.1 通信完全无响应检查清单时钟与电源确认微控制器和从设备都已上电且核心时钟已正确配置并运行。用示波器测量主控的时钟输出引脚确认系统时钟是否存在。引脚复用这是最常见的问题。反复检查AFSEL、PCTL、DEN寄存器的配置确保SPI功能正确映射到了你连接的物理引脚上。一个快速验证方法是将引脚配置为GPIO输出模式手动拉高拉低用万用表或示波器测量确认硬件连接正确。模块时钟使能确认RCGCSSI和RCGCGPIO寄存器中对应位已置1。可以读取PRSSI和PRGPIO寄存器确认外设是否就绪。SSE位状态配置完成后是否将SSICR1的SSE位置1模块必须使能后才能工作。同时检查MS位是否正确设置了主从模式。5.2 能发送但接收数据全为0或全为0xFF可能原因1模式不匹配这是最高频的原因。主机的SPO/SPH模式与从机不匹配。用逻辑分析仪同时抓取SCK、MOSI、MISO、CS四根线。重点对比第一个时钟边沿和MOSI/MISO数据变化的关系。与从机数据手册的时序图逐项核对CPOL和CPHA。可能原因2从机未就绪或损坏确认从机芯片的电源、复位引脚状态正常。有些传感器需要特定的初始化序列后才能响应SPI读取。可能原因3MISO线连接或配置问题在主机端MISO是输入引脚。确保GPIO配置为输入或复用功能输入。检查硬件上MISO线是否虚焊、短路。5.3 通信速度不稳定或出错可能原因1波特率计算错误重新计算CPSDVSR和SCR。确保CPSDVSR是2-254之间的偶数。计算出的SSInClk不能超过模块和从设备支持的最大频率。过高的速率会导致建立保持时间不足。可能原因2电气问题对于高速SPI10MHz需要考虑信号完整性。检查PCB走线是否过长是否靠近干扰源。可在时钟和数据线上串联小电阻如22-33欧姆来减少振铃。可能原因3中断或DMA冲突如果使用了中断或DMA确保中断服务程序处理时间足够快或者DMA缓冲区管理正确避免发生溢出Overrun或下溢Underrun错误。检查SSI中断状态寄存器SSIRIS和SSIMIS。5.4 连续读取时数据错位或重复可能原因SSInFss时序问题针对Freescale SPI, SPH0如前文所述在SPH0的模式下从机需要SSInFss在字间有一个高电平脉冲来更新其内部数据寄存器。如果你的驱动在连续传输时没有操作SSInFss或使用了FSSHLDFRM保持功能就会导致这个问题。解决方案是在SPH0时要么在软件上控制CS引脚在每个字传输后翻转要么使用QSSI的FSSHLDFRM0脉冲模式功能注意此功能要求数据长度为8位。5.5 使用逻辑分析仪/示波器调试SPI这是最有效的调试手段。连接好探头设置好触发通常用SSInFss下降沿触发抓取一次完整的传输。看空闲电平先看SSInClk的空闲电平确定SPO设置是否正确。看第一个数据边沿找到SSInFss变低后SSInClk的第一个有效边沿如果SPO0则是上升沿SPO1则是下降沿。观察在这个边沿之前SSInTx主机发送的数据是否已经稳定如果稳定了说明SPH0如果在这个边沿之后才稳定说明SPH1。看采样边沿观察SSInRx从机返回的数据在哪个边沿发生变化在哪个边沿保持稳定。稳定的边沿就是采样边沿。与主机配置对比。看帧间间隔在连续传输时观察SSInFss信号的行为是否符合你配置的模式保持低或脉冲。通过波形分析几乎可以定位所有时序相关的配置错误。配置QSSI模块的SPI通信关键在于理解“帧格式”和“时钟模式”这两个维度的选择。帧格式Freescale vs TI决定了SSInFss信号的行为逻辑而时钟模式SPO/SPH的四种组合则决定了数据与时钟边沿的精确对齐关系。记住那个核心公式SSInClk SysClk / (CPSDVSR * (1 SCR))以及高级模式下SPO/SPH必须为0的限制。在调试时逻辑分析仪是你的最佳伙伴对照波形和数据手册没有解决不了的问题。最后别忘了那个小细节当SPO1时记得给时钟线加上拉。