1. 项目概述与核心价值在嵌入式开发尤其是无线物联网IoT领域CC13x2和CC26x2系列无线微控制器MCU因其出色的射频性能和低功耗特性成为了许多传感器节点、智能家居设备和工业无线模块的首选。要让这些MCU与外部世界“对话”——无论是读取温湿度传感器的数据还是驱动一块OLED屏幕亦或是与另一颗协处理器通信——同步串行接口SSI通常实现为SPI和I2C这两种通信协议就是工程师手中最得力的“语言”。很多开发者习惯于依赖厂商提供的驱动库如TI的DriverLib或SimpleLink SDK进行快速开发这固然高效但一旦遇到时序异常、通信断续、中断不触发等“玄学”问题时如果对底层寄存器的运作机制一知半解调试过程就会变得异常痛苦。本文旨在为你剥开驱动库的“黑盒”直击CC13x2/CC26x2 SSI与I2C接口的寄存器核心。我将结合自己多年在无线传感网络产品开发中积累的实战经验不仅带你逐位解析官方手册中那些看似枯燥的寄存器表格更会分享在真实项目中如何配置、调试以及避坑。你将理解为何简单的SPI时钟相位SPH/SPO设置错误会导致传感器数据全为0xFF为何I2C总线上挂载多个设备时必须关注仲裁丢失ARBLST标志以及如何通过精准操控中断和DMA控制寄存器实现高效且不丢包的数据吞吐。无论你是正在评估CC13x2/CC26x2平台还是正在为现有项目中的通信稳定性问题头疼这篇深入寄存器层的解析都将为你提供清晰的路径和可靠的解决方案。2. SSISPI接口寄存器深度解析与实战配置SSISynchronous Serial Interface在CC13x2/CC26x2上通常被用作实现SPISerial Peripheral Interface协议。与通用的UART不同SPI是一种全双工、同步的通信总线其性能高度依赖于对时钟极性、相位、速率等参数的精确控制。这些控制最终都落在对一组特定内存地址即寄存器的读写操作上。2.1 核心控制寄存器CR0与CR1CR0和CR1是SPI通信的“大脑”决定了通信的基本框架。2.1.1 CR0寄存器定义通信“方言”CR0寄存器负责设定数据帧的格式、大小和时钟的基本特性。其位域配置是SPI与外设能够“听懂”彼此的前提。DSS (Data Size Select, 位[3:0]) 选择数据位宽从4位到16位。这是最基础的配置必须与从设备的数据宽度严格匹配。例如驱动一个8位ADC时应配置为0x78_BIT。一个常见的疏忽是当数据宽度小于16位时写入数据寄存器DR的数据必须右对齐高位补0。硬件在发送时会自动忽略未使用的高位接收时也会自动将数据右对齐放入接收缓冲区。如果你发现读取的数据总是错位首先应检查此处配置和数据填充方式。FRF (Frame Format, 位[5:4]) 选择帧格式。00代表Motorola SPI格式最常用01是TI同步串行格式10是National Microwire格式。绝大多数SPI外设如Flash、传感器都使用Motorola SPI格式。除非你明确知道外设要求否则保持为00。SPO (CLKOUT Polarity, 位6) 与 SPH (CLKOUT Phase, 位7) 这是SPI配置的灵魂共同定义了时钟极性CPOL和时钟相位CPHA。SPO0, SPH0(模式0) 时钟空闲时为低电平数据在时钟的第一个边沿上升沿采样。SPO0, SPH1(模式1) 时钟空闲时为低电平数据在时钟的第二个边沿下降沿采样。SPO1, SPH0(模式2) 时钟空闲时为高电平数据在时钟的第一个边沿下降沿采样。SPO1, SPH1(模式3) 时钟空闲时为高电平数据在时钟的第二个边沿上升沿采样。 注意SPI主从设备的CPOL和CPHA必须完全一致否则通信必然失败。许多传感器数据手册会明确要求工作模式。一个快速判断的方法是观察设备时序图看数据线MOSI/MISO在时钟的哪个边沿稳定即采样边沿以及在时钟空闲时是高是低。SCR (Serial Clock Rate, 位[15:8]) 串行时钟速率预分频器。它与CPSR寄存器共同决定最终的SPI比特率。计算公式为比特率 SSI输入时钟频率 / ((SCR 1) * CPSDVSR)。SCR取值范围0-255。通常先通过CPSR进行一个较大的整数分频再用SCR进行微调以获得精确的波特率。2.1.2 CR1寄存器启用与模式选择CR1寄存器控制SSI模块的使能、主从模式等全局功能。LBM (Loop Back Mode, 位0) 回环模式。置1时发送移位器的输出直接内部连接到接收移位器的输入。这是硬件自检和驱动调试的利器。在编写SPI驱动时我习惯先使能回环模式向DR寄存器写入一个已知值如0xAA55然后读取DR寄存器。如果读回的值一致说明SSI核心的数字通路基本正常可以排除软件读写寄存器逻辑的错误。之后再关闭回环连接真实外设进行测试。SSE (Synchronous Serial Interface Enable, 位1) SSI使能位。必须在配置完CR0、CR1、CPSR等其他所有参数后最后才将此位置1。在SSE0时可以安全修改MS位。MS (Master/Slave Select, 位2) 主从模式选择。0为主机1为从机。在CC13x2作为主机控制外设时设为0。SOD (Slave Output Disable, 位3) 从机输出禁用。仅在从机模式MS1下有意义。在多从机系统中如果多个从机的MISO线被连接在一起即“线与”则需要通过此位控制哪个从机有权驱动总线。对于主机或单从机系统通常保持为0。2.2 时钟与数据寄存器CPSR与DR2.2.1 CPSR寄存器时钟预分频除数CPSDVSR (Clock Prescale Divisor, 位[7:0]) 这是SSI模块的第一级分频器。它接收系统时钟输出一个较低的时钟供后续SCR分频。关键限制写入的值必须是2到254之间的偶数。如果你写入一个奇数如3硬件会强制将最低位置0实际生效的值是2。这个设计是为了保证分频后的时钟占空比为50%。在计算波特率时务必使用实际生效的偶数值。实战计算示例假设系统时钟为48MHz目标SPI波特率为1 Mbps。先确定CPSDVSR选择一个较大的偶数分频以降低时钟压力例如设为10。计算中间时钟48MHz / 10 4.8MHz。根据公式比特率 中间时钟 / (SCR 1) 可得SCR 1 4.8MHz / 1Mbps 4.8。SCR 3.8取整为4。验证实际波特率48MHz / (10 * (41)) 0.96 Mbps误差4%。若想更精确可以调整CPSDVSR为8则SCR1 48/(81)6 SCR5 实际波特率 48/(86)1.0 Mbps完全匹配。2.2.2 DR寄存器数据交换的窗口DR寄存器是双向的16位数据寄存器。写入时数据进入发送FIFO读取时从接收FIFO取出数据。 重要提醒当DSS配置为小于16位时例如8位你写入DR的数据必须右对齐。例如要发送0xAB8位应写入0x00AB而不是0xAB00。硬件发送逻辑会自动忽略高8位。同样接收到的8位数据硬件会自动右对齐你读到的DR寄存器低8位就是有效数据。忽略这一点是新手常犯的错误会导致数据错乱。2.3 状态与中断寄存器高效通信的保障轮询Polling和中断Interrupt是处理SPI数据的两种方式。对于低速或不频繁的操作轮询简单但对于需要及时响应或大数据量传输中断乃至DMA才是正道。2.3.1 SR寄存器实时状态窥镜SR寄存器提供了通信链路和FIFO的实时状态。TFE/TNF (位0/位1) 发送FIFO空/非满。TFE1表示发送FIFO完全空可以安全写入新数据但此时写入会直接进入移位器可能来不及处理。更常用的是TNF当TNF1时表示发送FIFO未满可以写入数据。在中断发送中我们通常检查TNF来决定是否填充下一个数据。RNE/RFF (位2/位3) 接收FIFO非空/满。RNE1表示有数据可读。RFF1表示接收FIFO已满如果此时继续有数据到来会发生溢出Overrun。BSY (位4) 忙标志。当BSY1时表示SSI正在发送或接收一帧数据或者发送FIFO非空。在修改CR0、CR1等关键配置寄存器前务必确保BSY0且SSE0否则可能导致不可预知的行为。2.3.2 中断寄存器组IMSC, RIS, MIS, ICR这组寄存器构成了一个完整的中断管理系统理解其工作流至关重要。RIS (Raw Interrupt Status) 原始中断状态寄存器。只要条件满足对应位就被硬件置1不受任何屏蔽影响。例如当接收FIFO中的数据达到4个或更多时RXRIS位自动置1。IMSC (Interrupt Mask Set and Clear) 中断屏蔽寄存器。你可以通过写1来使能某个中断源写0来禁用它。例如设置RXIM1就使能了接收FIFO中断。MIS (Masked Interrupt Status) 被屏蔽后的中断状态寄存器。MIS RIS IMSC。只有当RIS置1且IMSC对应位也使能时MIS的对应位才为1。通常中断服务程序ISR会查询MIS寄存器来判断是哪个中断源触发了本次中断。ICR (Interrupt Clear) 中断清除寄存器。这是一个只写寄存器向某位写1可以清除RIS中的对应中断标志。注意它清除的是RIS而不是MIS。对于TXRIS和RXRIS其标志会在条件不再满足时自动清除如发送FIFO数据多于4个或读取了接收FIFO数据。但对于RTRIS接收超时和RORRIS接收溢出必须手动写ICR寄存器来清除。中断配置实战流程 假设我们需要在接收FIFO中有数据RNE时产生中断。// 1. 配置SSI基本参数CR0, CR1, CPSR... // 2. 使能接收中断 HWREG(SSI0_BASE SSI_O_IMSC) | SSI_IMSC_RXIM; // 设置RXIM1 // 3. 全局使能SSI模块中断此处依赖具体MCU的中断控制器如NVIC IntEnable(INT_SSI0); // 4. 使能SSI模块 HWREG(SSI0_BASE SSI_O_CR1) | SSI_CR1_SSE;在中断服务程序中void SSI0_IRQHandler(void) { uint32_t mis HWREG(SSI0_BASE SSI_O_MIS); if (mis SSI_MIS_RXMIS) { // 判断是否为接收中断 while (HWREG(SSI0_BASE SSI_O_SR) SSI_SR_RNE) { // 循环读取直到FIFO空 uint16_t data HWREG(SSI0_BASE SSI_O_DR); // 读取数据 // ... 处理数据 } // RXRIS会自动清除无需操作ICR } // 检查其他中断源如TXMIS, RTMIS等... }2.3.3 DMACR寄存器解放CPU的利器当需要传输大量数据如读写SPI Flash的多个扇区时频繁的中断仍会消耗大量CPU资源。此时DMA直接内存访问是更好的选择。TXDMAE (位1) 发送DMA使能。置1后当发送FIFO有空闲位置时硬件会自动向DMA控制器发出请求由DMA将内存中的数据搬运到SSI的DR寄存器。RXDMAE (位0) 接收DMA使能。置1后当接收FIFO中有数据时硬件会自动请求DMA将DR寄存器中的数据搬运到指定内存。使用DMA的关键点你需要先正确配置MCU的DMA控制器设定好源地址、目标地址、传输数据量等。使能DMACR后SSI模块就与DMA控制器协同工作CPU几乎可以完全被解放。这对于需要维持高射频性能的无线应用如CC13x2/CC26x2的并发无线电操作尤为重要因为DMA传输不占用CPU总线带宽减少了对射频时序的干扰。3. I2C接口寄存器精讲与主从模式实战I2C以其简洁的两线制SDA数据线SCL时钟线和多主从支持在连接多个中低速外设如EEPROM、传感器、IO扩展芯片时极具优势。CC13x2/CC26x2的I2C模块功能完整但配置逻辑比SPI稍显复杂尤其是状态机的管理。3.1 I2C核心寄存器概览与工作模式I2C模块在寄存器层面清晰地分为**主Master和从Slave**两套几乎独立的寄存器组。这在支持多主模式或设备既可作为主机也可作为从机如智能传感器网络中时非常有用。主模式核心寄存器I2C_MSA(Master Slave Address) 写入目标从机地址和读写方向R/S位。I2C_MDR(Master Data) 读写传输的数据。I2C_MCTRL(Master Control) 控制单次传输的启动、停止、应答和运行。I2C_MTPR(Master Timer Period) 设置SCL时钟频率标准模式100kbps或快速模式400kbps。I2C_MSTAT(Master Status) 查询总线忙状态、错误和仲裁丢失。I2C_MIMR/I2C_MRIS/I2C_MMIS/I2C_MICR 主模式的中断屏蔽、原始状态、屏蔽后状态和中断清除寄存器。从模式核心寄存器I2C_SOAR(Slave Own Address) 设置本设备作为从机时的地址。I2C_SDR(Slave Data) 从机模式下的数据寄存器。I2C_SCTL(Slave Control) 从机控制寄存器。I2C_SSTAT(Slave Status) 从机状态寄存器指示数据请求方向。I2C_SIMR/I2C_SRIS/I2C_SMIS/I2C_SICR 从机模式的中断寄存器组。3.2 主模式配置与单次传输流程主模式是CC13x2作为控制器去访问其他I2C设备最常用的模式。3.2.1 速率配置MTPR寄存器计算I2C的时钟频率由I2C_MTPR寄存器决定。公式为SCL_PERIOD 2 × (1 TIMER_PRD) × (SCL_LP SCL_HP) × CLK_PRD其中SCL_LP和SCL_HP固定为6和4CLK_PRD是系统时钟周期TIMER_PRD是你要写入I2C_MTPR的值。简化计算与查表法 对于48MHz系统时钟标准模式100kbps目标SCL周期 1 / 100kHz 10 us。系统时钟周期 1 / 48MHz ≈ 20.83 ns。代入公式10 us 2 * (1TIMER_PRD) * (64) * 20.83 ns。解得TIMER_PRD ≈ 23。 实际应用中TI的技术参考手册通常会提供表格。例如对于16MHz系统时钟标准模式对应MTPR0x07快速模式对应MTPR0x01。最稳妥的方法是参考SDK中的示例代码或直接使用驱动库的初始化函数它们已经完成了这些计算。3.2.2 单次发送Master Transmit流程详解参考手册中的流程图一次完整的单次发送操作步骤如下我将结合寄存器操作进行解释等待总线空闲 读取I2C_MSTAT寄存器的BUSY位直到其为0。在多主系统中这是必须的在单主系统中可省略但保留检查是良好习惯。设置从机地址和方向 向I2C_MSA寄存器写入。高7位是地址最低位是R/S位0表示写1表示读。例如向地址0x50的EEPROM写入数据应写入0x50 1 | 0x000xA0。写入数据 将要发送的第一个字节数据写入I2C_MDR寄存器。启动传输并发送 配置I2C_MCTRL寄存器。RUN位 置1启动本次操作。START位 置1在本次传输开始时产生一个Start信号。STOP位 对于单次发送通常置1表示发送完数据后产生Stop信号。ACK位 在发送模式下此位无关因为ACK由从机发出。 例如写入0x3二进制0011即START1, STOP1, ACKX, RUN1。等待传输完成 轮询I2C_MSTAT的BUSY位直到其为0。或者使能主中断I2C_MIMR在中断服务程序中处理。检查错误 传输完成后必须检查I2C_MSTAT的ERROR位。如果为1表示从机未应答NACK本次传输失败。同时在多主系统中还应检查ARBLST仲裁丢失位。代码片段示例轮询方式// 假设I2C0基址已定义目标从机地址0x50发送单字节数据0xAB void I2C_MasterWriteByte(uint8_t slaveAddr, uint8_t data) { // 1. 可选等待总线空闲 while(HWREG(I2C0_BASE I2C_O_MSTAT) I2C_MSTAT_BUSY); // 2. 设置从机地址和写方向 HWREG(I2C0_BASE I2C_O_MSA) (slaveAddr 1) | 0x00; // R/S0, 写 // 3. 写入数据 HWREG(I2C0_BASE I2C_O_MDR) data; // 4. 启动传输产生Start发送数据产生Stop HWREG(I2C0_BASE I2C_O_MCTRL) I2C_MCTRL_START | I2C_MCTRL_STOP | I2C_MCTRL_RUN; // 5. 等待传输完成 while(HWREG(I2C0_BASE I2C_O_MSTAT) I2C_MSTAT_BUSY); // 6. 检查错误 if(HWREG(I2C0_BASE I2C_O_MSTAT) I2C_MSTAT_ERROR) { // 错误处理从机无应答 // 通常需要发送Stop条件来复位总线HWREG(I2C0_BASE I2C_O_MCTRL) I2C_MCTRL_STOP; } }3.3 带重复起始Repeated Start的复合操作I2C协议允许在一次通信中主机在不释放总线不发送Stop的情况下通过发送一个重复起始条件Repeated Start切换读写方向或寻址另一个从机。这在读取许多传感器时非常常见先写入寄存器地址再发起读操作。手册中的流程图图23-9, 23-10清晰地描述了这一过程。其核心要点是第一次传输如发送寄存器地址时MCTRL寄存器中的STOP位设为0不产生Stop。等待第一次传输完成BUSY0且无错误。不改变I2C_MSA中的地址如果地址相同或更新为新地址。进行第二次传输如读取数据这次MCTRL寄存器中START位仍置1产生Repeated StartSTOP位根据是否为最后一次传输决定读操作最后通常置1。 关键陷阱在重复起始操作中两次操作之间必须严格检查BUSY位和错误状态。如果第一次传输失败ERROR1总线可能处于挂起状态必须通过发送一个Stop条件MCTRL.STOP1来复位总线否则后续操作都会失败。3.4 从模式配置与中断处理当CC13x2需要作为I2C总线上的一个从设备例如被一个中央主机管理时需要配置从模式。设置自身地址 向I2C_SOAR寄存器写入本设备的7位I2C地址。使能与配置 通过I2C_SCLR寄存器使能从机模块。中断处理 从机通常采用中断驱动。需要使能I2C_SIMR中的相应中断位如DATAIM数据中断、STARTIM起始条件中断、STOPIM停止条件中断。中断服务程序逻辑 当从机中断触发读取I2C_SMIS确定中断源。如果是STARTMIS表示主机开始了针对本地址的通信。如果是DATAMIS需要立即读取I2C_SSTAT寄存器。若RREQ位为1表示主机请求读取数据从机发送模式应将待发送数据写入I2C_SDR。若TREQ位为1表示主机发送了数据从机接收模式应从I2C_SDR读取数据。如果是STOPMIS表示本次传输结束。从机模式对实时性要求较高必须在主机时钟超时前响应数据请求。在软件中断处理中如果处理逻辑复杂可能导致响应超时。此时可以考虑使用DMA辅助从机数据收发或者确保中断服务程序尽可能精简。4. 常见问题排查与调试技巧实录基于寄存器开发遇到问题时定位的精度更高。以下是我在项目中总结的常见问题与排查思路。4.1 SSI/SPI通信问题排查表现象可能原因排查步骤与解决方法通信完全无反应SCK无波形1. SSI模块未使能CR1.SSE0。2. GPIO引脚复用功能未正确配置。3. 时钟未使能或分频配置错误导致速率极低。1. 确认CR1寄存器的SSE位已置1。2. 检查IOCFG寄存器确保对应引脚已配置为SSI功能如IOC_IOCFGx_PORT_ID SSI_RX/TX/CLK/FSS。3. 使用逻辑分析仪抓取SCK引脚或检查CPSR和SCR配置计算实际波特率是否在预期范围。能抓到SCK波形但MOSI无数据或数据错误1. 数据位宽DSS或帧格式FRF不匹配。2. 时钟极性/相位SPO/SPH不匹配。3. 数据未右对齐当DSS16时。4. 从设备片选CS信号未正确控制。1. 核对主从设备数据手册确保DSS和FRF一致。2.用逻辑分析仪同时抓取SCK和MOSI对照从设备时序图检查数据在哪个时钟边沿被采样据此调整SPO/SPH。3. 检查发送数据时是否将数据放在了DR寄存器的低位右对齐。4. SSI硬件可能管理FSS片选信号也可能需要你用GPIO手动控制。确认配置正确。能发送但接收数据全为0xFF或0x001. 从设备未正确响应或损坏。2. MISO引脚连接错误或配置为输入。3. 在回环模式下测试正常但外接设备异常。1. 首先使能SSI的回环模式CR1.LBM1自发自收。若正常则SSI核心和软件配置基本正确问题在外部链路或从设备。2. 检查MISO引脚的IOCFG配置确保是输入模式。3. 测量从设备电源、复位引脚确认其已正常工作。中断无法触发1. 中断未在NVIC嵌套向量中断控制器中使能。2. IMSC寄存器中对应中断掩码未打开。3. 中断标志已置位但未及时清除导致后续中断被屏蔽。1. 确认除了配置IMSC还通过IntEnable()等函数使能了MCU级别的SSI中断。2. 在中断服务程序开头读取MIS寄存器判断中断源并在处理完后根据中断类型清除RIS标志对于RTRIS和RORRIS需写ICR寄存器。4.2 I2C通信问题排查表现象可能原因排查步骤与解决方法总线死锁SCL被拉低1. 从设备在传输中崩溃持续拉低SCL。2. 主机程序异常未正确完成或终止传输。1.这是I2C总线最棘手的问题。首先尝试用软件多次发送Stop条件MCTRL.STOP1。2. 如果无效需硬件复位从设备或短暂将SCL和SDA引脚配置为GPIO输出高电平手动产生几个时钟脉冲Clock Stretching来“唤醒”从设备然后再重新初始化为I2C功能。这是一种经典的I2C总线恢复技巧。从机无应答NACKMSTAT.ERROR11. 从机地址错误。2. 从设备不存在、未上电或损坏。3. 总线上下拉电阻不合适太大致使上升沿太慢太小驱动不足。1. 用逻辑分析仪抓取波形确认发送的7位地址1位R/W位是否正确。注意地址通常是7位发送时需要左移1位。2. 检查从设备电源、焊接。3. I2C总线需要上拉电阻通常4.7kΩ-10kΩ。测量SDA/SCL线上的波形上升沿应陡峭。过长上升时间可能导致识别错误。仲裁丢失ARBLST1多主系统中两个主机同时发起传输。1. 这是正常现象说明本机在仲裁中失败。程序应检测到此标志等待总线空闲后重试。2. 确保仲裁丢失后主机状态机能正确回到空闲状态而不是僵死。重复起始Repeated Start操作失败1. 第一次传输后未检查BUSY和ERROR就发起第二次操作。2.MCTRL寄存器配置顺序错误。1.严格遵循手册流程图第一次传输STOP0后等待BUSY0检查ERROR0。2. 第二次传输时确保START1以产生重复起始条件。4.3 高级调试与性能优化心得逻辑分析仪是你的最佳伙伴 无论是SPI还是I2C一个支持协议解码的逻辑分析仪如Saleae能直观显示时钟、数据线上的每一位以及解码后的字节。遇到问题时首先抓取波形比对时序图绝大部分硬件通信问题都能迎刃而解。充分利用回环与内部Loopback SSI的LBM位和I2C的LPBK位在MCR寄存器中是验证驱动逻辑的“安全沙箱”。在连接真实外设前务必在回环模式下测试基本的读写和中断功能确保MCU侧的软硬件基础是稳固的。中断与DMA的权衡 对于单次或低速操作轮询足够简单。对于连续或高速数据流中断是必须的。但对于大数据块传输如32字节一定要考虑使用DMA。在CC13x2/CC26x2上DMA不仅可以解放CPU更重要的是能减少总线占用这对于需要同时处理射频任务如BLE连接维护的应用至关重要能有效避免因CPU频繁服务串口中断而导致的射频时序错乱或连接断开。电源与噪声管理 通信不稳定有时问题不在软件。确保MCU和外部设备的供电干净、稳定。在高速SPI通信下过长的飞线会引入振铃和串扰可能导致数据错误。尽量缩短走线并在信号线靠近MCU端串联一个小电阻如22-33欧姆进行阻抗匹配能显著改善信号质量。仔细阅读数据手册的电气参数章节 特别是I2C的上升时间、下降时间SPI的最大时钟频率等。确保你的配置如GPIO驱动强度、上下拉电阻、时钟分频满足所有外设的要求。一个在实验室温良环境下工作的配置可能在高温或低温下因时序裕量不足而失败。