飞思卡尔DSPI寄存器实战:从HCR、CTAR到FIFO,驱动SPI外设全解析

📅 2026/6/16 2:34:06
飞思卡尔DSPI寄存器实战:从HCR、CTAR到FIFO,驱动SPI外设全解析
1. 项目概述从手册到实战拆解DSPI核心寄存器如果你正在使用飞思卡尔现恩智浦的PXS20系列微控制器或者任何基于其内核的芯片并且需要驱动SPI外设那么你大概率绕不开一个模块DSPI。手册里关于DSPI_HCR、DSPI_CTAR这些寄存器的描述往往是一大堆位域定义和时序图看得人头大。但说实话把这些寄存器玩明白了你的SPI通信就稳了一大半。今天我就结合手册里那些“干巴巴”的寄存器描述聊聊在实际项目中我是怎么理解、配置并最终驯服DSPI的。这不仅仅是照着手册填几个十六进制数更是理解硬件如何工作以及如何让它高效、可靠地为你服务的过程。无论你是刚接触嵌入式的新手还是想优化现有驱动性能的老手希望这篇从寄存器出发的实战解析能给你带来一些启发。2. DSPI硬件配置寄存器DSPI_HCR你的SPI模块“身份证”手册里把DSPI_HCR定义为只读寄存器提供模块的实现细节。这话听起来很官方但翻译成工程师的语言就是这个寄存器告诉你你手里的这块芯片它的DSPI模块“硬件能力”到底怎么样。在写驱动之前先读一下这个寄存器是避免后续很多坑的第一步。2.1 核心字段解读与实战意义DSPI_HCR里几个关键字段直接决定了你驱动程序的编写策略。CTAR、TXFR、RXFR这三个字段直接告诉你硬件资源。CTAR表示实现了几个时钟与传输属性寄存器通常是0-3即最多4个。TXFR和RXFR则表示发送和接收FIFO的最大深度。比如如果RXFR读出来是4意味着接收FIFO有4个条目。这个信息至关重要队列管理知道了FIFO深度你才能合理设计数据搬移策略。是等FIFO快满了再一次性读取还是来一个读一个深度决定了你中断或DMA触发的阈值。性能预估更深的FIFO意味着你可以一次性写入/读取更多数据减少CPU频繁处理中断的开销对于高波特率通信尤其重要。DIS_RXF禁用接收FIFO。这个位虽然可写但通常我们不会主动去禁用它除非在极其特殊的调试场景下。手册说设置后FIFO表现为单条目深度这实际上是把FIFO旁路了数据直接从移位寄存器到读数据寄存器。这样做会丧失FIFO的缓冲优势任何微小的读取延迟都可能导致数据溢出。在实战中我几乎从未主动设置过此位保持FIFO启用是更稳妥的选择。CLR_TXF / CLR_RXF清除发送/接收FIFO计数器。这是两个非常关键的操作位。在哪些场景下你会用到它们通信初始化或重新开始在启动一次新的SPI传输序列前为了确保从一个干净的状态开始我会先写1清除这两个FIFO。这能避免残留的旧数据干扰本次通信。错误恢复当通信出现异常例如从设备无响应导致超时在尝试恢复通信链路时清除FIFO是标准操作流程的一部分用于重置模块的内部状态。注意手册明确提到这两个位“总是读为0”。这意味着你不能通过读取它们来确认清除操作是否完成。标准的做法是写入1后等待一个短暂的系统时钟周期通常用__NOP()或类似的空操作指令或者通过查询DSPI_SR中的TXCTR和RXCTRFIFO计数器来确认它们已归零。SMPL_PT采样点控制。这个位仅在“修改的传输格式”下使用它决定了主设备在SCK时钟沿之后多少个系统时钟周期去采样SIN数据输入线。这对于匹配不同从设备的数据建立/保持时间要求至关重要。例如某些低速传感器可能在SCK边沿后需要较长时间才能稳定输出数据这时将SMPL_PT设置为01或10延迟1-2个系统时钟再采样可以提高通信可靠性。在标准SPI模式下这个位通常保持为00在SCK驱动边沿采样。HALT暂停位。这是控制传输流程的“总开关”。设置HALT1会停止所有正在进行的和排队的传输。这在多种场景下有用动态参数更新当你需要修改DSPI_CTAR寄存器如切换波特率时必须先停止DSPIHALT1修改完成后再启动HALT0。手册警告在运行状态写入CTAR可能导致不可预知的行为。低功耗管理在进入低功耗模式前停止DSPI模块。紧急停止当检测到通信总线冲突或其他严重错误时立即暂停传输以保护硬件。2.2 配置流程与避坑指南基于以上理解一个稳健的DSPI初始化流程应该是这样的读取DSPI_HCR获取硬件FIFO深度和CTAR数量并存储到你的驱动上下文结构体中。这为后续动态配置提供依据。可选清除FIFO在初始化开始时向CLR_TXF和CLR_RXF写1确保FIFO为空。配置主控寄存器DSPI_MCR设置模块为主/从模式、是否使能DMA等全局配置这部分在提供的手册片段之外但通常先于HCR操作。配置DSPI_CTAR根据从设备要求设置波特率、时钟极性/相位等下一章详述。启动传输确保所有静态配置完成后最后将HALT位清零如果之前被停止并开始向DSPI_PUSHR写入数据。避坑心得顺序很重要一定要先HALT再改CTAR先清FIFO再开始新传输。顺序错乱是导致通信失败的常见原因。状态查询不要假设操作是瞬间完成的。在清除FIFO或改变HALT状态后通过查询DSPI_SR寄存器中的TXRXS运行状态位和TXCTR/RXCTR来确认状态变更是编写健壮驱动的好习惯。理解“只读”部分像CTAR数量、FIFO深度这些只读信息不要在代码里写死。用DSPI_HCR读出的值作为你驱动程序的配置上限这样代码在不同型号的芯片间移植性会更好。3. 时钟与传输属性寄存器DSPI_CTAR精雕细琢通信时序如果说DSPI_HCR是模块的“身份证”那么DSPI_CTAR就是它的“行为准则手册”。你与每一个SPI从设备通信的时序细节几乎都由它定义。DSPI最多支持4个CTAR寄存器CTAR0-CTAR3这意味着你可以预先定义最多4套不同的通信参数并在每次传输时通过命令字快速切换这对于需要与多个不同规格从设备通信的系统来说是一个巨大的便利。3.1 关键属性深度解析FMSZ帧大小FMSZ的值加1就是每帧传输的比特数。手册规定最小有效值为3即最小4位帧。这一点需要注意常见的8位数据传输对应FMSZ7。这个设置直接影响你写入DSPI_PUSHR和从DSPI_POPR读取的数据对齐方式。CPOL与CPHA时钟极性/相位这是SPI通信的基石决定了时钟空闲电平和数据采样的边沿。共有4种模式模式0-3。必须与从设备的数据手册要求严格匹配否则通信必然失败。一个简单的记忆方法是CPOL决定SCK空闲时的电平0低1高CPHA决定数据在哪个边沿采样0第一个边沿1第二个边沿。在“连续SCK”模式下CPHA被忽略并按1处理。LSBFELSB优先设置数据传输是从最高位MSB还是最低位LSB开始。同样这必须与从设备约定一致。大部分器件采用MSB优先。波特率生成DBR, PBR, BR这是配置的难点和重点。波特率计算公式为SCK波特率 fSYS / [PBR * (1DBR) * BR]fSYS系统时钟频率。PBR预分器2, 3, 5, 7。DBR双倍波特率使能。置1时公式中的(1DBR)等于2相当于波特率翻倍但代价是SCK的占空比可能不再是50%取决于PBR和CPHA见手册表16-7。BR分频器2到32768之间的特定值。实战计算示例假设系统时钟fSYS 50MHz目标SCK波特率为1MHz。先尝试简单分频50MHz / 1MHz 50。我们需要在PBR、DBR、BR的组合中找到乘积接近50的解。若设置PBR2DBR0 则需要BR 50 / 2 25。但查表16-9BR的可选值中没有25最接近的是16或32。调整思路设PBR5DBR1此时1DBR2则BR 50 / (5*2) 5。查表BR值中也没有5。再试设PBR5DBR0 则BR 50 / 5 10。BR表中依然没有10。最终找到一个可行解PBR5DBR0BR8。计算实际波特率50MHz / (5 * 1 * 8) 1.25MHz。这个误差25%对于许多从设备可能不可接受。更好的解PBR2DBR0BR32。实际波特率50MHz / (2*1*32) 781.25kHz误差约22%。尝试使用DBRPBR3DBR1BR8。实际波特率50MHz / (3*2*8) ≈ 1.0417MHz误差仅4.2%这是一个相当好的结果。但需注意此时SCK占空比可能不是50%需核对表16-7确认从设备是否支持。这个过程说明SPI波特率的配置往往是一个寻找最接近目标值的组合过程很难做到绝对精确。在高速通信时还需考虑PBR和BR带来的时钟抖动。延时控制PCSSCK/CSSCK, PASC/ASC, PDT/DT这三个延时PCS到SCK延时、SCK后延时、传输后延时是高级SPI主设备必须掌握的技能。它们用于满足从设备特定的时序要求例如片选有效到第一个时钟沿的建立时间tCSC、最后一个时钟沿到片选无效的保持时间tASC以及连续传输间片选不活动的时间tDT。计算公式为延时时间 (1/fSYS) * PCSSCK * CSSCK以tCSC为例。PCSSCK是预分频1,3,5,7CSSCK是倍频器2的幂次2到65536。通过灵活配置可以产生从纳秒到微秒量级的精确延时。3.2 主从模式配置差异从提供的寄存器图可以看出从模式下的CTAR配置项远少于主模式。在从模式下你通常只能设置FMSZ、CPOL、CPHA以及可选的奇偶校验SLAVE_PE,SLAVE_PP。波特率、各类延时均由外部主设备控制从设备只需被动跟随。因此在从设备初始化时只需根据主设备将要使用的通信格式配置好这几个有限的参数即可。DSPI_CTAR0和DSPI_CTAR1在从模式下可用但通常只使用CTAR0。3.3 多CTAR寄存器使用策略拥有多个CTAR寄存器的优势在于可以实现“无缝”切换。例如CTAR0配置为高速模式10MHz 8位数据用于连接高速Flash。CTAR1配置为低速模式1MHz 16位数据用于连接精度较高的ADC。CTAR2配置为极低速模式100kHz 模式3用于连接一个老式的、时序要求特殊的传感器。在向DSPI_PUSHR写入命令和数据时可以通过命令字中的CTAS字段2位指定本次传输使用哪一个CTAR0-3。这样在一次DMA传输或一个FIFO队列中混合发送不同格式的数据帧成为可能极大地提高了总线利用率和实时性。配置步骤总结确定需求仔细阅读从设备数据手册列出所有时序参数SCK模式CPOL/CPHA、最大SCK频率、数据位顺序、帧长度、以及tCSC、tASC、tDT等时间要求。计算参数根据fSYS和所需SCK频率计算PBR、DBR、BR的最佳组合。根据时间要求计算延时参数。编写配置函数将计算好的值填入对应的CTAR寄存器位域。注意在写入前确保DSPI已停止HALT1。验证如果条件允许使用逻辑分析仪抓取SPI总线波形实测SCK频率、占空比及各延时时间与计算值进行对比这是确保通信稳定的黄金标准。4. 状态、中断与FIFO操作构建高效数据流配置好通信参数只是第一步如何高效、可靠地收发数据才是驱动程序的灵魂。这离不开对状态寄存器DSPI_SR、中断请求寄存器DSPI_RSER以及FIFO推送/弹出寄存器DSPI_PUSHR/DSPI_POPR的协同操作。4.1 状态寄存器DSPI_SR通信的“仪表盘”DSPI_SR寄存器提供了模块运行的实时状态。理解每个标志位的含义和触发条件是进行轮询或中断驱动编程的基础。核心状态标志TCF(Transfer Complete Flag)单个SPI帧传输完成标志。注意手册特别提醒在传输正在进行时不建议写入此位。因为串行链路侧的更新优先级高于寄存器访问。在实践中我们通常只读取它并通过写1来清除它。TXRXS运行状态位。反映DSPI是处于运行RUNNING还是停止STOPPED状态。检查此位可以确认HALT位的操作是否生效。EOQF(End of Queue Flag)队列结束标志。当传输的命令字中EOQ位被置1且该帧传输完成时此标志置位。同时TXRXS会自动清零停止传输。这是实现精确控制传输帧数的关键机制。TFFF(Transmit FIFO Fill Flag) RFDF(Receive FIFO Drain Flag)这是最常用的两个标志。TFFF1表示发送FIFO未满可以继续写入数据。RFDF1表示接收FIFO非空有数据可以读取。它们是驱动中断或DMA请求的核心。TFUF(Transmit FIFO Underflow) RFOF(Receive FIFO Overflow)下溢和上溢标志属于错误状态。在从模式下如果TX FIFO为空时主设备发起传输会发生TFUF。如果RX FIFO已满时又收到新数据会发生RFOF。良好的驱动应能处理或避免这些情况。SPEF(SPI Parity Error Flag)奇偶校验错误标志仅特定版本支持。如果使能了奇偶校验此标志在收到校验错误的帧时置位。TXCTR, TXNXTPTR, RXCTR, POPNXTPTR这些字段提供了FIFO内部的详细计数器和指针信息在深度调试FIFO操作异常如数据顺序错乱时非常有用。4.2 中断与DMA请求使能寄存器DSPI_RSER解放CPUDSPI_RSER允许你将特定的状态标志TFFF,RFDF,TCF,EOQF,TFUF,RFOF,SPEF配置为触发中断或DMA请求。这是实现高效、非阻塞数据传输的关键。配置策略轮询模式不使能任何*_RE位。程序循环查询TFFF和RFDF标志进行读写。简单但CPU占用率高。中断模式使能TFFF_RE和RFDF_RE并将TFFF_DIRS和RFDF_DIRS设为0选择中断。当FIFO可写或可读时触发中断服务程序ISR进行数据搬移。适合中等数据量、低延迟的场景。DMA模式使能TFFF_RE和RFDF_RE并将TFFF_DIRS和RFDF_DIRS设为1选择DMA。结合DMA控制器可以在无需CPU干预的情况下自动将内存中的数据搬移到DSPI_PUSHR或将DSPI_POPR的数据搬移到内存。这是处理大批量、高速SPI通信如读写SPI Flash、与高速ADC/DAC交互的首选方案能极大降低CPU负载。典型的中断/DMA驱动流程初始化时在DSPI_RSER中使能TFFF_RE和RFDF_RE并选择中断或DMA方向。启动传输前先向TX FIFO写入若干个数据例如填满一半深度以启动传输引擎。当TX FIFO有空位TFFF置位时触发中断/DMA在ISR或DMA传输完成回调中补充数据。当RX FIFO有数据RFDF置位时触发中断/DMA在ISR或DMA传输完成回调中读取数据。利用EOQ机制在最后一个数据帧的命令字中设置EOQ1传输完成后会触发EOQF中断通知CPU/DMA本次传输序列全部结束。4.3 数据推送与弹出寄存器DSPI_PUSHR/POPR数据交换的窗口DSPI_PUSHR(Master Mode)在主机模式下这是一个32位寄存器高16位是命令CONT,CTAS,EOQ,CTCNT,PCS[7:0]等低16位是数据TXDATA。一次32位写入操作会将命令和数据作为一个整体压入TX FIFO。命令字中的CTAS选择了本次传输使用的CTAR寄存器PCS选择了激活哪个片选信号EOQ标记队列结束CONT控制片选是否在帧间保持有效。DSPI_PUSHR(Slave Mode)在从机模式下整个32位寄存器都用作TXDATA支持最大32位帧长。从设备在此准备好要发送的数据等待主设备来读取。DSPI_POPR读取此寄存器会从RX FIFO中弹出一个接收到的数据。注意读取操作本身就会更新FIFO的弹出指针和RXCTR。在中断或DMA处理中通常需要连续读取RXCTR指示的多个数据。避坑指南对齐问题当帧大小不是16或32位时需要关注数据在TXDATA字段中的对齐方式通常是右对齐或左对齐以及在RXDATA中的位置。FIFO写满在向PUSHR写入前务必检查TFFF标志或TXCTR计数器避免写入已满的FIFO导致数据丢失。虽然有些硬件可能忽略此次写入但这不是可靠的行为。EOQ的使用EOQ位需要设置在最后一个有效数据帧的命令字中。传输完该帧后DSPI会自动停止TXRXS清零并置位EOQF。这对于控制多帧传输的精确结束点非常有用。从机模式下的TX FIFO管理在从机模式下务必确保在主机发起传输前TX FIFO中已有待发送的数据否则会发生TFUF下溢。通常需要在初始化或每次应答后提前将数据写入从机的TX FIFO。5. 实战配置案例与调试技巧让我们通过一个具体的场景将上述所有知识点串联起来使用DSPI主模式以中断方式循环读取一个SPI接口的温湿度传感器假设为SHT3x使用模式0CPOL0CPHA0MSB优先8位帧最高时钟1MHz。5.1 初始化与配置代码框架伪代码风格// 1. 使能DSPI模块时钟此步骤依赖具体MCU的时钟控制系统 CLOCK_EnableClock(kCLOCK_Dspi0); // 2. 获取硬件配置信息 uint32_t hcr DSPI0-HCR; uint8_t tx_fifo_depth ((hcr 8) 0x1F) 1; // 提取TXFR字段 uint8_t rx_fifo_depth ((hcr 16) 0x1F) 1; // 提取RXFR字段 uint8_t ctar_count (hcr 0x07) 1; // 提取CTAR字段 // 存储这些信息到驱动上下文 // 3. 软件复位并停止DSPI DSPI0-MCR | DSPI_MCR_MDIS_MASK | DSPI_MCR_HALT_MASK; // 先进入模块禁用模式可能需按手册顺序 DSPI0-MCR DSPI_MCR_HALT_MASK | DSPI_MCR_MSTR_MASK; // 保持停止设置为主模式 // 清除FIFO DSPI0-HCR | DSPI_HCR_CLR_TXF_MASK | DSPI_HCR_CLR_RXF_MASK; // 短暂延时或等待SR中的计数器归零 while((DSPI0-SR (DSPI_SR_TXCTR_MASK | DSPI_SR_RXCTR_MASK)) ! 0); // 4. 配置CTAR0 // 假设系统时钟fSYS48MHz目标SCK1MHz。 // 计算48MHz / 1MHz 48。 // 尝试组合PBR2, DBR0, 则需要BR24。查表无24取BR32得0.75MHz。 // 尝试组合PBR3, DBR1, 则分母为3*26需要BR8。查表有8。 // 实际波特率 48MHz / (3 * 2 * 8) 1.0MHz。完美。 // CPOL0, CPHA0, FMSZ7 (8 bits), LSBFE0 (MSB first). // 延时参数根据传感器手册要求设置假设使用默认最小值。 uint32_t ctar0_config 0; ctar0_config | DSPI_CTAR0_FMSZ(7); // 8-bit frame ctar0_config | DSPI_CTAR0_CPOL(0) | DSPI_CTAR0_CPHA(0); // Mode 0 ctar0_config | DSPI_CTAR0_LSBFE(0); // MSB first ctar0_config | DSPI_CTAR0_PBR(1) | DSPI_CTAR0_BR(3); // PBR3 (b01), BR8 (b0011) ctar0_config | DSPI_CTAR0_DBR(1); // Double baud rate enable // PCS to SCK delay, After SCK delay, Delay after transfer 使用默认或计算值 ctar0_config | DSPI_CTAR0_CSSCK(0) | DSPI_CTAR0_ASC(0) | DSPI_CTAR0_DT(0); ctar0_config | DSPI_CTAR0_PCSSCK(0) | DSPI_CTAR0_PASC(0) | DSPI_CTAR0_PDT(0); DSPI0-CTAR[0] ctar0_config; // 5. 配置中断使能TFFF和RFDF中断选择中断非DMA DSPI0-RSER DSPI_RSER_TFFF_RE_MASK | DSPI_RSER_RFDF_RE_MASK; // 在NVIC中使能DSPI中断 EnableIRQ(DSPI0_IRQn); // 6. 准备发送数据读取温度命令例如0x2400 g_tx_buffer[0] 0x2400; // 假设命令字CTAS0 (使用CTAR0), PCS0 (选择传感器片选) // 将数据写入TX FIFO首次手动写入启动传输 DSPI0-PUSHR DSPI_PUSHR_CONT(0) | DSPI_PUSHR_CTAS(0) | DSPI_PUSHR_PCS(1) | DSPI_PUSHR_TXDATA(g_tx_buffer[0]); // 7. 启动传输清除HALT位 DSPI0-MCR ~DSPI_MCR_HALT_MASK;5.2 中断服务程序ISR处理逻辑void DSPI0_IRQHandler(void) { uint32_t sr DSPI0-SR; // 读取状态寄存器 // 处理发送FIFO未满中断 if(sr DSPI_SR_TFFF_MASK) { DSPI0-SR | DSPI_SR_TFFF_MASK; // 写1清除标志 // 检查是否还有数据要发送 if(g_tx_index g_tx_length) { uint32_t command 0; if(g_tx_index g_tx_length - 1) { command | DSPI_PUSHR_EOQ_MASK; // 最后一帧设置EOQ } command | DSPI_PUSHR_CTAS(0) | DSPI_PUSHR_PCS(1) | DSPI_PUSHR_TXDATA(g_tx_buffer[g_tx_index]); DSPI0-PUSHR command; g_tx_index; } } // 处理接收FIFO非空中断 if(sr DSPI_SR_RFDF_MASK) { DSPI0-SR | DSPI_SR_RFDF_MASK; // 写1清除标志 // 读取所有可用的接收数据 while(DSPI0-SR DSPI_SR_RXCTR_MASK) { g_rx_buffer[g_rx_index] DSPI0-POPR 0xFFFF; // 读取16位数据 } // 检查是否收到EOQF传输结束 if(sr DSPI_SR_EOQF_MASK) { DSPI0-SR | DSPI_SR_EOQF_MASK; // 清除结束标志 // 本次传输序列完成处理数据g_rx_buffer process_sensor_data(g_rx_buffer); // 准备下一次读取... g_tx_index 0; g_rx_index 0; // 重新填充第一个数据并启动如果需要连续读取 } } // 处理错误中断可选 if(sr (DSPI_SR_TFUF_MASK | DSPI_SR_RFOF_MASK)) { // 记录错误清除FIFO可能需要进行错误恢复 DSPI0-HCR | DSPI_HCR_CLR_TXF_MASK | DSPI_HCR_CLR_RXF_MASK; DSPI0-SR | DSPI_SR_TFUF_MASK | DSPI_SR_RFOF_MASK; // ... 错误处理逻辑 } }5.3 常见问题排查实录问题完全没有SCK时钟输出。检查1确认DSPI_MCR[MSTR]位已设置为1主模式。检查2确认DSPI_MCR[HALT]位已清零。这是最容易被忽略的一点检查3确认对应SPI引脚SCK MOSI MISO PCS的复用功能已正确配置并且方向输入/输出设置正确。检查4TX FIFO是否为空只有TX FIFO中有待发送的数据DSPI才会启动传输并产生SCK。确保在启动HALT清零前或之后至少向PUSHR写入了一个数据。问题有SCK时钟但MOSI上没有数据或数据全为0/1。检查1确认写入PUSHR的TXDATA字段值是否正确。调试时可以先尝试写入一个固定的测试模式如0xAA或0x55。检查2确认CPOL和CPHA设置与逻辑分析仪捕获的波形是否匹配。错误的模式会导致数据采样错位。检查3检查LSBFE位确认数据传输顺序是否符合预期。问题能发送数据但接收到的数据总是0xFF或0x00。检查1确认从设备已正确上电且片选信号PCS已正确触发低电平有效或高电平有效取决于从设备。检查2检查MISO引脚连接和配置。用逻辑分析仪同时抓取MOSI和MISO看从设备是否在正确的时钟边沿回送了数据。检查3确认DSPI_CTAR中的帧大小FMSZ设置与从设备返回的数据长度一致。检查4读取DSPI_POPR的时机是否正确是否在RFDF置位或RXCTR0后才去读取过早读取可能得到旧数据或无效数据。问题高波特率下通信不稳定出现偶发性错误。检查1检查SCK波特率计算是否准确实际测量频率是否与预期相符。过高的波特率可能接近或超过从设备或PCB布线的极限。检查2检查PCSSCK、PASC、PDT等延时设置是否满足从设备的最小时序要求。在高速下建立/保持时间不足是常见问题。适当增加这些延时。检查3检查电源噪声和信号完整性。高速SPI信号对PCB走线敏感确保时钟和数据线长度匹配远离噪声源并考虑是否需要串联端接电阻。检查4是否使能了FIFO在高速传输中使用FIFO并结合DMA是减少CPU中断延迟、避免数据溢出/下溢的关键。问题使用多个CTAR时切换后通信异常。检查确保在修改DSPI_CTARx寄存器x1,2,3的内容之前DSPI模块已处于停止状态HALT1。这是手册明确强调的禁忌。修改完成后再清除HALT位。调试SPI一把逻辑分析仪是必不可少的。它能直观地展示SCK、MOSI、MISO、PCS的波形让你清晰地看到时钟极性、相位、数据位、帧间隔是否完全符合预期。将抓取的波形与数据手册的时序图逐一比对是定位硬件配置问题最快最直接的方法。寄存器配置是冰冷的数字但逻辑分析仪上的波形才是硬件真正“听懂”了你指令的证明。