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. SSI(SPI)接口寄存器深度解析与实战配置
SSI(Synchronous Serial Interface)在CC13x2/CC26x2上通常被用作实现SPI(Serial Peripheral Interface)协议。与通用的UART不同,SPI是一种全双工、同步的通信总线,其性能高度依赖于对时钟极性、相位、速率等参数的精确控制。这些控制,最终都落在对一组特定内存地址(即寄存器)的读写操作上。
2.1 核心控制寄存器:CR0与CR1
CR0和CR1是SPI通信的“大脑”,决定了通信的基本框架。
2.1.1 CR0寄存器:定义通信“方言”
CR0寄存器负责设定数据帧的格式、大小和时钟的基本特性。其位域配置是SPI与外设能够“听懂”彼此的前提。
DSS (Data Size Select, 位[3:0]): 选择数据位宽,从4位到16位。这是最基础的配置,必须与从设备的数据宽度严格匹配。例如,驱动一个8位ADC时,应配置为
0x7(8_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)。
SPO=0, SPH=0(模式0): 时钟空闲时为低电平,数据在时钟的第一个边沿(上升沿)采样。SPO=0, SPH=1(模式1): 时钟空闲时为低电平,数据在时钟的第二个边沿(下降沿)采样。SPO=1, SPH=0(模式2): 时钟空闲时为高电平,数据在时钟的第一个边沿(下降沿)采样。SPO=1, SPH=1(模式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。在SSE=0时,可以安全修改MS位。
MS (Master/Slave Select, 位2): 主从模式选择。0为主机,1为从机。在CC13x2作为主机控制外设时,设为0。
SOD (Slave Output Disable, 位3): 从机输出禁用。仅在从机模式(MS=1)下有意义。在多从机系统中,如果多个从机的MISO线被连接在一起(即“线与”),则需要通过此位控制哪个从机有权驱动总线。对于主机或单从机系统,通常保持为0。
2.2 时钟与数据寄存器:CPSR与DR
2.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 * (4+1)) = 0.96 Mbps,误差4%。若想更精确,可以调整CPSDVSR为8,则SCR+1 = 48/(81)=6, SCR=5, 实际波特率 = 48/(86)=1.0 Mbps,完全匹配。
2.2.2 DR寄存器:数据交换的窗口
DR寄存器是双向的16位数据寄存器。写入时,数据进入发送FIFO;读取时,从接收FIFO取出数据。> 重要提醒:当DSS配置为小于16位时(例如8位),你写入DR的数据必须右对齐。例如要发送0xAB(8位),应写入0x00AB,而不是0xAB00。硬件发送逻辑会自动忽略高8位。同样,接收到的8位数据,硬件会自动右对齐,你读到的DR寄存器低8位就是有效数据。忽略这一点是新手常犯的错误,会导致数据错乱。
2.3 状态与中断寄存器:高效通信的保障
轮询(Polling)和中断(Interrupt)是处理SPI数据的两种方式。对于低速或不频繁的操作,轮询简单;但对于需要及时响应或大数据量传输,中断乃至DMA才是正道。
2.3.1 SR寄存器:实时状态窥镜
SR寄存器提供了通信链路和FIFO的实时状态。
- TFE/TNF (位0/位1): 发送FIFO空/非满。
TFE=1表示发送FIFO完全空,可以安全写入新数据(但此时写入会直接进入移位器,可能来不及处理)。更常用的是TNF,当TNF=1时,表示发送FIFO未满,可以写入数据。在中断发送中,我们通常检查TNF来决定是否填充下一个数据。 - RNE/RFF (位2/位3): 接收FIFO非空/满。
RNE=1表示有数据可读。RFF=1表示接收FIFO已满,如果此时继续有数据到来,会发生溢出(Overrun)。 - BSY (位4): 忙标志。当
BSY=1时,表示SSI正在发送或接收一帧数据,或者发送FIFO非空。在修改CR0、CR1等关键配置寄存器前,务必确保BSY=0且SSE=0,否则可能导致不可预知的行为。
2.3.2 中断寄存器组:IMSC, RIS, MIS, ICR
这组寄存器构成了一个完整的中断管理系统,理解其工作流至关重要。
- RIS (Raw Interrupt Status): 原始中断状态寄存器。只要条件满足,对应位就被硬件置1,不受任何屏蔽影响。例如,当接收FIFO中的数据达到4个或更多时,
RXRIS位自动置1。 - IMSC (Interrupt Mask Set and Clear): 中断屏蔽寄存器。你可以通过写1来使能某个中断源,写0来禁用它。例如,设置
RXIM=1,就使能了接收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; // 设置RXIM=1 // 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和4,CLK_PRD是系统时钟周期,TIMER_PRD是你要写入I2C_MTPR的值。
简化计算与查表法: 对于48MHz系统时钟,标准模式(100kbps):
- 目标SCL周期 = 1 / 100kHz = 10 us。
- 系统时钟周期 = 1 / 48MHz ≈ 20.83 ns。
- 代入公式:10 us = 2 * (1+TIMER_PRD) * (6+4) * 20.83 ns。
- 解得
TIMER_PRD ≈ 23。 实际应用中,TI的技术参考手册通常会提供表格。例如,对于16MHz系统时钟,标准模式对应MTPR=0x07,快速模式对应MTPR=0x01。最稳妥的方法是参考SDK中的示例代码或直接使用驱动库的初始化函数,它们已经完成了这些计算。
3.2.2 单次发送(Master Transmit)流程详解
参考手册中的流程图,一次完整的单次发送操作步骤如下,我将结合寄存器操作进行解释:
- 等待总线空闲: 读取
I2C_MSTAT寄存器的BUSY位,直到其为0。在多主系统中,这是必须的;在单主系统中可省略,但保留检查是良好习惯。 - 设置从机地址和方向: 向
I2C_MSA寄存器写入。高7位是地址,最低位是R/S位(0表示写,1表示读)。例如,向地址0x50的EEPROM写入数据,应写入0x50 << 1 | 0x00=0xA0。 - 写入数据: 将要发送的第一个字节数据写入
I2C_MDR寄存器。 - 启动传输并发送: 配置
I2C_MCTRL寄存器。RUN位: 置1启动本次操作。START位: 置1,在本次传输开始时产生一个Start信号。STOP位: 对于单次发送,通常置1,表示发送完数据后产生Stop信号。ACK位: 在发送模式下,此位无关(因为ACK由从机发出)。 例如,写入0x3(二进制0011,即START=1, STOP=1, ACK=X, RUN=1)。
- 等待传输完成: 轮询
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/S=0, 写 // 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)。 - 等待第一次传输完成(
BUSY=0)且无错误。 - 不改变
I2C_MSA中的地址(如果地址相同),或更新为新地址。 - 进行第二次传输(如读取数据),这次
MCTRL寄存器中START位仍置1(产生Repeated Start),STOP位根据是否为最后一次传输决定(读操作最后通常置1)。
> 关键陷阱:在重复起始操作中,两次操作之间必须严格检查BUSY位和错误状态。如果第一次传输失败(ERROR=1),总线可能处于挂起状态,必须通过发送一个Stop条件(MCTRL.STOP=1)来复位总线,否则后续操作都会失败。
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.SSE=0)。 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. 数据未右对齐(当DSS<16时)。 4. 从设备片选(CS)信号未正确控制。 | 1. 核对主从设备数据手册,确保DSS和FRF一致。 2.用逻辑分析仪同时抓取SCK和MOSI,对照从设备时序图,检查数据在哪个时钟边沿被采样,据此调整SPO/SPH。 3. 检查发送数据时,是否将数据放在了DR寄存器的低位(右对齐)。 4. SSI硬件可能管理FSS(片选)信号,也可能需要你用GPIO手动控制。确认配置正确。 |
| 能发送,但接收数据全为0xFF或0x00 | 1. 从设备未正确响应或损坏。 2. MISO引脚连接错误或配置为输入。 3. 在回环模式下测试正常,但外接设备异常。 | 1. 首先使能SSI的回环模式(CR1.LBM=1),自发自收。若正常,则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.STOP=1)。2. 如果无效,需硬件复位从设备,或短暂将SCL和SDA引脚配置为GPIO输出高电平,手动产生几个时钟脉冲(Clock Stretching)来“唤醒”从设备,然后再重新初始化为I2C功能。这是一种经典的I2C总线恢复技巧。 |
| 从机无应答(NACK),MSTAT.ERROR=1 | 1. 从机地址错误。 2. 从设备不存在、未上电或损坏。 3. 总线上下拉电阻不合适(太大致使上升沿太慢,太小驱动不足)。 | 1. 用逻辑分析仪抓取波形,确认发送的7位地址+1位R/W位是否正确。注意地址通常是7位,发送时需要左移1位。 2. 检查从设备电源、焊接。 3. I2C总线需要上拉电阻(通常4.7kΩ-10kΩ)。测量SDA/SCL线上的波形,上升沿应陡峭。过长上升时间可能导致识别错误。 |
| 仲裁丢失(ARBLST=1) | 多主系统中,两个主机同时发起传输。 | 1. 这是正常现象,说明本机在仲裁中失败。程序应检测到此标志,等待总线空闲后重试。 2. 确保仲裁丢失后,主机状态机能正确回到空闲状态,而不是僵死。 |
| 重复起始(Repeated Start)操作失败 | 1. 第一次传输后未检查BUSY和ERROR就发起第二次操作。2. MCTRL寄存器配置顺序错误。 | 1.严格遵循手册流程图:第一次传输(STOP=0)后,等待BUSY=0,检查ERROR=0。2. 第二次传输时,确保 START=1以产生重复起始条件。 |
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驱动强度、上下拉电阻、时钟分频)满足所有外设的要求。一个在实验室温良环境下工作的配置,可能在高温或低温下因时序裕量不足而失败。