1. 项目概述与串行通信的核心价值在嵌入式系统开发尤其是工业控制、电机驱动和新能源领域TMS320F28335这颗经典的C2000系列DSP几乎是绕不开的明星芯片。我们做项目无论是驱动一台伺服电机还是搭建一个光伏逆变器都离不开一个核心环节通信。芯片需要和上位机对话、读取传感器数据、或者与其他控制器协同工作这时候串行通信接口就成了连接内外的“神经系统”。串行通信顾名思义就是数据一位一位地按顺序在单根或少数几根线上传输。这听起来似乎没有并行通信一次传一个字节来得快但它的优势在工程实践中是决定性的节省宝贵的I/O引脚、简化PCB布线、降低硬件成本并且能够轻松实现长距离可靠通信。在F28335上德州仪器TI为我们集成了三种最主流、最经典的串行通信外设SCI、SPI和I2C。很多新手拿到芯片手册看到满屏的寄存器位定义和时序图可能会发怵觉得配置起来很复杂。其实不然一旦你理解了它们各自的设计哲学和应用场景再结合手册里的公式和寄存器就能像搭积木一样构建出稳定可靠的通信链路。我经手过不少基于F28335的项目从简单的通过SCI也就是常说的UART打印调试信息到用SPI驱动高速ADC采集电流电压再到通过I2C配置外围的EEPROM或温度传感器。这些接口用好了系统就活了。本文将结合官方数据手册的“硬核”内容以及我实际调试中积累的“软经验”为你深入解析F28335上这三个串行通信接口。我们不只讲寄存器怎么配更要讲清楚为什么这么配以及在配置过程中有哪些手册上没写但实际开发中一定会踩到的“坑”。目标是让你读完就能动手配完就能通。2. 串行通信接口SCI模块深度解析SCI在通用语境下就是我们熟知的UART通用异步收发传输器。它是嵌入式世界里的“普通话”因为其协议简单、对时钟同步要求低异步通信几乎成了所有微控制器与PC、蓝牙模块、GPS模块等设备通信的标准配置。F28335提供了三个独立的SCI模块SCI-A SCI-B SCI-C这为我们实现多路通信或冗余备份提供了便利。2.1 SCI核心工作机制与寄存器地图SCI通信的核心是“帧”。每一帧数据包含一个起始位、5-8个数据位、一个可选的奇偶校验位以及1或2个停止位。F28335的SCI模块完全由一组内存映射的寄存器控制理解这些寄存器是灵活运用的前提。根据手册每个SCI模块的寄存器组起始地址不同。以SCI-A为例其控制寄存器SCICCR位于0x7050。这里需要特别注意一个关键细节手册明确指出这些寄存器是8位寄存器但位于16位的外设帧2空间。这意味着当你用C语言以16位类型如Uint16访问它们时有效数据只在低8位位7-0高8位位15-8读出来永远是0写入高8位则无效。这个细节在编程时至关重要否则你可能无意中修改了相邻寄存器的值。配置SCI通常遵循一个固定流程首先禁用发送器和接收器SCICTL1寄存器然后配置通信控制寄存器SCICCR设定数据位长度、停止位、奇偶校验模式接着配置波特率寄存器最后再使能模块。波特率的计算是第一个关键点。手册给出了公式当波特率除数BRR≠ 0时波特率 LSPCLK / [(BRR 1) * 8]当BRR 0时波特率 LSPCLK / 16这里的LSPCLK是低速外设时钟它来源于系统时钟SYSCLKOUT并通过外设时钟控制寄存器进行分频。假设我们的系统主频是150MHz通过配置使LSPCLK SYSCLKOUT / 4 37.5MHz。现在我们需要配置一个经典的115200波特率。计算过程如下根据公式变形BRR (LSPCLK / (波特率 * 8)) - 1代入数值BRR (37.5e6 / (115200 * 8)) - 1 ≈ (37.5e6 / 921600) - 1 ≈ 40.69 - 1 39.69取最接近的整数值BRR 40。计算实际波特率实际波特率 37.5e6 / ((401)*8) 37.5e6 / 328 ≈ 114332 bps计算误差误差 (114332 - 115200) / 115200 ≈ -0.75%。这个误差在异步通信的可接受范围内通常要求2%。在实际代码中我们需要将计算出的整型BRR值拆分为高8位SCIHBAUD和低8位SCILBAUD写入。BRR400x28所以SCIHBAUD 0x00SCILBAUD 0x28。2.2 双缓冲与FIFO模式实战手册中提到SCI的发送和接收是“双缓冲”的。这是什么意思呢你可以把它想象成有两个水杯。当你在往“发送缓冲寄存器”SCITXBUF里倒水写数据时前一个水杯发送移位寄存器TXSHF里的水正在通过SCITXD引脚一点点倒出去串行移位发送。这样CPU无需等待一个字节完全发送完毕就可以准备下一个字节的数据提高了效率。而FIFO先入先出模式则是更强大的增强功能。它提供了一个16级深度的硬件队列。启用FIFO后你可以一次性写入最多16个字节到发送FIFO硬件会自动按顺序发送同样接收端也可以连续接收最多16个字节再一次性通知CPU读取。这极大地减轻了CPU的中断负担特别适合批量数据传输。配置FIFO主要通过SCIFFTXSCIFFRX和SCIFFCT这三个增强寄存器。例如要使能SCI-A的发送和接收FIFO并设置发送FIFO的中断触发级别为8即当FIFO中剩余数据小于等于8个时产生中断你需要将SCIFFTX寄存器的SCIFFEN位位14置1使能FIFO功能。将SCIFFTX寄存器的TXFIFO Reset位位12置1然后清0以复位发送FIFO指针。设置TXFFIL位4-0为8配置中断触发级别。注意在使能或修改FIFO配置前最好先复位FIFO指针将TXFFRST和RXFFRST位置1再清0以避免残留的旧数据指针导致混乱。这是一个手册里可能一笔带过但实际调试中极其重要的步骤。2.3 错误处理与多处理器模式可靠的通信离不开健壮的错误检测。F28335的SCI模块提供了四种错误检测标志位于SCIRXST寄存器中奇偶错误PE接收数据的奇偶校验位与预设规则不符。帧错误FE没有在预期的位置检测到停止位通常是电平错误或波特率不匹配。溢出错误OECPU还没来得及读取SCIRXBUF中的数据新的数据又覆盖进来了。这是新手最容易忽视的错误一旦发生如果不手动清除后续数据可能无法正确接收。间断检测BRKDT接收到长时间的低电平Break信号。在中断服务程序中必须首先检查SCIRXST中的这些错误位并进行相应处理如丢弃错误数据、重发等。清除这些错误标志通常通过读取SCIRXBUF对于OEFE PE或软件序列对于BRKDT来实现。此外SCI还支持“多处理器”通信模式包括空闲线多处理器模式和地址位多处理器模式。这在构建一主多从的通信网络时非常有用。其核心思想是数据帧中包含一个地址字节只有地址匹配的从机才会响应后续的数据帧。配置时需要在SCICCR寄存器中选择模式并利用TXWAKE和RXWAKE位来控制地址帧的发送与识别。3. 串行外设接口SPI模块配置精要如果说SCI是异步、非接地的“对话”那么SPI就是同步、手拉手的“协作”。SPI是一种高速、全双工、同步的串行通信总线采用主从模式。它需要四根线时钟SPICLK、主出从入SPISIMO、主入从出SPISOMI和从机片选SPISTE。F28335上有一个SPI模块SPI-A其最大特点是极高的可配置性和速度。3.1 SPI时钟极性与相位理解四种模式的本质SPI通信的时序核心由时钟极性SPICCR.6CLOCK POLARITY和时钟相位SPICTL.3CLOCK PHASE两个位控制它们共同构成了四种模式Mode 0 1 2 3。很多开发者只记模式编号却不理解其物理意义一旦换用不同约定的从设备就容易出错。时钟极性CPOL决定SPICLK空闲时的电平。0空闲低电平1空闲高电平。时钟相位CPHA决定数据在时钟的哪个边沿被采样。0数据在第一个边沿即时钟从空闲状态跳变后的第一个边沿被采样1数据在第二个边沿被采样。手册中描述的四种时钟方案可以这样理解下降沿无相位延迟CPOL1 CPHA0时钟空闲为高。主机在时钟下降沿输出数据从机在时钟上升沿采样数据。这是F28335 SPI模块的复位默认模式也是很多SPI器件如Flash存储器的常用模式。下降沿有相位延迟CPOL1 CPHA1时钟空闲为高。数据输出提前半个周期在下降沿采样。上升沿无相位延迟CPOL0 CPHA0时钟空闲为低。在上升沿输出下降沿采样。上升沿有相位延迟CPOL0 CPHA1时钟空闲为低。数据输出提前半个周期在上升沿采样。实操心得配置SPI与从设备通信时第一件事就是查阅从设备的数据手册确认其支持的SPI模式。然后根据上述规则设置F28335的SPICCR和SPICTL寄存器。一个快速验证的方法是用逻辑分析仪抓取SPICLK和SPISIMO/SPISOMI的波形对照时序图检查数据建立和保持时间是否满足从设备要求。3.2 波特率计算与主从模式配置SPI的波特率计算公式与SCI不同手册给出当SPIBRR 3 到 127时波特率 LSPCLK / (SPIBRR 1)当SPIBRR 0 1 2时波特率 LSPCLK / 4SPIBRR是一个7位的值0-127。假设LSPCLK仍为37.5MHz我们需要配置一个10MHz的SPI时钟。计算SPIBRR LSPCLK / 波特率 - 1 37.5e6 / 10e6 - 1 3.75 - 1 2.75。取整后SPIBRR 3。实际波特率 37.5e6 / (31) 9.375 MHz。如果需要更接近10MHz只能尝试调整LSPCLK的源时钟分频比。主从模式通过SPICTL.2MASTER/SLAVE位选择。作为主机时SPICLK由F28335产生作为从机时SPICLK为输入。一个关键点是SPISTE引脚在从机模式下此引脚通常由主机拉低来选中该从机。在F28335的SPI从机配置中你可以通过设置SPICTL.4TALK位来控制从机是否驱动数据线。只有当SPISTE为低且TALK1时从机才会在SPISOMI上输出数据。3.3 数据帧格式与FIFO操作F28335的SPI数据长度可编程为1-16位通过SPICCR.3-0位设置。数据存储在大端格式的SPIDAT寄存器中。发送数据时写入SPITXBUF数据会自动加载到SPIDAT并开始移位传输。接收到的数据可以从SPIRXBUF读取。SPI同样支持16级深度的发送/接收FIFO通过SPIFFTXSPIFFRX和SPIFFCT寄存器配置。启用FIFO可以大幅提升大数据量传输的效率。这里有一个重要的延迟发送控制功能SPIFFCT寄存器它可以设置在每次FIFO传输之间插入特定的时钟延迟这对于驱动某些需要特定数据间隔的器件如某些型号的DAC或LCD控制器非常有用。4. 内部集成电路I2C总线接口详解I2C是一种仅需两根线串行数据线SDA和串行时钟线SCL的多主多从、半双工串行总线。它通过地址寻址机制可以在总线上挂载多个设备非常适合连接板上的多个低速外设如EEPROM、温度传感器、RTC等。F28335的I2C模块兼容Philips I2C规范v2.1支持标准模式100kbps和快速模式400kbps。4.1 I2C总线协议基础与F28335实现I2C协议的基本单元是“位传输”。在SCL为高电平期间SDA线的电平必须保持稳定只有SCL为低电平时SDA才能变化。每一次传输都以一个START条件SCL高时SDA由高变低开始以一个STOP条件SCL高时SDA由低变高结束。中间传输的数据以字节为单位每字节后跟随一个应答位ACK。F28335的I2C模块将这一系列复杂的时序全部用硬件实现我们只需要操作寄存器。核心寄存器包括I2CMDR模式寄存器配置I2C模块为主/从模式、传输模式、启动/停止条件产生等。I2CSAR从机地址寄存器在主机模式下存放要访问的从机7位或10位地址。I2CCNT数据计数寄存器设置要发送/接收的数据字节数在重复模式I2CMDR.5RM位下非常有用。I2CDXR数据发送寄存器和I2CDRR数据接收寄存器顾名思义存放待发送和已接收的数据。I2CSTR状态寄存器和I2CIER中断使能寄存器用于查询状态和控制中断。4.2 时钟配置与通信流程I2C总线的时钟由主机产生。F28335作为主机时其I2C模块时钟I2C_CLK来源于系统时钟SYSCLKOUT。SCL的频率通过I2CPSC预分频和I2CCLKL/I2CCLKH时钟低/高时间寄存器共同配置。例如配置快速模式400kbps假设SYSCLKOUT 150MHzI2C_CLK SYSCLKOUT 150MHz。首先用I2CPSC进行粗调。I2C_CLK分频后得到模块内部时钟。假设设置I2CPSC6则内部时钟频率 150MHz / (61) ≈ 21.43MHz。然后配置I2CCLKL和I2CCLKH来细分SCL的高低电平时间。对于400kbpsSCL周期为2.5us。内部时钟周期约为46.7ns。需要将2.5us划分为高电平和低电平时间。通常设置为各占一半即1.25us。计算分频值ICCL I2CCLKH 1.25us / 46.7ns ≈ 27取整。最终SCL频率 ≈21.43MHz / (2727) ≈ 397 kHz接近400kHz。一次典型的I2C主机写操作流程如下配置I2CMDR为主发送模式设置I2CSAR为从机地址。如果需要设置I2CCNT。将I2CMDR寄存器中的STT位启动位置1硬件自动产生START条件。等待I2CSTR中的XRDY发送就绪标志置位然后向I2CDXR写入第一个字节通常为从机寄存器地址。继续等待XRDY写入要发送的数据字节。写入最后一个字节后将I2CMDR中的STP位停止位置1硬件会在传输完成后自动产生STOP条件。4.3 FIFO模式与中断处理F28335的I2C模块也包含16字深的发送和接收FIFO通过I2CFFTX和I2CFFRX寄存器控制。启用FIFO可以简化中断服务程序实现数据块的连续传输。I2C的中断源非常丰富包括发送准备好、接收准备好、寄存器访问准备好、无应答NACK、仲裁丢失、检测到停止条件、被寻址为从机等。I2CISRC寄存器会指示当前触发中断的具体事件。在中断服务程序中必须根据I2CISRC的值进行分支处理这是I2C编程比SCI和SPI稍复杂的地方。重要提示I2C的SDA和SCL引脚是开漏Open-Drain输出。这意味着F28335内部只能将线拉低无法主动拉高。因此必须在外部连接上拉电阻通常4.7kΩ - 10kΩ到VCC3.3V以确保总线在空闲时能被拉至高电平。忘记接上拉电阻是I2C通信失败的最常见硬件原因之一。5. GPIO复用与引脚配置实战F28335拥有多达88个GPIO引脚这些引脚绝大多数都与上述串行通信外设以及其他功能如PWM CAP QEP等复用。如何正确地将一个物理引脚配置为SCI的TXD功能而不是普通的GPIO输出是驱动成功的第一步。这完全由GPIO复用控制寄存器GPxMUX和方向控制寄存器GPxDIR决定。5.1 复用配置详解以将GPIO28配置为SCI-A的接收引脚SCIRXDA为例我们需要查阅手册中的“GPIO-A Mux Peripheral Selection Matrix”表格对应表4-16。找到GPIO28所在行GPAMUX2寄存器的位[25:24]控制GPIO28的功能。当GPAMUX2[25:24] 00时为GPIO功能。当GPAMUX2[25:24] 01时为SCIRXDA功能即外设1。当GPAMUX2[25:24] 10时为XZCS6功能外设2。当GPAMUX2[25:24] 11时为保留功能。因此在代码中我们需要执行EALLOW; // 解除对受保护寄存器的写保护 GpioCtrlRegs.GPAMUX2.bit.GPIO28 1; // 设置GPIO28为外设功能具体是SCIRXDA由下面GPxQSEL决定这里需要更精确。 // 实际上根据表格GPIO28的PER1是SCIRXDA对应GPAMUX2[25:24]01。 // 假设我们使用位域定义通常操作如下 GpioCtrlRegs.GPAMUX2.bit.GPIO28 1; // 这只是示意具体位域名称需参考TI提供的头文件。 // 更常见的做法是直接操作寄存器 GpioCtrlRegs.GPAMUX2.all (GpioCtrlRegs.GPAMUX2.all 0xFCFFFFFF) | (0x1 24); // 将bit24-25设为01 EDIS; // 重新使能写保护同时由于SCIRXDA是输入功能我们还需要确保GPADIR寄存器中对应GPIO28的方向位被设置为输入0。但通常当引脚被配置为外设输入功能时方向寄存器会自动被忽略不过显式地将其设为输入是一个好习惯。5.2 输入信号量化Qualification这是F28335 GPIO一个非常有用且重要的特性尤其对于连接机械开关、远程信号等可能带有毛刺的输入。输入量化功能可以对输入信号进行“消抖”处理。它通过一个可配置的采样窗口只有当连续多个采样周期内信号电平都一致时才认为输入有效。配置在GPxQSEL1/2和GPxCTRL寄存器中。GPxQSEL选择量化模式00仅同步到SYSCLKOUT默认。01或10使用采样窗口进行量化3采样或6采样模式。11不同步用于外设内部已同步的信号。GPxCTRL寄存器中的QUALPRD位域则为每组GPIO通常8个一组设置采样周期。例如设置QUALPRD5采样周期为6个SYSCLKOUT周期QUALPRD1。在6采样模式下只有当连续6个采样点电平相同时输入才被确认改变。这能有效滤除宽度小于6 * (QUALPRD1) * SYSCLKOUT周期的毛刺。实操心得对于连接按键或限位开关的GPIO强烈建议启用输入量化例如6采样模式并设置合适的QUALPRD值如对应1ms左右的滤波时间可以极大提高系统抗干扰能力避免误触发。但对于高速通信引脚如SPI CLK则必须禁用量化选择11模式或使用仅同步模式否则会引入无法接受的延迟。6. 常见问题排查与调试技巧实录即使完全按照手册配置在实际调试中通信不通也是家常便饭。下面是我在多年项目中总结的一些典型问题及排查思路形成了一份速查表。现象可能原因排查步骤与解决方法SCI通信无输出或乱码1. 波特率计算错误或时钟源配置错误。2. 引脚复用未正确配置实际引脚仍是GPIO模式。3. 发送器未使能SCICTL1.1TXENA位。4. 硬件连接错误TX/RX交叉连接、共地问题。1.首要检查用示波器或逻辑分析仪测量SCITXD引脚。如果完全没有波形检查引脚复用和使能位。如果有波形但波特率不对重新计算LSPCLK和BRR并检查系统时钟配置。2. 确认GPxMUX和GPxDIR寄存器配置正确。3. 检查SCICTL1寄存器确保SW RESET位已置1模块使能且TXENA位为1。4. 确保控制器与对端设备共地且TX接对方的RX。SCI只能发送不能接收1. 接收器未使能SCICTL1.0RXENA位。2. 接收中断未开启或中断服务程序ISR未正确清除标志。3. 对方设备未发送或电平不匹配如3.3V与5V器件直接连接。1. 检查SCICTL1的RXENA位。2. 检查SCICTL2的RX/BK INT ENA位及PIE中断配置。在RX ISR中必须读取SCIRXBUF来清除RXRDY标志。3. 测量SCIRXD引脚是否有数据波形。如有必要使用电平转换芯片。SPI通信从机无响应1. 时钟极性/相位CPOL/CPHA模式不匹配。2. 从机片选信号SPISTE未正确拉低。3. 从机TALK位从机模式下未使能。4. 数据位长度不匹配。1.用逻辑分析仪这是调试SPI最有效的工具。对照从设备手册的时序图检查SPICLK空闲电平、数据采样边沿是否一致。2. 确认主机正确控制了SPISTE引脚通常配置为GPIO输出并在通信期间拉低。3. 在从机配置中检查SPICTL.1TALK位必须在SPISTE为低时置1才能输出数据。4. 核对主机SPICCR.3-0与从机要求的数据位宽。I2C总线一直为低电平锁死1. 总线缺少上拉电阻。2. 从设备故障将总线拉低。3. 主设备在通信过程中异常复位未释放总线。1.硬件第一检查SDA和SCL线上是否接了上拉电阻通常4.7kΩ。2. 逐一断开从设备排查是哪一设备导致总线锁死。3. F28335的I2C模块提供了“总线清除”功能。在I2CMDR寄存器中有一个BC位总线清除模式当置位时模块会尝试通过发送时钟脉冲来恢复总线。这是一个软件复位总线的好方法。I2C通信收到NACK无应答1. 从机地址错误。2. 从机设备不存在或未上电。3. 总线电平或时序问题。4. 从机正忙如EEPROM正在写周期内。1. 仔细核对I2CSAR寄存器中的7位/10位地址格式注意7位地址通常左移一位最低位是R/W位。2. 用示波器检查通信波形看START条件后SDA上发出的地址位是否正确。3. 检查上拉电阻阻值是否合适总线电容是否过大导致上升沿过缓。4. 对于有写周期的器件发送写命令后需等待足够时间查阅器件手册的Twr再发送下一个命令。使用FIFO时数据丢失或顺序错乱1. FIFO复位不彻底。2. 中断触发级别设置不当导致溢出或中断过于频繁。3. 在FIFO使能情况下错误地操作了非FIFO缓冲区。1. 在使能FIFO功能SCIFFEN或SPIFFEN前或需要清空FIFO时务必先执行FIFO复位操作将TXFFRST和RXFFRST位置1再清0。2. 根据数据流特性调整TXFFIL和RXFFIL。对于突发大数据量可以设置较高的触发级别以减少中断次数对于实时性要求高的单字节数据可设置为1。3. 启用FIFO后发送数据应写入SCIFFTX/SPIFFTX相关的发送缓冲寄存器实质是FIFO而不是原来的SCITXBUF/SPITXBUF。同样接收数据应从FIFO接收缓冲寄存器读取。调试黄金法则当通信失败时不要急于修改代码。首先用示波器或逻辑分析仪观察通信引脚上的实际波形。检查是否有信号信号电平是否正确波特率/时钟频率是否匹配数据内容是否符合预期硬件工具的直观呈现往往能瞬间定位是软件配置问题、硬件连接问题还是器件本身问题。尤其是SPI和I2C的时序逻辑分析仪的解码功能可以让你直接看到传输的地址、数据和ACK/NACK位事半功倍。最后关于稳定性。在复杂的电力电子或电机控制环境中电磁干扰强烈。确保通信线路远离功率回路必要时使用屏蔽线或双绞线。对于长距离的SCI通信可以考虑使用RS-485差分总线标准并启用SCI的硬件奇偶校验或添加软件校验和。SPI时钟频率较高时注意PCB走线等长减少反射。I2C总线上拉电阻的选择需权衡速度和功耗总线电容过大时需减小上拉电阻值以改善上升沿。