CC13x2/CC26x2 GPT定时器核心寄存器解析与实战配置指南 1. GPT定时器在CC13x2/CC26x2系统中的核心地位在嵌入式开发尤其是无线物联网设备开发中时序控制是决定系统稳定性和性能的基石。无论是处理无线协议栈的严格时序要求还是驱动传感器进行周期性采样亦或是生成精确的PWM信号来控制电机或LED亮度都离不开一个可靠、灵活的定时器模块。CC13x2和CC26x2系列作为德州仪器TISimpleLink™平台下的明星产品其内置的通用定时器GPT模块功能之强大、配置之灵活常常是项目成败的关键。很多开发者初次接触其长达数十页的技术手册时面对密密麻麻的寄存器位域描述容易感到无从下手。实际上只要理解了GPT模块的设计哲学和核心寄存器组的协作关系就能将其强大的能力为我所用。GPT本质上是一个可编程的计数器其核心思想是通过对计数器的“装载值”、“匹配值”和“计数方向”进行配置来产生周期性的“超时”事件。这个超时事件可以触发中断通知CPU进行处理也可以直接翻转一个GPIO引脚生成PWM波还可以在外部引脚出现特定边沿时捕获当前的计数值用于测量脉冲宽度或频率。CC13x2/CC26x2的GPT模块提供了两个独立的16位定时器Timer A和Timer B它们既可以独立工作也可以组合成一个32位定时器使用这为不同精度的定时需求提供了极大的灵活性。而这一切功能的实现都依赖于对一系列内存映射寄存器的精确配置。本文将抛开手册式的平铺直叙以一个实际开发者的视角深入解析这些关键寄存器的“脾气秉性”并结合典型应用场景手把手带你掌握配置要点和避坑技巧。2. 核心寄存器组功能解析与设计思路GPT的寄存器虽然数量众多但并非杂乱无章。我们可以将其分为几个功能明确的组别来理解这有助于我们在编程时建立清晰的逻辑脉络。2.1 全局配置与模式选择寄存器这是定时器功能的“总开关”和“模式选择器”决定了定时器的基本框架。CFGConfiguration Register偏移地址 0h这是第一个需要配置的寄存器。它只有最低3位CFG[2:0]有效用于选择定时器的整体结构。设置为0h时Timer A和Timer B合并为一个32位定时器32BIT_TIMER。设置为4h时则配置为两个独立的16位定时器16BIT_TIMER。这个选择是后续所有配置的基础。例如当你需要非常长的定时周期超过16位计数器所能表示的范围时就必须选择32位模式。而在需要同时进行两项独立定时任务的场景如一个定时器用于PWM输出另一个用于输入捕获则选择16位模式。TAMR/TBMRTimer A/B Mode Register偏移地址 4h/8h这两个寄存器结构完全对称分别控制Timer A和Timer B的工作模式是功能配置的核心。其位域非常丰富TAMR/TBMR[1:0] (Mode): 这是模式选择的核心位。01为单次触发One-Shot模式计数器减到0或加到装载值后停止需要软件重新触发10为周期Periodic模式计数器自动重载持续运行这是最常用的定时中断模式11为输入捕获Capture模式用于测量外部信号。TAMR/TBMR[2] (Capture Mode): 仅在捕获模式下有效。0为边沿计数Edge-Count模式记录边沿事件发生的次数1为边沿时间Edge-Time模式记录边沿事件发生时刻的计数器值常用于测频或测脉宽。TAMR/TBMR[3] (Alternate Mode):0为捕获/比较模式1为PWM模式。注意要启用PWM模式必须先将TACM/TBCM位捕获模式选择清零并且将TAMR/TBMR[1:0]设置为10周期模式。这是一个常见的配置陷阱顺序错误会导致PWM无法正常输出。TAMR/TBMR[4] (Count Direction):0向下计数1向上计数。在PWM模式下计数方向会直接影响输出波形的极性需要结合其他配置仔细考量。TAMR/TBMR[5] (Match Interrupt Enable): 匹配中断使能。当计数器值等于TAMATCHR/TBMATCHR中设定的匹配值时是否产生中断。TAMR/TBMR[8] (Interval Load Write): 决定了TAILR/TBILR间隔加载寄存器的值何时更新到实际计数器TAR/TBR。0表示下一个时钟周期立即更新1表示等到下一次超时计数器归零或达到装载值时才更新。在需要动态、平滑地改变PWM占空比时通常设置为1在下次超时更新以避免当前周期波形出现毛刺。TAMR/TBMR[10] (Match Register Update): 决定了TAMATCHR/TAPMR匹配寄存器的值何时生效。与TAILD类似0立即更新1下次超时更新。在动态调整PWM频率或占空比时通常将TAILD和TAMRSU配合使用确保装载值和匹配值在同一时刻下一次超时同步更新保证波形连续性。实操心得在配置PWM模式时务必遵循“先模式后方向再使能”的步骤。即先设置TAMR[1:0]2周期TACM0TAAMS1PWM模式然后设置TACDIR确定计数方向最后再使能定时器CTL.TAEN1。如果顺序错乱可能会观察到不可预期的输出。2.2 定时器核心数值寄存器这组寄存器直接决定了定时器的时序参数是计算和配置的重点。TAILR/TBILRTimer A/B Interval Load Register偏移地址 28h/2Ch这是定时器的“重装载值”或“周期寄存器”。在周期模式下计数器减计数到0或加计数到此值时会产生超时事件并自动重载此值重新开始计数。因此定时周期 (TAILR 1) * 时钟周期。例如系统时钟为48MHz要实现1ms的定时中断则TAILR应设置为(0.001s * 48,000,000 Hz) - 1 47999。它的复位值很有意思TAILR是FFFFFFFFh32位最大值而TBILR是0000FFFFh16位最大值这暗示了它们在32位和16位模式下的默认位宽。TAMATCHR/TBMATCHRTimer A/B Match Register偏移地址 30h/34h这是“匹配寄存器”是GPT模块灵活性的关键。在不同模式下作用不同在周期/单次模式当使能了匹配中断TAMR.TAMIE1时计数器值等于此寄存器值时会触发匹配中断。这允许你在一个定时周期内产生多个中断事件。在PWM模式此寄存器决定了输出波形的占空比。在向下计数模式下计数器从TAILR值开始递减当计数值大于TAMATCHR时输出一种电平小于或等于时输出另一种电平。因此占空比 (TAMATCHR / TAILR) * 100%。在向上计数模式下逻辑相反。在边沿计数捕获模式此寄存器与TAILR共同决定要捕获的边沿事件数量。总事件数 TAILR - TAMATCHR。TAPR/TBPRTimer A/B Prescale Register偏移地址 38h/3Ch预分频器寄存器。当需要的定时周期很长即使TAILR取最大值也无法满足时就需要预分频器来扩展定时范围。它是一个8位寄存器实际的分频系数 TAPR 1。例如TAPR设置为9则分频系数为10定时器的计数时钟变为输入时钟的1/10。此时定时周期 (TAILR 1) * (TAPR 1) * 时钟周期。在向下计数的周期/单次模式中它是一个“真正的”预分频器会先于主计数器递减到0。在其他模式如PWM向上计数下它只是计数器的高位扩展在16位模式下提供额外的8位与主计数器一起构成24位计数器。TAR/TBR TAV/TBVTimer A/B Register Value偏移地址 48h/4Ch 50h/54h这是反映当前计数器值的寄存器。TAR/TBR是“快照”值其更新时机受TAILD/TBILD控制。TAV/TBV则是“自由运行”值随时读取都能获得当前精确的计数值在需要高精度时间戳或调试时非常有用。在输入捕获模式下TAR/TBR中存储的就是捕获事件发生时的时刻值。2.3 中断与事件控制寄存器组嵌入式系统的实时性很大程度上依赖于高效的中断处理GPT提供了完善的中断管理机制。IMRInterrupt Mask Register偏移地址 18h中断屏蔽寄存器。你可以把它想象成每个中断源的“开关”。只有相应位被置1该中断源如超时、匹配、捕获事件发生时才会将状态传递到下一级MIS寄存器并可能向CPU申请中断。例如如果你只关心定时器A的超时中断那么只需将TATOIM位第0位置1即可其他位保持为0这样可以避免不必要的中断打扰。RISRaw Interrupt Status Register偏移地址 1Ch原始中断状态寄存器。它反映了中断事件是否真实发生无论IMR是否屏蔽。这是一个只读寄存器。当定时器A超时TATORIS位或匹配事件发生TAMRIS位时对应的位会自动被硬件置1。它是中断状态的“源头”。MISMasked Interrupt Status Register偏移地址 20h被屏蔽后的中断状态寄存器。它的值等于RIS IMR按位与。也就是说只有那些既发生了RIS1又被允许了IMR1的中断才会在MIS中显示为1。通常CPU的中断服务程序ISR会查询这个寄存器来判断具体是哪个被使能的中断源触发了本次中断。ICLRInterrupt Clear Register偏移地址 24h中断清除寄存器。这是一个“写1清零”的寄存器。在中断服务程序ISR中处理完某个中断事件后必须向ICLR中对应的位写1以清除RIS和MIS中的相应状态位。这是防止同一中断被重复触发、导致ISR死循环的关键操作。例如处理完定时器A超时中断后需要执行HWREG(GPT0_BASE GPT_O_ICLR) GPT_ICLR_TATOCINT;。注意事项清除中断状态是ISR中的规定动作务必在ISR入口或执行完关键操作后立即进行。有些开发者喜欢在ISR末尾清除但如果ISR执行时间较长可能会错过在此期间发生的下一次中断事件。更稳妥的做法是在ISR一开始就读取MIS保存状态然后立刻清除对应的中断标志。DMAEVDMA Event Register偏移地址 6ChDMA事件触发使能寄存器。在需要高频、批量数据传输且不希望CPU频繁被中断打扰的场景如高速ADC采样数据搬运DMA是提升系统效率的利器。GPT可以配置在超时、匹配或捕获事件发生时自动触发DMA传输。例如使能TATODMAEN位后每次定时器A超时都会产生一个DMA请求可以将ADC结果寄存器中的数据自动搬运到指定的内存缓冲区中。2.4 其他辅助功能寄存器CTLControl Register偏移地址 Ch控制寄存器主要包含定时器使能位TAEN/TBEN和调试暂停控制位TASTALL/TBSTALL。TAEN/TBEN是定时器工作的总闸门在所有参数配置完成后最后将此位置1定时器才开始计数。TASTALL/TBSTALL位则在调试时非常有用当CPU被调试器暂停时此位为1会使定时器也暂停计数便于观察定时器在断点处的状态为0则定时器继续运行模拟真实环境。SYNCSynchronize Register偏移地址 10h同步寄存器。CC13x2/CC26x2有多个GPT模块GPT0, GPT1等。此寄存器可以用于软件同步多个定时器的超时事件。例如向SYNC0字段写入3可以同时触发GPT0的Timer A和Timer B的超时事件如果它们配置在“等待触发”模式。这在需要多个定时器严格同步启动的复杂时序控制中非常有用。ANDCCPCombined CCP Output Register偏移地址 FB4h这是一个很有意思的寄存器用于将Timer A和Timer B的PWM输出信号进行逻辑“与”操作。当CCP_AND_EN置1时Timer A的PWM输出引脚实际输出的是Timer A和Timer B内部PWM信号的“与”结果。这可以用来生成更复杂的波形例如带有死区时间的互补PWM对对于驱动H桥电路至关重要。3. 典型应用场景配置实战与代码剖析理解了寄存器功能后我们通过几个典型场景来看如何将它们组合起来完成实际任务。我将使用TI的DriverLib库函数与直接寄存器操作两种方式对比说明这有助于你理解底层原理。3.1 场景一配置1ms周期性定时中断这是最常见的需求用于提供系统心跳或任务调度时钟。步骤与原理分析确定时钟源与分频假设使用48MHz系统时钟。要实现1ms周期需要计数值 N 周期 / 时钟周期 0.001s / (1/48e6)s 48000。由于计数器从0开始计数到N-1超时所以重载值TAILR 48000 - 1 47999。配置GPT为32位周期定时器设置CFG寄存器为032BIT_TIMER。这样我们获得了一个完整的32位计数器无需担心溢出。配置Timer A模式设置TAMR寄存器。TAMR[1:0]2周期模式TAMR[4]0向下计数。其他位如匹配中断TAMIE可根据需要设置本例中我们使用超时中断故先保持为0。设置定时周期将计算好的47999写入TAILR寄存器。配置中断在IMR寄存器中使能超时中断TATOIM位置1。在NVIC嵌套向量中断控制器中使能GPT对应的中断通道。启动定时器将CTL寄存器的TAEN位置1。DriverLib示例代码#include ti/drivers/dpl/ClockP.h #include ti/drivers/dpl/HwiP.h #include ti/devices/cc13x2_cc26x2/driverlib/timer.h #include ti/devices/cc13x2_cc26x2/driverlib/interrupt.h // 假设使用GPT0 #define GPT0_BASE 0x40010000 void GPT0_IntHandler(void) { // 1. 读取中断状态判断来源 uint32_t intStatus TimerIntStatus(GPT0_BASE, true); // 2. 清除中断标志这是必须的 TimerIntClear(GPT0_BASE, intStatus); // 3. 执行你的中断任务例如翻转一个LED // GPIO_toggle(...); } void init_1ms_timer(void) { // 步骤12: 启用GPT0外设时钟并配置为32位周期定时器 TimerConfigure(GPT0_BASE, TIMER_CFG_PERIODIC); // 步骤3: 设置定时周期 (1ms 48MHz) TimerLoadSet(GPT0_BASE, TIMER_A, 47999); // 步骤4: 注册中断处理函数并使能中断 TimerIntRegister(GPT0_BASE, TIMER_A, GPT0_IntHandler); TimerIntEnable(GPT0_BASE, TIMER_TIMA_TIMEOUT); // 使能超时中断 // 步骤5: 在NVIC中使能GPT0中断 IntEnable(INT_TIMER0A); // 步骤6: 启动定时器 TimerEnable(GPT0_BASE, TIMER_A); }直接寄存器操作更接近本质#define HWREG(x) (*((volatile uint32_t *)(x))) #define GPT0_BASE 0x40010000 #define GPT_O_CFG 0x00000000 #define GPT_O_TAMR 0x00000004 #define GPT_O_TAILR 0x00000028 #define GPT_O_IMR 0x00000018 #define GPT_O_CTL 0x0000000C #define GPT_O_ICLR 0x00000024 // 寄存器位定义 #define GPT_CFG_32BIT_TIMER 0x0 #define GPT_TAMR_TAMR_PERIODIC 0x2 #define GPT_TAMR_TACDIR_DOWN 0x0 #define GPT_IMR_TATOIM 0x00000001 #define GPT_CTL_TAEN 0x00000001 #define GPT_ICLR_TATOCINT 0x00000001 void init_1ms_timer_direct(void) { // 1. 配置为32位定时器 HWREG(GPT0_BASE GPT_O_CFG) GPT_CFG_32BIT_TIMER; // 2. 配置Timer A为向下计数的周期模式 HWREG(GPT0_BASE GPT_O_TAMR) (GPT_TAMR_TAMR_PERIODIC | GPT_TAMR_TACDIR_DOWN); // 3. 设置重载值 HWREG(GPT0_BASE GPT_O_TAILR) 47999; // 4. 使能超时中断 HWREG(GPT0_BASE GPT_O_IMR) | GPT_IMR_TATOIM; // 5. 启动定时器 HWREG(GPT0_BASE GPT_O_CTL) | GPT_CTL_TAEN; } // 在中断服务程序中 void GPT0A_IRQHandler(void) { // 清除中断标志 HWREG(GPT0_BASE GPT_O_ICLR) GPT_ICLR_TATOCINT; // ... 处理任务 }3.2 场景二生成一路1kHz占空比30%的PWM信号PWM常用于控制亮度、速度或模拟电压输出。步骤与原理分析假设向下计数模式确定时钟与周期仍用48MHz时钟。PWM频率1kHz则周期T1ms。计数值计算同上TAILR 47999。计算匹配值占空比30%则高电平时间 0.3 * 1ms 0.3ms。在向下计数模式中计数器从TAILR递减到0。PWM输出在计数值大于匹配值时为高或低取决于极性小于等于匹配值时翻转。因此匹配值TAMATCHR TAILR * (1 - 占空比) 47999 * 0.7 ≈ 33599。更通用的公式是TAMATCHR TAILR - (TAILR 1) * 占空比。配置GPT为16位PWM模式设置CFG为416BIT_TIMER。设置TAMR寄存器TAMR[1:0]2周期模式TAMR[2]0非捕获模式TAMR[3]1PWM模式TAMR[4]0向下计数。同时为了动态更新占空比时波形平滑建议设置TAMR[8]1TAILD下次超时更新装载值和TAMR[10]1TAMRSU下次超时更新匹配值。设置周期与匹配值将计算好的值写入TAILR和TAMATCHR。配置PWM输出引脚需要通过IOC输入输出控制器将对应的CCP捕获/比较/PWM引脚功能映射到具体的GPIO上并将GPIO配置为外设输出模式。启动定时器置位CTL.TAEN。关键配置详解计数方向与PWM极性在向下计数模式TACDIR0下PWM输出行为由TAMR[11]TAPLOPWM传统操作位和CTL[6]TAPWMLPWM输出电平控制位共同决定。通常保持TAPLO0传统模式则输出在计数器值大于匹配值时为“有效电平”由其他逻辑决定小于等于时翻转。TAPWML可以反转最终输出。向上计数模式逻辑相反。务必结合示波器观察来确定最终极性。动态更新占空比这是PWM应用中的常见需求。由于我们设置了TAILD和TAMRSU为1因此可以在任何时刻安全地写入新的TAILR改频率或TAMATCHR改占空比新值会在当前PWM周期结束后、下一个周期开始时生效从而避免了输出波形出现“毛刺”或“窄脉冲”。代码片段使用DriverLibvoid init_1kHz_30pct_pwm(void) { // 1. 配置为16位PWM向下计数模式 TimerConfigure(GPT0_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM)); // 2. 设置PWM周期 (1kHz) TimerLoadSet(GPT0_BASE, TIMER_A, 47999); // TAILR // 3. 设置PWM匹配值 (30%占空比) // 对于向下计数Match Load - (Load1)*DutyCycle uint32_t matchValue 47999 - (uint32_t)(48000 * 0.3); TimerMatchSet(GPT0_BASE, TIMER_A, matchValue); // TAMATCHR // 4. 配置PWM输出引脚 (例如将CCP0映射到GPIO引脚) // 这需要配合GPIO驱动设置引脚复用功能为GPT0_CCP0 // IOCPortConfigureSet(GPIO_PORT, GPIO_PIN, IOC_PORT_MCU_PORT_EVENT0, ...); // 5. 启动定时器A TimerEnable(GPT0_BASE, TIMER_A); } // 动态改变占空比到60% void change_pwm_duty_to_60pct(void) { uint32_t newMatchValue 47999 - (uint32_t)(48000 * 0.6); TimerMatchSet(GPT0_BASE, TIMER_A, newMatchValue); // 新值将在下个周期生效 }3.3 场景三测量外部脉冲宽度输入捕获输入捕获功能常用于编码器读数、红外遥控信号解码或超声波测距。步骤与原理分析边沿时间模式配置GPT为输入捕获模式设置CFG为416BIT_TIMER。设置TAMR寄存器TAMR[1:0]3捕获模式TAMR[2]1边沿时间模式Edge-Time。通过CTL[3:2]TAEVENT选择捕获边沿例如0x1为下降沿0x0为上升沿0x3为双边沿。配置捕获引脚将对应的CCP引脚通过IOC配置为输入并映射到GPT模块。使能捕获中断在IMR寄存器中使能捕获事件中断CAEIM或捕获匹配中断CAMIM。通常使用捕获事件中断它在指定边沿到来时立即触发。启动定时器置位CTL.TAEN。定时器开始自由运行通常向上计数从0开始。中断处理当指定边沿到来时触发中断。在中断服务程序中读取TAR寄存器的值这个值就是边沿发生时定时器的计数值。连续捕获两个边沿如上升沿和下降沿的时刻值它们的差值乘以时钟周期就是脉冲宽度。注意事项与高级技巧计数器溢出处理在测量长脉冲时计数器可能会溢出归零。为了正确计算时间差需要在中断服务程序中维护一个溢出计数器。每次发生超时中断TATOIM时将该计数器加1。计算脉冲宽度时不仅要考虑两次捕获的TAR值之差还要加上溢出次数乘以计数器的满量程时间。提高测量精度与量程可以启用预分频器TAPR但这会降低时间分辨率。更好的方法是利用GPT的32位模式或者使用Timer A和Timer B串联通过TBMR.TBWOT位配置Timer B等待Timer A的触发来虚拟扩展位数。去抖与滤波对于有噪声的输入信号GPT模块本身不提供硬件滤波。需要在软件中断处理中增加去抖逻辑例如连续采样几次确认边沿有效或者使用GPIO模块自带的数字滤波器如果MCU支持。捕获模式代码框架volatile uint32_t firstEdgeCapture 0; volatile uint32_t pulseWidthTicks 0; volatile bool isFirstEdgeCaptured false; void GPT0_Capture_IRQHandler(void) { uint32_t intStatus TimerIntStatus(GPT0_BASE, true); TimerIntClear(GPT0_BASE, intStatus); if (intStatus TIMER_CAPA_EVENT) { // 捕获事件中断 uint32_t currentCapture TimerValueGet(GPT0_BASE, TIMER_A); // 读取TAR if (!isFirstEdgeCaptured) { firstEdgeCapture currentCapture; isFirstEdgeCaptured true; // 可选切换捕获边沿准备捕获下一个边沿 // TimerControlLevel(GPT0_BASE, TIMER_A, ...); } else { uint32_t secondEdgeCapture currentCapture; // 计算差值注意处理计数器溢出 if (secondEdgeCapture firstEdgeCapture) { pulseWidthTicks secondEdgeCapture - firstEdgeCapture; } else { // 发生了溢出需要加上计数器模值 pulseWidthTicks (0xFFFF - firstEdgeCapture) secondEdgeCapture 1; } isFirstEdgeCaptured false; // 脉冲宽度计算完成可供主循环使用 } } } void init_input_capture(void) { // 1. 配置为16位边沿时间捕获模式捕获上升沿 TimerConfigure(GPT0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP); TimerControlEvent(GPT0_BASE, TIMER_A, TIMER_EVENT_POS_EDGE); // 2. 使能捕获事件中断 TimerIntEnable(GPT0_BASE, TIMER_CAPA_EVENT); // 3. 注册中断、配置NVIC略 // 4. 启动定时器 TimerEnable(GPT0_BASE, TIMER_A); }4. 高级功能与配置陷阱深度剖析掌握了基本操作后一些高级功能和潜在陷阱决定了你的代码是否健壮、高效。4.1 预分频器的两种角色与计算误区预分频器TAPR/TBPR的行为根据模式不同而有差异这是最容易混淆的地方。在向下计数的周期/单次模式One-Shot/Periodic Down它是一个“真正的”预分频器。计数器的工作流程是预分频器从设定值递减到0然后主计数器TAR减1预分频器重载。此时定时周期 (TAILR 1) * (TAPR 1) * T_clk。例如TAPR255TAILR65535则最大定时周期可达 (65536 * 256) 个时钟周期。在其他模式如PWM Up, Capture它仅仅是计数器的高位扩展。在16位模式下TAR是16位TAPR作为高8位共同组成一个24位的计数器。此时计数范围扩展了256倍但不是分频。计数值是(TAPR 16) | TAR。计算时间时直接用这个24位值乘以时钟周期即可。陷阱在PWM模式下错误地认为TAPR是分频器从而错误计算频率。例如想要1MHz的PWM48MHz时钟周期48个ticks却设置了TAPR1以为能把频率降到500kHz结果实际计数器变成了一个24位计数器周期值TAILR需要按24位来理解导致实际频率极低。4.2 同步SYNC与等待触发WOT功能实现精准协同在多定时器协同或主从控制的场景下SYNC和WOT功能至关重要。SYNC寄存器用于软件强制同步。例如系统中有GPT0和GPT1都需要从某个绝对时间点开始计时。可以先配置好两个定时器的参数但先不启动TAEN0。然后先启动GPT0紧接着向SYNC1寄存器写入1这将立即触发GPT1的Timer A超时事件。由于GPT1配置为等待触发模式见下这个超时事件会启动它的计数器。这样就实现了两个定时器的硬同步。TAMR.TAWOT/TBMR.TBWOTWait-On-Trigger将此位置1定时器即使被使能TAEN1也不会开始计数直到它接收到来自“前一级”定时器的触发信号。这个“前一级”通常是同一个GPT模块的另一个定时器如Timer B等待Timer A或者是通过SYNC寄存器触发的其他GPT模块。这在生成相位相关的多路PWM或构建复杂的定时器链时非常有用。应用示例用Timer A产生一个基础的时基Timer B配置为WOT模式并在Timer A每次超时后延迟一段时间再启动从而产生一个相位可调的PWM与Timer A的PWM形成互补或交错关系。4.3 中断与DMA的协同最大化系统效率在数据采集或流处理应用中GPT中断结合DMA可以极大减轻CPU负担。GPT定时触发ADC采样配置GPT为周期模式使能超时中断TATOIM和超时DMA触发TATODMAEN。配置DMA通道将DMA的触发源设置为GPT超时事件。设置源地址为ADC结果寄存器目标地址为内存中的循环缓冲区。设置传输数据量。工作流程GPT每1ms超时一次同时产生两个动作一是向CPU申请中断二是向DMA控制器发出请求。DMA在后台自动将ADC数据搬移到内存。CPU的中断服务程序可以非常简短只需检查缓冲区是否已满或者设置一个标志通知主循环处理数据。这样高频的数据搬运工作由DMA完成CPU只在需要处理数据时才被唤醒非常适合低功耗应用。配置要点需要仔细阅读DMAEV寄存器的每个位确保使能了正确的事件超时TATODMAEN、匹配TAMDMAEN还是捕获CAEDMAEN。同时在GPT的模式寄存器中可能还需要使能相应的DMA触发功能如TAMR.TAPWMIE在PWM捕获模式下对DMA触发的控制。4.4 低功耗模式下的定时器行为CC13x2/CC26x2具有出色的低功耗特性。GPT定时器在CPU进入低功耗模式如Idle, Standby时其行为取决于时钟配置。如果GPT的时钟源是常开的高频时钟如48MHz HF RCOSC那么即使CPU休眠GPT仍会继续运行并在超时时产生中断唤醒CPU。这是实现周期性唤醒如传感器采样的典型方法。如果GPT的时钟源是随CPU域关闭的时钟那么定时器会暂停。调试暂停CTL寄存器中的TASTALL位控制当调试器暂停CPU时定时器是否也暂停。在调试时序相关的问题时将其设为1可以冻结定时器方便观察状态。避坑指南在低功耗设计中务必确认你使用的GPT时钟源在目标低功耗模式下是否仍然有效。例如在待机模式下只有特定的低频时钟可能可用你需要根据这个时钟频率重新计算定时器的重载值TAILR。5. 调试技巧与常见问题排查实录即使理解了所有寄存器实际调试中仍会遇到各种问题。以下是我在项目中积累的一些实战经验。问题一PWM没有输出或波形不对。检查清单引脚复用配置这是最常见的原因。确认GPIO是否已正确配置为CCP功能使用IOCPortConfigureSet函数。使用TI的SysConfig图形工具可以直观检查。定时器是否真正启动检查CTL寄存器的TAEN位是否为1。确认没有其他错误配置导致定时器被禁用。计数方向与极性结合TACDIR、TAPLO、TAPWML位理清输出逻辑。最直接的方法是用示波器观察然后调整极性配置位。一个技巧是先配置成最简单的向下计数、传统模式、输出不反转此时占空比应为(TAILR - TAMATCHR) / (TAILR 1)。匹配值是否大于装载值在向下计数模式如果TAMATCHR TAILR输出可能恒为高或恒为低。寄存器更新模式如果动态修改了TAILR或TAMATCHR但波形没变检查TAMR中的TAILD和TAMRSU位。确保你是在“下次超时更新”的模式下并且等待了一个完整的PWM周期。问题二定时中断不触发或触发过于频繁。排查步骤中断使能层层检查这是一个“金字塔”结构。确保a) GPT模块的IMR寄存器中对应中断位使能b) CPU的NVIC中对应中断通道使能c) 全局中断已开启对于Cortex-M调用__enable_irq()或类似函数。中断标志清除在中断服务程序开头是否清除了ICLR寄存器中的对应位如果没有清除中断会连续触发导致系统卡死。使用DriverLib的TimerIntClear(GPT0_BASE, TimerIntStatus(GPT0_BASE, true))可以一次性清除所有已发生的中断标志。重载值TAILR为0如果TAILR设置为0在周期模式下计数器将从0减到0或从0加到0每个时钟周期都会超时导致中断风暴。确保TAILR的值大于0。中断优先级过低或被屏蔽检查是否有更高优先级的中断长时间执行或者在某些关键代码段关闭了全局中断。问题三输入捕获值不准或跳动大。可能原因与对策信号噪声在捕获引脚前端增加硬件RC滤波。在软件中可以连续捕获多次取平均或采用中值滤波。中断响应延迟虽然捕获事件发生时TAR的值已被硬件锁存但如果中断服务程序被高优先级中断阻塞可能导致多次捕获事件丢失或顺序错乱。提高捕获中断的优先级或者使用DMA直接将捕获值传输到缓冲区如果支持。未处理计数器溢出这是测量长脉冲宽度的经典错误。必须维护一个溢出计数器在超时中断中递增并在计算脉冲宽度时加上溢出次数 * (计数器最大值 1)。问题四使用DriverLib库函数配置后功能不正常。诊断方法回归寄存器本质。使用调试器直接查看关键寄存器的值与你的预期配置进行比对。例如检查TAMR寄存器的值是否与你调用TimerConfigure()时传入的参数一致。DriverLib库虽然方便但有时其宏定义或函数实现可能因版本更新而有细微差别。理解寄存器配置能让你快速定位是库函数使用问题还是底层硬件问题。调试利器TAV/TBV寄存器。当你怀疑定时器计数不正常时不要只看TAR/TBR。在运行过程中连续读取TAV寄存器自由运行值可以更真实地反映计数器的动态情况因为TAR的更新可能受TAILD位的影响。