1. 项目概述与核心价值在嵌入式系统开发中串行通信是连接微控制器与传感器、存储器、显示模块乃至其他处理器的“血管”。SPI和SCI通常就是我们熟知的UART是其中最常用、最基础的两种协议。很多工程师能调通基本的收发但一旦遇到复杂的多设备组网、调试时的断点仿真干扰或者需要节省宝贵的GPIO引脚时往往就卡在了寄存器配置的细节上。我见过不少项目通信时好时坏最后发现是某个控制位的理解有偏差。今天我们就以TI的TMS320F2803x系列DSP为例抛开那些笼统的概念直接深入到最核心的寄存器层面把SPI的优先级控制寄存器SPIPRI和SCI的多处理器通信模式掰开揉碎了讲清楚。这不仅是为了配置几个寄存器更是为了理解协议设计者的意图让你在下次遇到通信异常时能快速定位到是时序问题、模式问题还是中断管理问题。2. SPI优先级控制寄存器SPIPRI深度解析SPI协议以其简单、全双工、高速的特性深受欢迎但在复杂的嵌入式系统中尤其是涉及仿真调试和多主机场景时简单的收发使能配置就不够用了。TMS320F2803x的SPIPRI寄存器偏移地址Fh正是为应对这些高级场景而设计的。它虽然只有16位且大部分位是保留的但剩下的几个控制位却个个关键直接关系到系统调试的便利性和硬件连接的灵活性。2.1 仿真控制位FREE与SOFT让调试不再“断”了通信在嵌入式开发中我们极度依赖仿真器进行单步调试和断点调试。但想象一下这个场景你的SPI正在以10Mbps的速率向一个ADC连续发送采集命令此时你在代码中设了一个断点。CPU暂停了那SPI外设会怎样如果它也跟着戛然而止时钟停在半高半低数据线停在某个不确定的状态很可能会导致从设备状态机混乱甚至锁死。SPIPRI寄存器中的FREE和SOFT位就是为了优雅地处理这种“仿真挂起”状态。FREE位位4是总开关。当FREE 1时SPI模块进入“自由运行”模式。这意味着无论仿真器是否触发断点、CPU是否暂停SPI模块都会继续我行我素地完成当前的传输任务完全不受影响。这对于那些不能中断的实时数据流比如音频流、电机控制反馈环内的通信至关重要。然而在大多数调试场景下我们希望在断点处能观察系统状态包括通信状态如果SPI一直跑数据刷过去了反而不好分析。这时就需要设置FREE 0。当FREE 0时SPI的行为则由SOFT位位5精细控制SOFT 0停止模式这是最需要理解的一种模式。当仿真挂起如遇到断点时传输并非立即停止。如果挂起发生在一次传输的两个SPI时钟脉冲之间那么传输会立即暂停。但如果挂起发生在一个数据位的传输过程中SPI会坚持把当前正在移出的这个位发完然后在下一个时钟脉冲前暂停。更关键的是一旦仿真恢复断点继续SPI会从刚才暂停的地方接着传输剩余的数据位。手册里那个“3 out of 8 bits”的例子非常经典假设正在传一个8位数据刚传完3位时遇到断点SPI会暂停继续运行后它会从第4位开始传并且仍然会传满8个位即把剩下的5位传完。这保证了数据帧的完整性避免产生残缺帧误导从设备。SOFT 1完成模式行为相对简单。如果挂起发生在一次传输开始之前第一个SPICLK脉冲之前则整个传输取消。如果挂起发生在传输开始之后则SPI会坚持把当前移位寄存器SPIDAT和发送缓冲区TXBUF或TX FIFO里的所有数据全部发送完毕后再停止。这确保了至少当前缓存的数据包是完整的。实操心得在调试SPI驱动时我习惯先将FREE和SOFT都设为0。这样在断点处SPI会暂停我可以安全地检查发送/接收缓冲区的值、时钟相位等状态。如果调试的代码段与SPI通信强相关需要观察连续数据流我会临时将FREE设为1。切记在产品发布的代码中如果不涉及特殊调试需求通常将FREE位保持默认值0即可SOFT位根据是否需要保证帧完整性来选择。2.2 三线模式TRIWIRE节省引脚的艺术标准SPI需要四根线SCLK时钟、MOSI主出从入、MISO主入从出和SS片选。当你的MCU引脚资源紧张或者只需要与一个单向传输的设备通信时TRIWIRE位位0就派上用场了。当TRIWIRE 1时SPI启用三线模式。这里的“三线”指的是SCLK、片选和一根双向数据线。主模式MASTER/SLAVE 1SPISIMO主出从入引脚变为SPIMOMI引脚承担起双向数据传输的任务。主设备通过这根线既发送数据也接收数据实际上在时钟驱动下发送和接收是同时进行的只是方向固定。而原来的SPISOMI主入从出引脚则被释放可以配置为普通GPIO使用。从模式MASTER/SLAVE 0SPISOMI主入从出引脚变为SPISISO引脚作为从设备的双向数据线。原来的SPISIMO引脚被释放为GPIO。注意事项三线模式本质上是半双工通信吗并不是。它依然是全双工因为数据在时钟的上升沿或下降沿同时被采样和输出只是物理上共用了一根数据线。这要求主从设备对数据线的驱动要有严格的时序控制避免冲突。通常主设备在时钟边沿输出数据从设备在相反的边沿输出数据通过时钟相位和极性的巧妙配置来实现。启用此模式前务必确认你的从设备也支持三线SPI模式。2.3 片选信号极性控制STEINV在多从设备的SPI系统中主设备通过片选信号SPISTE来选择与哪个从设备通信。通常片选信号是低电平有效。但有些特殊的应用场景例如需要接收左右声道数字音频数据时可能会需要高电平有效的片选信号。STEINV位位1就是用来控制SPISTE信号的极性。STEINV 0片选信号低电平有效默认。STEINV 1片选信号高电平有效。重要提示手册明确指出此位仅在从模式下有效。当SPI配置为主模式时写入此位是无效的。这是因为片选信号通常由主设备产生并控制其极性在主设备端更多是由GPIO输出初始化时决定的而非SPI模块本身。在从模式下这个位决定了从设备在何种电平下被“选中”并响应SPI时钟和数据。3. SCI多处理器通信模式精讲SCIUART的异步通信虽然简单但在构建多节点网络时如何让数据准确地送达目标节点而不是广播给所有节点是个关键问题。TMS320F2803x的SCI模块提供了两种高效的多处理器通信协议空闲线模式和地址位模式。这两种模式的核心思想都是“唤醒-寻址-通信”。3.1 多处理器通信的核心机制无论是哪种模式其通信流程都遵循一个基本范式睡眠SLEEP所有从节点Listener的SCI初始化后都会将SCICTL1寄存器中的SLEEP位位2置1。在此状态下从节点的SCI接收器虽然仍在工作但收到数据帧时不会置位RXRDY标志也不会产生接收中断除非检测到特定的唤醒条件。这避免了所有从节点被每一个数据字节都中断。唤醒与寻址主节点Talker要发送数据块时先发送一个特殊的地址。这个地址帧会“唤醒”总线上的所有从节点使它们都能接收到这个地址字节并与自己预设的地址进行比较。选择性响应只有地址匹配的那个从节点才会在软件中断服务程序中清除自己的SLEEP位。此后该节点将对后续的数据帧正常响应产生中断读取数据。地址不匹配的从节点其SLEEP位保持为1继续忽略后续的数据帧直到下一个地址帧的到来。数据块传输主节点在发送地址帧后紧接着发送数据帧。只有被寻址的从节点会接收这些数据。3.2 空闲线多处理器模式Idle-Line Mode这种模式通过帧间的空闲时间Idle Time来区分数据块。它规定如果一个帧结束停止位后通信线上保持10个位时间以上的高电平空闲状态那么下一个帧就被认为是新数据块的开始即地址帧。操作流程主设备在发送完上一个数据块后有意让总线空闲超过10个位时间。主设备发送地址帧。所有从设备检测到长空闲后的第一个帧将其识别为地址帧并产生中断。从设备在中断服务程序中比较地址。匹配者清除SLEEP位准备接收数据不匹配者保持SLEEP1。主设备紧接着发送数据帧。数据帧之间的间隔小于10个位时间因此不会被误认为是新地址帧。如何产生精确的11位空闲时间手动延时计算位时间比较麻烦。SCI提供了一个硬件机制TXWAKE标志位SCICTL1.3。主设备在发送地址帧前先将TXWAKE位写1。然后向SCITXBUF寄存器写入一个“无关紧要”的数据字Dummy Data。注意这个数据字本身不会被发送出去。当这个“唤醒”请求被处理时硬件会自动在总线上插入一个恰好11个位时间的空闲周期。空闲周期结束后主设备再向SCITXBUF写入真正的目标地址开始通信。避坑指南空闲线模式非常适合数据块较大例如超过10个字节的通信。因为它的开销就是块之间的一个长空闲。但如果你的数据块非常小且发送频繁每个块之间都要等待10多个位时间的空闲会导致总线利用率显著下降。此时应考虑地址位模式。3.3 地址位多处理器模式Address-Bit Mode这种模式在每个数据帧的格式中增加了一个额外的“地址位”用来显式标识该帧是地址帧还是数据帧。地址位置1表示该帧是地址帧置0表示是数据帧。这样数据块之间无需长空闲间隔可以连续发送。操作流程主设备要发送地址帧时先将TXWAKE位置1然后向SCITXBUF写入地址值。硬件发送该帧时会自动将地址位置1。所有从设备检测到地址位为1的帧将其作为地址帧处理并产生中断。从设备比较地址匹配者清除SLEEP位。主设备发送后续数据帧前先将TXWAKE位清零再写入数据。这样发出的数据帧其地址位为0。只有SLEEP位已清除的目标从设备会响应这些数据帧。地址位位于帧格式中的哪里它紧跟在最后一个数据位之后在可选的奇偶校验位和停止位之前。所以一个典型的8位数据、无校验、1位停止位的帧在地址位模式下会变成1位起始位 8位数据位 1位地址位 1位停止位共11位。经验之谈地址位模式是“空间换时间”的典型。它每帧都多了一个位对于长数据块来说效率不如空闲线模式。但对于短数据块、频繁通信的场景它的效率更高因为省去了块间的等待时间。手册中的建议很中肯数据帧多于11字节用空闲线模式少于等于11字节用地址位模式。这个“11字节”的临界点就是权衡了额外地址位带来的开销与长空闲时间开销后的经验值。4. SCI寄存器配置与通信格式详解要实现可靠的SCI通信除了模式选择对数据格式、波特率、中断的精确配置是基础。这些配置都通过一组寄存器完成。4.1 可编程数据格式SCICCR寄存器SCI的帧格式非常灵活通过SCICCR通信控制寄存器进行配置SCICHAR位2-0选择数据字符长度1到8位可选。通常选择8位0b111。PARITYENA位5奇偶校验使能位。1为使能0为禁用。在干扰不大的环境中可以禁用以简化处理。PARITY位6当校验使能时此位选择奇校验0或偶校验1。奇偶校验是一种简单的检错机制但无法纠错。STOPBITS位7停止位数量。0为1个停止位1为2个停止位。大多数设备使用1个停止位。ADDR/IDLE MODE位3这是选择多处理器模式的关键位。0为空闲线模式1为地址位模式。4.2 波特率计算SCI的波特率由低速外设时钟LSPCLK和一个16位的波特率选择寄存器SCI Baud Select Registers 通常是SCIHBAUD和SCILBAUD两个8位寄存器组成共同决定。计算公式为SCI Baud Rate LSPCLK / [(BRR 1) * 8]其中BRR就是波特率选择寄存器SCIBAUD中16位的值。例如当LSPCLK 100 MHz 目标波特率为9600时BRR LSPCLK / (SCI Baud Rate * 8) - 1 100,000,000 / (9600 * 8) - 1 ≈ 1301.04取整后BRR 13010x515。代入公式验证实际波特率100,000,000 / [(13011)*8] ≈ 9600.96误差约0.01%在可接受范围内。配置要点务必根据系统实际的LSPCLK频率计算BRR值。LSPCLK通常由系统时钟SYSCLK分频得到需要在系统初始化时确认其值。波特率误差应控制在2%以内最好在1%以下以保证长时间通信的稳定性。4.3 中断机制与FIFO操作SCI提供了丰富的中断源来高效处理通信事件而非单纯依赖轮询。基本中断控制发送中断由TXRDY标志SCICTL2.7触发。当发送缓冲寄存器SCITXBUF为空可以接收新数据时此位置1。如果TX INT ENA位SCICTL2.0已使能则会产生发送中断。接收中断由RXRDY标志SCIRXST.6触发。当接收缓冲寄存器SCIRXBUF收到新数据时此位置1。如果RX/BK INT ENA位SCICTL2.1已使能则会产生接收中断。接收错误中断帧错误FE、溢出错误OE、奇偶校验错误PE和间隔检测BRKDT这四个错误标志位任意一个置位都会导致RX ERROR标志SCIRXST.7置位。如果RX ERR INT ENA位SCICTL1.6已使能也会触发接收中断与RXRDY共用中断线。FIFO增强功能为了减少CPU频繁处理中断的开销C28x的SCI模块支持4级深度的硬件FIFO。使能FIFO通过设置SCIFFTX寄存器中的SCIFFEN位为1来使能FIFO模式。中断触发级别这是FIFO模式最实用的特性。你可以设置FIFO收到多少数据后才产生中断。接收FIFO通过RXFFIL位SCIFFRX.4-0设置触发级别。例如设置为4则只有当RX FIFO中存有4个或更多字符时才触发RXINT中断。这避免了每收到一个字节就中断一次CPU。发送FIFO通过TXFFIL位SCIFFTX.4-0设置触发级别。例如设置为0当TX FIFO完全空即最后一个字从FIFO移入发送移位器TXSHF时才触发TXINT中断通知CPU可以填充下一批数据。可编程发送延迟SCIFFCT寄存器SCIFFCT的低8位FFTXDLY7-0可以设置每个字符从TX FIFO加载到TXSHF之间的延迟以波特率时钟周期为单位。设置为0可实现背靠背连续发送设置一个值可以人为降低发送速率以兼容响应速度慢的旧设备无需CPU干预延时。5. 实战配置与常见问题排查理解了原理最终要落到代码上。下面以配置一个使用地址位多处理器模式、波特率115200、8位数据、无校验、1位停止位的SCI从机为例并分享几个踩过的坑。5.1 寄存器初始化代码示例C语言片段// 假设 LSPCLK 100MHz 目标波特率 115200 // 计算 BRR 100,000,000 / (115200 * 8) - 1 ≈ 107.5 // 取整 BRR 108 (0x6C) #define SCI_BRR 108 void SCI_Init(void) { // 1. 使能SCI模块时钟取决于具体系统时钟配置 SysCtrlRegs.PCLKCR7.bit.SCI_A 1; // 使能SCI-A外设时钟 DELAY_US(10); // 短暂延时等待时钟稳定 // 2. 配置GPIO复用为SCI引脚以GPIO28/29为例 EALLOW; GpioCtrlRegs.GPAMUX2.bit.GPIO28 1; // GPIO28 复用为 SCIRXDA GpioCtrlRegs.GPAMUX2.bit.GPIO29 1; // GPIO29 复用为 SCITXDA EDIS; // 3. 软件复位SCI模块 SciaRegs.SCICTL1.bit.SWRESET 0; // 先置0 DELAY_US(10); SciaRegs.SCICTL1.bit.SWRESET 1; // 再置1结束复位 // 4. 配置通信格式SCICCR SciaRegs.SCICCR.bit.SCICHAR 7; // 8位数据位 (71) SciaRegs.SCICCR.bit.PARITYENA 0; // 禁止奇偶校验 SciaRegs.SCICCR.bit.PARITY 0; // 奇校验未使能此位无效 SciaRegs.SCICCR.bit.STOPBITS 0; // 1位停止位 SciaRegs.SCICCR.bit.ADDRIDLE_MODE 1; // 1地址位多处理器模式 // 5. 配置波特率 SciaRegs.SCIHBAUD (SCI_BRR 8) 0xFF; // 高位字节 SciaRegs.SCILBAUD SCI_BRR 0xFF; // 低位字节 // 6. 配置控制寄存器1SCICTL1 SciaRegs.SCICTL1.bit.RXENA 1; // 使能接收器 SciaRegs.SCICTL1.bit.TXENA 1; // 使能发送器 SciaRegs.SCICTL1.bit.SLEEP 1; // 初始置于睡眠模式多处理器 SciaRegs.SCICTL1.bit.TXWAKE 0; // 发送唤醒标志初始清零 // RX ERR INT ENA 根据需求使能此处先关闭 SciaRegs.SCICTL1.bit.RXERRINTENA 0; // 7. 配置控制寄存器2SCICTL2和中断此处不使能中断用查询方式示例 SciaRegs.SCICTL2.bit.TXINTENA 0; // 禁止发送中断查询TXRDY SciaRegs.SCICTL2.bit.RXBKINTENA 0; // 禁止接收/间隔中断查询RXRDY // 8. 使能SCI结束初始化 SciaRegs.SCICTL1.bit.SWRESET 1; // 确保SWRESET1 }5.2 常见问题排查速查表现象可能原因排查步骤与解决方案完全无法收发数据1. GPIO复用未配置。2. 外设时钟未使能。3. SWRESET位未置1。1. 检查GPIO MUX寄存器配置确认引脚功能已切换到SCI。2. 检查PCLKCRx寄存器确认SCI模块时钟已开启。3.最关键一步确认SCICTL1寄存器的SWRESET位已置1。该位为0时SCI模块处于复位状态所有配置无效。能发送但不能接收或反之1. 发送器或接收器未使能。2. 引脚连接错误RX/TX交叉。3. 从设备的SLEEP位未正确管理。1. 检查SCICTL1的TXENA和RXENA位。2. 用示波器或逻辑分析仪检查SCIRXD和SCITXD引脚波形确认主从设备TX接对方RX。3. 在多处理器模式下确认从机在地址匹配后清除了SLEEP位。接收数据错误乱码1. 波特率不匹配。2. 数据格式数据位、停止位、校验位不匹配。3. 电气电平不匹配如3.3V与5V。1.双盲检查主从双方的波特率计算值和实际LSPCLK频率。误差需在2%内。2. 逐项核对SCICCR寄存器的配置SCICHAR, STOPBITS, PARITYENA。3. 检查电平转换电路或使用兼容电平的器件。多处理器模式下从机收不到数据1. 主设备未正确发送地址帧TXWAKE使用错误。2. 从机SLEEP位一直为1。3. 地址比较逻辑有误。1. 主设备发送数据前确认TXWAKE位和地址位的操作顺序正确先置TXWAKE写地址后清零TXWAKE写数据。2. 从机在接收中断中检查收到的第一个字节地址比较成功后务必手动清除SLEEP位。3. 使用逻辑分析仪捕获总线波形确认地址帧的格式空闲线或地址位符合预期。FIFO模式下中断不触发1. FIFO未使能SCIFFEN。2. 中断触发级别TXFFIL/RXFFIL设置不当。3. PIE中断向量表未配置或使能。1. 确认SCIFFTX寄存器的SCIFFEN位已置1。2. 例如若RXFFIL设为4则需收到4个字节才会触发中断。检查FIFO状态位TXFFST/RXFFST。3. 检查PIE相关寄存器的配置确认SCI中断已正确映射并开启。仿真时SPI通信异常FREE和SOFT位配置不当。根据调试需求配置SPIPRI寄存器的FREE和SOFT位。若需在断点处观察通信状态设置FREE0, SOFT0。若通信不能中断设置FREE1。5.3 调试心得逻辑分析仪是你的最佳伙伴无论是SPI的时钟相位问题还是SCI多处理器模式的地址帧识别问题光靠看代码和打印信息很难定位。一个支持协议解码的逻辑分析仪如Saleae能极大提升调试效率。连接好线抓取SCLK、MOSI、MISO、STE对于SPI或TX、RX对于SCI的波形解码器能直观地显示出每个帧的数据、地址位、起始/停止位。你可以清晰地看到SPI的时钟极性和相位CPOL, CPHA是否与从设备匹配。在空闲线模式下帧间的空闲时间是否真的超过了10个位时间。在地址位模式下地址帧的“地址位”是否为1数据帧的是否为0。数据内容是否正确有无错位。纸上得来终觉浅绝知此事要躬行。寄存器配置表看再多遍也不如动手写一段初始化代码抓一次波形来得深刻。希望这篇结合了手册核心内容和实战经验的解析能帮你下次面对SPI和SCI时多一份从容少一个通宵。
深入解析TMS320F2803x SPI/SCI寄存器:从调试模式到多处理器通信实战
1. 项目概述与核心价值在嵌入式系统开发中串行通信是连接微控制器与传感器、存储器、显示模块乃至其他处理器的“血管”。SPI和SCI通常就是我们熟知的UART是其中最常用、最基础的两种协议。很多工程师能调通基本的收发但一旦遇到复杂的多设备组网、调试时的断点仿真干扰或者需要节省宝贵的GPIO引脚时往往就卡在了寄存器配置的细节上。我见过不少项目通信时好时坏最后发现是某个控制位的理解有偏差。今天我们就以TI的TMS320F2803x系列DSP为例抛开那些笼统的概念直接深入到最核心的寄存器层面把SPI的优先级控制寄存器SPIPRI和SCI的多处理器通信模式掰开揉碎了讲清楚。这不仅是为了配置几个寄存器更是为了理解协议设计者的意图让你在下次遇到通信异常时能快速定位到是时序问题、模式问题还是中断管理问题。2. SPI优先级控制寄存器SPIPRI深度解析SPI协议以其简单、全双工、高速的特性深受欢迎但在复杂的嵌入式系统中尤其是涉及仿真调试和多主机场景时简单的收发使能配置就不够用了。TMS320F2803x的SPIPRI寄存器偏移地址Fh正是为应对这些高级场景而设计的。它虽然只有16位且大部分位是保留的但剩下的几个控制位却个个关键直接关系到系统调试的便利性和硬件连接的灵活性。2.1 仿真控制位FREE与SOFT让调试不再“断”了通信在嵌入式开发中我们极度依赖仿真器进行单步调试和断点调试。但想象一下这个场景你的SPI正在以10Mbps的速率向一个ADC连续发送采集命令此时你在代码中设了一个断点。CPU暂停了那SPI外设会怎样如果它也跟着戛然而止时钟停在半高半低数据线停在某个不确定的状态很可能会导致从设备状态机混乱甚至锁死。SPIPRI寄存器中的FREE和SOFT位就是为了优雅地处理这种“仿真挂起”状态。FREE位位4是总开关。当FREE 1时SPI模块进入“自由运行”模式。这意味着无论仿真器是否触发断点、CPU是否暂停SPI模块都会继续我行我素地完成当前的传输任务完全不受影响。这对于那些不能中断的实时数据流比如音频流、电机控制反馈环内的通信至关重要。然而在大多数调试场景下我们希望在断点处能观察系统状态包括通信状态如果SPI一直跑数据刷过去了反而不好分析。这时就需要设置FREE 0。当FREE 0时SPI的行为则由SOFT位位5精细控制SOFT 0停止模式这是最需要理解的一种模式。当仿真挂起如遇到断点时传输并非立即停止。如果挂起发生在一次传输的两个SPI时钟脉冲之间那么传输会立即暂停。但如果挂起发生在一个数据位的传输过程中SPI会坚持把当前正在移出的这个位发完然后在下一个时钟脉冲前暂停。更关键的是一旦仿真恢复断点继续SPI会从刚才暂停的地方接着传输剩余的数据位。手册里那个“3 out of 8 bits”的例子非常经典假设正在传一个8位数据刚传完3位时遇到断点SPI会暂停继续运行后它会从第4位开始传并且仍然会传满8个位即把剩下的5位传完。这保证了数据帧的完整性避免产生残缺帧误导从设备。SOFT 1完成模式行为相对简单。如果挂起发生在一次传输开始之前第一个SPICLK脉冲之前则整个传输取消。如果挂起发生在传输开始之后则SPI会坚持把当前移位寄存器SPIDAT和发送缓冲区TXBUF或TX FIFO里的所有数据全部发送完毕后再停止。这确保了至少当前缓存的数据包是完整的。实操心得在调试SPI驱动时我习惯先将FREE和SOFT都设为0。这样在断点处SPI会暂停我可以安全地检查发送/接收缓冲区的值、时钟相位等状态。如果调试的代码段与SPI通信强相关需要观察连续数据流我会临时将FREE设为1。切记在产品发布的代码中如果不涉及特殊调试需求通常将FREE位保持默认值0即可SOFT位根据是否需要保证帧完整性来选择。2.2 三线模式TRIWIRE节省引脚的艺术标准SPI需要四根线SCLK时钟、MOSI主出从入、MISO主入从出和SS片选。当你的MCU引脚资源紧张或者只需要与一个单向传输的设备通信时TRIWIRE位位0就派上用场了。当TRIWIRE 1时SPI启用三线模式。这里的“三线”指的是SCLK、片选和一根双向数据线。主模式MASTER/SLAVE 1SPISIMO主出从入引脚变为SPIMOMI引脚承担起双向数据传输的任务。主设备通过这根线既发送数据也接收数据实际上在时钟驱动下发送和接收是同时进行的只是方向固定。而原来的SPISOMI主入从出引脚则被释放可以配置为普通GPIO使用。从模式MASTER/SLAVE 0SPISOMI主入从出引脚变为SPISISO引脚作为从设备的双向数据线。原来的SPISIMO引脚被释放为GPIO。注意事项三线模式本质上是半双工通信吗并不是。它依然是全双工因为数据在时钟的上升沿或下降沿同时被采样和输出只是物理上共用了一根数据线。这要求主从设备对数据线的驱动要有严格的时序控制避免冲突。通常主设备在时钟边沿输出数据从设备在相反的边沿输出数据通过时钟相位和极性的巧妙配置来实现。启用此模式前务必确认你的从设备也支持三线SPI模式。2.3 片选信号极性控制STEINV在多从设备的SPI系统中主设备通过片选信号SPISTE来选择与哪个从设备通信。通常片选信号是低电平有效。但有些特殊的应用场景例如需要接收左右声道数字音频数据时可能会需要高电平有效的片选信号。STEINV位位1就是用来控制SPISTE信号的极性。STEINV 0片选信号低电平有效默认。STEINV 1片选信号高电平有效。重要提示手册明确指出此位仅在从模式下有效。当SPI配置为主模式时写入此位是无效的。这是因为片选信号通常由主设备产生并控制其极性在主设备端更多是由GPIO输出初始化时决定的而非SPI模块本身。在从模式下这个位决定了从设备在何种电平下被“选中”并响应SPI时钟和数据。3. SCI多处理器通信模式精讲SCIUART的异步通信虽然简单但在构建多节点网络时如何让数据准确地送达目标节点而不是广播给所有节点是个关键问题。TMS320F2803x的SCI模块提供了两种高效的多处理器通信协议空闲线模式和地址位模式。这两种模式的核心思想都是“唤醒-寻址-通信”。3.1 多处理器通信的核心机制无论是哪种模式其通信流程都遵循一个基本范式睡眠SLEEP所有从节点Listener的SCI初始化后都会将SCICTL1寄存器中的SLEEP位位2置1。在此状态下从节点的SCI接收器虽然仍在工作但收到数据帧时不会置位RXRDY标志也不会产生接收中断除非检测到特定的唤醒条件。这避免了所有从节点被每一个数据字节都中断。唤醒与寻址主节点Talker要发送数据块时先发送一个特殊的地址。这个地址帧会“唤醒”总线上的所有从节点使它们都能接收到这个地址字节并与自己预设的地址进行比较。选择性响应只有地址匹配的那个从节点才会在软件中断服务程序中清除自己的SLEEP位。此后该节点将对后续的数据帧正常响应产生中断读取数据。地址不匹配的从节点其SLEEP位保持为1继续忽略后续的数据帧直到下一个地址帧的到来。数据块传输主节点在发送地址帧后紧接着发送数据帧。只有被寻址的从节点会接收这些数据。3.2 空闲线多处理器模式Idle-Line Mode这种模式通过帧间的空闲时间Idle Time来区分数据块。它规定如果一个帧结束停止位后通信线上保持10个位时间以上的高电平空闲状态那么下一个帧就被认为是新数据块的开始即地址帧。操作流程主设备在发送完上一个数据块后有意让总线空闲超过10个位时间。主设备发送地址帧。所有从设备检测到长空闲后的第一个帧将其识别为地址帧并产生中断。从设备在中断服务程序中比较地址。匹配者清除SLEEP位准备接收数据不匹配者保持SLEEP1。主设备紧接着发送数据帧。数据帧之间的间隔小于10个位时间因此不会被误认为是新地址帧。如何产生精确的11位空闲时间手动延时计算位时间比较麻烦。SCI提供了一个硬件机制TXWAKE标志位SCICTL1.3。主设备在发送地址帧前先将TXWAKE位写1。然后向SCITXBUF寄存器写入一个“无关紧要”的数据字Dummy Data。注意这个数据字本身不会被发送出去。当这个“唤醒”请求被处理时硬件会自动在总线上插入一个恰好11个位时间的空闲周期。空闲周期结束后主设备再向SCITXBUF写入真正的目标地址开始通信。避坑指南空闲线模式非常适合数据块较大例如超过10个字节的通信。因为它的开销就是块之间的一个长空闲。但如果你的数据块非常小且发送频繁每个块之间都要等待10多个位时间的空闲会导致总线利用率显著下降。此时应考虑地址位模式。3.3 地址位多处理器模式Address-Bit Mode这种模式在每个数据帧的格式中增加了一个额外的“地址位”用来显式标识该帧是地址帧还是数据帧。地址位置1表示该帧是地址帧置0表示是数据帧。这样数据块之间无需长空闲间隔可以连续发送。操作流程主设备要发送地址帧时先将TXWAKE位置1然后向SCITXBUF写入地址值。硬件发送该帧时会自动将地址位置1。所有从设备检测到地址位为1的帧将其作为地址帧处理并产生中断。从设备比较地址匹配者清除SLEEP位。主设备发送后续数据帧前先将TXWAKE位清零再写入数据。这样发出的数据帧其地址位为0。只有SLEEP位已清除的目标从设备会响应这些数据帧。地址位位于帧格式中的哪里它紧跟在最后一个数据位之后在可选的奇偶校验位和停止位之前。所以一个典型的8位数据、无校验、1位停止位的帧在地址位模式下会变成1位起始位 8位数据位 1位地址位 1位停止位共11位。经验之谈地址位模式是“空间换时间”的典型。它每帧都多了一个位对于长数据块来说效率不如空闲线模式。但对于短数据块、频繁通信的场景它的效率更高因为省去了块间的等待时间。手册中的建议很中肯数据帧多于11字节用空闲线模式少于等于11字节用地址位模式。这个“11字节”的临界点就是权衡了额外地址位带来的开销与长空闲时间开销后的经验值。4. SCI寄存器配置与通信格式详解要实现可靠的SCI通信除了模式选择对数据格式、波特率、中断的精确配置是基础。这些配置都通过一组寄存器完成。4.1 可编程数据格式SCICCR寄存器SCI的帧格式非常灵活通过SCICCR通信控制寄存器进行配置SCICHAR位2-0选择数据字符长度1到8位可选。通常选择8位0b111。PARITYENA位5奇偶校验使能位。1为使能0为禁用。在干扰不大的环境中可以禁用以简化处理。PARITY位6当校验使能时此位选择奇校验0或偶校验1。奇偶校验是一种简单的检错机制但无法纠错。STOPBITS位7停止位数量。0为1个停止位1为2个停止位。大多数设备使用1个停止位。ADDR/IDLE MODE位3这是选择多处理器模式的关键位。0为空闲线模式1为地址位模式。4.2 波特率计算SCI的波特率由低速外设时钟LSPCLK和一个16位的波特率选择寄存器SCI Baud Select Registers 通常是SCIHBAUD和SCILBAUD两个8位寄存器组成共同决定。计算公式为SCI Baud Rate LSPCLK / [(BRR 1) * 8]其中BRR就是波特率选择寄存器SCIBAUD中16位的值。例如当LSPCLK 100 MHz 目标波特率为9600时BRR LSPCLK / (SCI Baud Rate * 8) - 1 100,000,000 / (9600 * 8) - 1 ≈ 1301.04取整后BRR 13010x515。代入公式验证实际波特率100,000,000 / [(13011)*8] ≈ 9600.96误差约0.01%在可接受范围内。配置要点务必根据系统实际的LSPCLK频率计算BRR值。LSPCLK通常由系统时钟SYSCLK分频得到需要在系统初始化时确认其值。波特率误差应控制在2%以内最好在1%以下以保证长时间通信的稳定性。4.3 中断机制与FIFO操作SCI提供了丰富的中断源来高效处理通信事件而非单纯依赖轮询。基本中断控制发送中断由TXRDY标志SCICTL2.7触发。当发送缓冲寄存器SCITXBUF为空可以接收新数据时此位置1。如果TX INT ENA位SCICTL2.0已使能则会产生发送中断。接收中断由RXRDY标志SCIRXST.6触发。当接收缓冲寄存器SCIRXBUF收到新数据时此位置1。如果RX/BK INT ENA位SCICTL2.1已使能则会产生接收中断。接收错误中断帧错误FE、溢出错误OE、奇偶校验错误PE和间隔检测BRKDT这四个错误标志位任意一个置位都会导致RX ERROR标志SCIRXST.7置位。如果RX ERR INT ENA位SCICTL1.6已使能也会触发接收中断与RXRDY共用中断线。FIFO增强功能为了减少CPU频繁处理中断的开销C28x的SCI模块支持4级深度的硬件FIFO。使能FIFO通过设置SCIFFTX寄存器中的SCIFFEN位为1来使能FIFO模式。中断触发级别这是FIFO模式最实用的特性。你可以设置FIFO收到多少数据后才产生中断。接收FIFO通过RXFFIL位SCIFFRX.4-0设置触发级别。例如设置为4则只有当RX FIFO中存有4个或更多字符时才触发RXINT中断。这避免了每收到一个字节就中断一次CPU。发送FIFO通过TXFFIL位SCIFFTX.4-0设置触发级别。例如设置为0当TX FIFO完全空即最后一个字从FIFO移入发送移位器TXSHF时才触发TXINT中断通知CPU可以填充下一批数据。可编程发送延迟SCIFFCT寄存器SCIFFCT的低8位FFTXDLY7-0可以设置每个字符从TX FIFO加载到TXSHF之间的延迟以波特率时钟周期为单位。设置为0可实现背靠背连续发送设置一个值可以人为降低发送速率以兼容响应速度慢的旧设备无需CPU干预延时。5. 实战配置与常见问题排查理解了原理最终要落到代码上。下面以配置一个使用地址位多处理器模式、波特率115200、8位数据、无校验、1位停止位的SCI从机为例并分享几个踩过的坑。5.1 寄存器初始化代码示例C语言片段// 假设 LSPCLK 100MHz 目标波特率 115200 // 计算 BRR 100,000,000 / (115200 * 8) - 1 ≈ 107.5 // 取整 BRR 108 (0x6C) #define SCI_BRR 108 void SCI_Init(void) { // 1. 使能SCI模块时钟取决于具体系统时钟配置 SysCtrlRegs.PCLKCR7.bit.SCI_A 1; // 使能SCI-A外设时钟 DELAY_US(10); // 短暂延时等待时钟稳定 // 2. 配置GPIO复用为SCI引脚以GPIO28/29为例 EALLOW; GpioCtrlRegs.GPAMUX2.bit.GPIO28 1; // GPIO28 复用为 SCIRXDA GpioCtrlRegs.GPAMUX2.bit.GPIO29 1; // GPIO29 复用为 SCITXDA EDIS; // 3. 软件复位SCI模块 SciaRegs.SCICTL1.bit.SWRESET 0; // 先置0 DELAY_US(10); SciaRegs.SCICTL1.bit.SWRESET 1; // 再置1结束复位 // 4. 配置通信格式SCICCR SciaRegs.SCICCR.bit.SCICHAR 7; // 8位数据位 (71) SciaRegs.SCICCR.bit.PARITYENA 0; // 禁止奇偶校验 SciaRegs.SCICCR.bit.PARITY 0; // 奇校验未使能此位无效 SciaRegs.SCICCR.bit.STOPBITS 0; // 1位停止位 SciaRegs.SCICCR.bit.ADDRIDLE_MODE 1; // 1地址位多处理器模式 // 5. 配置波特率 SciaRegs.SCIHBAUD (SCI_BRR 8) 0xFF; // 高位字节 SciaRegs.SCILBAUD SCI_BRR 0xFF; // 低位字节 // 6. 配置控制寄存器1SCICTL1 SciaRegs.SCICTL1.bit.RXENA 1; // 使能接收器 SciaRegs.SCICTL1.bit.TXENA 1; // 使能发送器 SciaRegs.SCICTL1.bit.SLEEP 1; // 初始置于睡眠模式多处理器 SciaRegs.SCICTL1.bit.TXWAKE 0; // 发送唤醒标志初始清零 // RX ERR INT ENA 根据需求使能此处先关闭 SciaRegs.SCICTL1.bit.RXERRINTENA 0; // 7. 配置控制寄存器2SCICTL2和中断此处不使能中断用查询方式示例 SciaRegs.SCICTL2.bit.TXINTENA 0; // 禁止发送中断查询TXRDY SciaRegs.SCICTL2.bit.RXBKINTENA 0; // 禁止接收/间隔中断查询RXRDY // 8. 使能SCI结束初始化 SciaRegs.SCICTL1.bit.SWRESET 1; // 确保SWRESET1 }5.2 常见问题排查速查表现象可能原因排查步骤与解决方案完全无法收发数据1. GPIO复用未配置。2. 外设时钟未使能。3. SWRESET位未置1。1. 检查GPIO MUX寄存器配置确认引脚功能已切换到SCI。2. 检查PCLKCRx寄存器确认SCI模块时钟已开启。3.最关键一步确认SCICTL1寄存器的SWRESET位已置1。该位为0时SCI模块处于复位状态所有配置无效。能发送但不能接收或反之1. 发送器或接收器未使能。2. 引脚连接错误RX/TX交叉。3. 从设备的SLEEP位未正确管理。1. 检查SCICTL1的TXENA和RXENA位。2. 用示波器或逻辑分析仪检查SCIRXD和SCITXD引脚波形确认主从设备TX接对方RX。3. 在多处理器模式下确认从机在地址匹配后清除了SLEEP位。接收数据错误乱码1. 波特率不匹配。2. 数据格式数据位、停止位、校验位不匹配。3. 电气电平不匹配如3.3V与5V。1.双盲检查主从双方的波特率计算值和实际LSPCLK频率。误差需在2%内。2. 逐项核对SCICCR寄存器的配置SCICHAR, STOPBITS, PARITYENA。3. 检查电平转换电路或使用兼容电平的器件。多处理器模式下从机收不到数据1. 主设备未正确发送地址帧TXWAKE使用错误。2. 从机SLEEP位一直为1。3. 地址比较逻辑有误。1. 主设备发送数据前确认TXWAKE位和地址位的操作顺序正确先置TXWAKE写地址后清零TXWAKE写数据。2. 从机在接收中断中检查收到的第一个字节地址比较成功后务必手动清除SLEEP位。3. 使用逻辑分析仪捕获总线波形确认地址帧的格式空闲线或地址位符合预期。FIFO模式下中断不触发1. FIFO未使能SCIFFEN。2. 中断触发级别TXFFIL/RXFFIL设置不当。3. PIE中断向量表未配置或使能。1. 确认SCIFFTX寄存器的SCIFFEN位已置1。2. 例如若RXFFIL设为4则需收到4个字节才会触发中断。检查FIFO状态位TXFFST/RXFFST。3. 检查PIE相关寄存器的配置确认SCI中断已正确映射并开启。仿真时SPI通信异常FREE和SOFT位配置不当。根据调试需求配置SPIPRI寄存器的FREE和SOFT位。若需在断点处观察通信状态设置FREE0, SOFT0。若通信不能中断设置FREE1。5.3 调试心得逻辑分析仪是你的最佳伙伴无论是SPI的时钟相位问题还是SCI多处理器模式的地址帧识别问题光靠看代码和打印信息很难定位。一个支持协议解码的逻辑分析仪如Saleae能极大提升调试效率。连接好线抓取SCLK、MOSI、MISO、STE对于SPI或TX、RX对于SCI的波形解码器能直观地显示出每个帧的数据、地址位、起始/停止位。你可以清晰地看到SPI的时钟极性和相位CPOL, CPHA是否与从设备匹配。在空闲线模式下帧间的空闲时间是否真的超过了10个位时间。在地址位模式下地址帧的“地址位”是否为1数据帧的是否为0。数据内容是否正确有无错位。纸上得来终觉浅绝知此事要躬行。寄存器配置表看再多遍也不如动手写一段初始化代码抓一次波形来得深刻。希望这篇结合了手册核心内容和实战经验的解析能帮你下次面对SPI和SCI时多一份从容少一个通宵。