深入解析CC35xx通用定时器:从PWM生成到正交编码与同步控制
1. 通用定时器GPT在嵌入式系统中的核心地位在嵌入式开发领域尤其是涉及电机控制、电源转换、传感器接口或通信协议生成时精确的时序控制是项目成败的关键。无论是驱动一个步进电机的微步进还是生成一个特定频率的PWM信号来调节LED亮度亦或是精确捕获一个外部脉冲的宽度其底层都离不开一个核心硬件模块通用定时器。对于使用TI CC35xx这类集成Wi-Fi 6和蓝牙低功耗的无线MCU开发者而言深入理解其内置的通用定时器模块是解锁高级实时控制能力、优化系统性能和可靠性的必经之路。通用定时器常简称为GPT绝非一个简单的“计数器”。它是一个高度集成、功能丰富的数字外设其本质是一个可编程的时钟计数器配合一系列比较、捕获和输出控制逻辑能够以硬件方式独立完成复杂的时序任务极大减轻CPU的负担。在CC35xx这类资源受限但对实时性要求高的物联网设备中GPT的价值尤为突出。它允许开发者在后台进行精确的PWM生成、输入信号测量甚至多轴运动的同步控制而主CPU可以专注于处理网络协议栈或应用程序逻辑从而实现高效的系统分工。2. CC35xx GPT模块架构与核心功能解析CC35xx设备通常包含多个GPT实例每个GPT都是一个功能完整的定时器单元。理解其整体架构是进行有效编程的第一步。2.1 模块整体框图与数据通路从逻辑上看一个GPT模块可以抽象为几个核心部分时钟源与预分频器、核心计数器、多个独立的捕获/比较通道以及输出控制逻辑。这些部分通过内部总线紧密协作。时钟源GPT的“心跳”可以来自系统主时钟如80MHz也可以来自事件管理器Event Manager提供的TICKEN信号。后者为跨外设的精确同步提供了可能。预分频器这是一个8位向下计数器通过对时钟源进行分频产生最终的“定时器时钟”用于驱动核心计数器。通过配置PRECFG.TICKDIV寄存器我们可以灵活调整计数器的基准频率以适应从微秒到秒级的不同定时需求。核心计数器一个32位的向上/向下计数器是GPT的“发动机”。其计数模式单次、周期、上下周期等决定了定时行为的基础波形。捕获/比较通道这是GPT的“多面手”。每个GPT通常有多个这样的通道例如4个。在“捕获”模式下通道可以在外部信号发生特定边沿时瞬间锁存当前计数器的值用于测量脉冲宽度或周期。在“比较”模式下通道会持续将计数器值与一个预设值进行比较当匹配时触发预先定义的动作如翻转一个输出引脚、产生中断或启动DMA传输。输出控制与死区插入比较事件产生的动作最终会作用到GPIO引脚上。GPT支持复杂的输出控制包括直接设置、清除、翻转或产生一个固定宽度的脉冲。更高级的是对于电机驱动等需要防止上下桥臂直通的场景GPT支持互补PWM输出和可编程死区插入。死区时间是指在互补信号切换时插入一个两者都为低电平的短暂延时确保一个开关管完全关断后另一个才开启。注意在阅读数据手册时务必区分“定时器时钟”Timer Clock和“预分频器时钟”Prescaler Clock。定时器时钟是计数器CNTR递增/递减的速率而预分频器时钟是驱动预分频器本身的速率。通道滤波器的采样时钟可以独立选择为两者之一这为抗噪声设计提供了灵活性。2.2 核心寄存器组概览与GPT交互主要通过内存映射的寄存器。以下是一些最关键的寄存器类别理解它们的功能是编程的基础控制寄存器如CTL用于设置计数器模式MODE、使能定时器等。预分频配置寄存器PRECFG用于选择时钟源和设置分频系数。目标值寄存器TGT和PTGT。TGT是当前周期值PTGT是“流水线”目标值。在PWM应用中更新PTGT可以在下一个周期开始时无缝切换到新周期值避免周期抖动。通道配置寄存器CnCFGn为通道号。这是通道的“大脑”配置其工作模式捕获还是比较具体哪种动作、输入源、输出映射、边沿检测类型等。通道比较/捕获值寄存器CnCC和PCnCC。在比较模式下CnCC存放比较值在捕获模式下捕获到的计数器值会存入CnCC。PCnCC是其对应的流水线寄存器用于无抖动更新。中断与DMA寄存器IMASK用于使能特定事件的中断RIS用于查看挂起的中断状态。DMA相关寄存器则用于配置DMA传输触发。3. 核心工作模式深度剖析与配置指南GPT的强大源于其多样化的可配置模式。下面我们深入几个最常用和关键的模式。3.1 计数器模式定时行为的基石计数器模式由CTL.MODE字段控制它定义了计数器CNTR如何运行UP_ONCE单次向上计数。从0开始计数到TGT值然后停止。适用于需要单次延时或触发的场景。UP_PER周期性向上计数。从0计数到TGT然后自动重置为0并重新开始。这是生成边沿对齐PWM最常用的模式。UPDWN_PER周期性向上向下计数。从0计数到TGT然后递减回0如此循环。这是生成中心对齐PWM的基础。QDEC正交解码模式。在此模式下计数器会根据两个相位差90度的编码器信号PHA, PHB自动进行加减计数用于读取旋转编码器或线性尺的位置。SYNC_*模式同步模式。允许一个GPT的计数器与另一个GPT通常是GPT0同步启动实现多个定时器的精确对齐在多轴协同控制中至关重要。实操心得在UP_PER和UPDWN_PER模式下TGT寄存器的值实际对应的是“周期-1”。例如若定时器时钟为1MHz需要产生1kHz的PWM则周期应为1000个计数。在UP_PER模式下TGT应设置为999在UPDWN_PER模式下计数器会从0到TGT再到0一个完整周期是2 * TGT个计数因此TGT应设置为499。3.2 通道动作GPT的灵魂操作每个通道的CnCFG.CCACT字段定义了该通道的具体行为这是GPT功能多样化的核心。动作可分为单次和连续两大类。这里重点解析几个工程中最关键的动作3.2.1 周期与脉宽测量此模式CCACT PER_PULSE_WIDTH_MEAS是测量外部信号频率和占空比的利器。通道会连续测量输入信号的周期和脉冲宽度。其巧妙之处在于它会用输入信号的边沿来同步复位计数器。这意味着即使被测信号与定时器时钟不同步也能获得精确测量。如图13-5所示两个通道可以交替测量两个不同信号的参数实现时间复用。配置要点将通道CCACT设置为PER_PULSE_WIDTH_MEAS。通过CnCFG.INPUT选择输入源GPIO或事件管理器信号。通过CnCFG.EDGE选择捕获边沿上升沿、下降沿或双边沿。测量周期通常使用相同的边沿测量高电平脉宽则使用上升沿捕获、下降沿捕获相结合的逻辑通常由硬件自动处理CnCC存周期PCnCC存脉宽。使能该通道对应的输出事件CnCFG.OUTn以便在测量完成时触发中断或DMA。3.2.2 重复比较动作PWM生成的引擎这是生成PWM的核心。两种最常用的动作是SET_ON_0_TGL_ON_CMP在CNTR0时置位输出在CNTRCnCC时翻转输出。结合UP_PER模式可生成边沿对齐PWM。PWM周期由TGT决定高电平时间由CnCC决定。CLR_ON_0_TGL_ON_CMP在CNTR0时清零输出在CNTRCnCC时翻转输出。结合UPDWN_PER模式可生成中心对齐PWM。此时输出在CNTRCnCC和CNTRTGT-CnCC时都会翻转形成对称的PWM波形。中心对齐PWM在电机驱动中能有效降低谐波噪声。无抖动更新技巧在PWM运行时直接修改CnCC或TGT可能会导致当前周期输出出现毛刺或宽度异常。正确的做法是更新其对应的流水线寄存器PCnCC或PTGT。硬件会在下一个计数器周期开始时CNTR0自动将流水线寄存器的值加载到工作寄存器中实现平滑过渡。3.3 输入滤波与边沿检测外部信号往往带有噪声GPT的通道输入滤波器是抗干扰的第一道防线。如图13-3所示信号在进入边沿检测器之前会经过一个可配置的数字滤波器。工作原理滤波器计数器从CHFILT.LOAD值开始递减仅当连续LOAD1个采样时钟周期内输入信号都稳定不变时该变化才会被传递。任何抖动都会重置计数器。时钟选择滤波器采样时钟可以独立选择为系统时钟、预分频器时钟或定时器时钟。对于慢速信号使用定时器时钟滤波即可对于需要抑制高频毛刺的快速信号则应使用更快的系统时钟进行采样滤波。配置公式必须确保滤波器延时不会错过有效信号。即滤波器时钟周期 * (CHFILT.LOAD 1) 待测信号的最小脉宽。如果此条件不满足可能会丢失捕获事件。4. 高级应用场景实现与避坑指南掌握了基础原理和配置后我们可以将这些功能组合起来解决复杂的工程问题。4.1 生成高精度PWM信号假设我们需要用GPT0的通道0生成一个38kHz、占空比50%的PWM方波例如用于红外载波。计算参数系统时钟80MHz目标频率38kHz。周期计数 80MHz / 38kHz ≈ 2105。在UP_PER模式下TGT 周期 - 1 2104。对于50%占空比C0CCTGT/ 2 1052。但为了更精确我们可以利用预分频器。设PRECFG.TICKDIV 4则预分频后时钟 80MHz / (41) 16MHz。新周期计数 16MHz / 38kHz ≈ 421。TGT 420C0CC 210。这样量化误差更小。配置步骤// 1. 配置预分频器 GPT0.PRECFG.TICKSRC 0; // 使用系统时钟 GPT0.PRECFG.TICKDIV 4; // 分频系数5 // 2. 配置周期和比较值 GPT0.TGT 420; GPT0.C0CC 210; // 3. 配置通道0动作和输出 GPT0.C0CFG.CCACT SET_ON_0_TGL_ON_CMP; // 边沿对齐PWM GPT0.C0CFG.OUT0 1; // 动作输出到Output 0 // 注意还需通过IO复用配置将GPT0的输出0连接到具体的GPIO引脚。 // 4. 启动定时器 GPT0.CTL.MODE UP_PER;4.2 实现正交编码器接口将GPT配置为QDEC模式可以轻松接口旋转编码器。硬件连接将编码器的A相、B相接至GPT通道0和通道1对应的GPIO引脚。零位索引信号如果存在接通道2。软件配置// 1. 配置输入源 GPT0.C0CFG.INPUT 1; // PHA 来自IO GPT0.C1CFG.INPUT 1; // PHB 来自IO GPT0.C2CFG.INPUT 1; // IDX 来自IO (如果使用) GPT0.C2CFG.EDGE RISING; // 配置IDX信号的边沿 // 2. 配置采样率需高于编码器信号最高频率的2倍 GPT0.PRECFG.TICKDIV 0; // 使用80MHz直接采样适用于高速编码器 // 或使用预分频降低采样率 // 3. 设置计数器上限可选用于溢出处理 GPT0.TGT 0xFFFF; // 例如设置一个上限 // 4. 可选使能计数器变化中断用于实时读取位置 GPT0.IMASK.CNTRCHNG 1; // 5. 启动正交解码模式 GPT0.CTL.MODE QDEC;读取位置直接读取CNTR寄存器即可得到累积的位置计数。方向信息隐含在计数的增减中。4.3 多定时器同步与联动在复杂的控制系统中如多电机协同需要多个PWM输出严格同步。CC35xx的GPT支持硬件同步。主从配置通常将GPT0设为主定时器GPT1设为从定时器。配置步骤// 配置从定时器GPT1为同步模式 GPT1.CTL.MODE SYNC_UP_PER; // 同步周期向上模式 // 在事件管理器中配置一个同步事件源例如GPT0的计数器归零事件 // 假设我们将GPT0的ZERO事件映射到事件管理器的某个同步信号SYNC_EVT_X EVENT_MANAGER.CHANNEL[n].SRC GPT0_ZERO_EVENT; // 配置GPT1订阅该同步事件 GPT1.EVTCTL1.SYNC SYNC_EVT_X;效果当GPT0的计数器归零时会发出同步事件。GPT1在收到该事件后会在下一个定时器时钟周期将自己的计数器重置为0并开始计数从而实现两个定时器的周期完全对齐。这对于需要多个相位关联的PWM输出至关重要。4.4 故障输入与安全停车在电机驱动等安全关键应用中GPT的故障Fault和停车Park功能是硬件安全屏障。故障输入可以将一个GPIO通常通过通道0复用配置为故障输入。当该引脚出现有效电平可配置高或低有效时GPT会根据FAULT.CTL的配置采取行动。IMMEDIATE立即停止计数器PWM输出立即进入安全状态。ZEROCOND在当前PWM周期结束后CNTR0再停止实现“软关断”避免因突然关断引起的大电压电流冲击。停车状态当故障触发停车后PARK寄存器可以控制每个输出引脚被驱动到一个确定的安全状态高、低或高阻而不是保持悬空。配置示例// 1. 配置故障输入引脚和极性 GPT0.C0CFG.INPUT 1; // 通道0输入来自IO GPT0.C0CFG.EDGE RISING; // 上升沿高电平为故障有效 // 配置对应GPIO为输入并上拉/下拉以确保默认无效 // 2. 配置故障模式 GPT0.FAULT.CTL ZEROCOND; // 选择周期结束后停车 // 3. 配置停车状态 GPT0.PARK.CTL FAULT; // 故障时进入停车模式 GPT0.PARK.IOPS0 DRIVE_LOW; // 故障时输出0被驱动为低电平安全状态 // 4. 使能故障中断以便CPU响应 GPT0.IMASK.FAULT 1; // 5. 启动定时器 GPT0.CTL.MODE UP_PER;5. 实战调试与常见问题排查即使配置正确在实际调试中也可能遇到各种问题。以下是一些常见坑点及排查思路。5.1 PWM输出无信号或频率不对检查时钟树确认GPT的时钟源是否使能。检查PRECFG.TICKSRC和PRECFG.TICKDIV配置是否正确。一个简单的验证方法是在调试器中单步运行启动定时器后观察CNTR寄存器的值是否在递增。检查GPIO复用这是最容易被忽略的一步GPT的输出信号需要正确映射到具体的GPIO引脚。必须配置该引脚的复用功能为对应的GPT输出并且将引脚方向设置为输出。检查输出使能确认CnCFG.OUTn字段已使能将通道动作绑定到了具体的输出上。一个通道可以同时驱动多个输出。计算错误重新计算TGT和CnCC的值。记住UP_PER模式下周期TGT1UPDWN_PER模式下周期2*(TGT1)。使用逻辑分析仪或示波器测量实际输出与计算值对比。5.2 捕获功能不稳定或数据错误输入信号质量首先用示波器观察输入信号的边沿是否有振铃或毛刺。硬件上的RC滤波可能是必要的。滤波器配置不当如果CHFILT.LOAD设置过大可能会滤掉正常的窄脉冲如果设置过小则无法滤除噪声。根据信号最小脉宽和滤波器时钟重新计算LOAD值。可以尝试暂时旁路滤波器CHFILT.MODE BYPASS来排查是否是滤波器引起的问题。边沿检测配置确认CnCFG.EDGE设置与期望捕获的边沿一致。中断服务程序在捕获中断中读取CnCC寄存器后该中断标志会被自动清除。确保你的ISR没有过于耗时导致错过后续的捕获事件。对于高频信号考虑使用DMA将捕获值直接搬运到内存中。5.3 中断无法触发或触发异常中断使能嵌套需要使能三层中断GPT模块级设置IMASK寄存器中对应事件位如CMPZERO。中断控制器级在MCU的NVIC中使能GPT对应的中断线。全局中断确保执行了__enable_irq()或类似指令。中断标志清除某些中断标志在读取相关寄存器如CnCCTGT时会自动清除。如果你的ISR中需要读取这些寄存器又需要手动清除标志请使用RIS.CLR子寄存器或者使用对应的“无清除”寄存器如TGTNC进行访问以避免意外清除中断标志。短周期下的中断丢失在PWM频率很高周期很短时如果同时使能了ZERO和TGT中断且ISR中通过读写TGT来清除中断可能会因为CPU响应速度跟不上导致刚产生的ZERO中断在还没来得及处理时就被对TGT的写操作连带清除了。解决方案是使用PTGTNC/TGTNC寄存器进行更新并分别清除RIS.ZERO.CLR和RIS.TGT.CLR。5.4 同步功能失效事件管理器配置同步依赖于事件管理器。确保主定时器如GPT0的同步输出事件如ZERO已正确配置到事件管理器的一个通道。从定时器订阅确认从定时器如GPT1的EVTCTL1.SYNC寄存器正确订阅了事件管理器产生的那个同步事件信号。模式匹配确保从定时器的CTL.MODE设置为SYNC_UP_PER等同步模式而不是普通的UP_PER。启动顺序通常应先启动从定时器使其进入等待同步状态再启动主定时器。如果先启动主定时器从定时器可能会错过第一个同步事件。GPT模块是CC35xx这类现代MCU的瑞士军刀其功能深度足以应对绝大多数嵌入式时序挑战。从简单的延时到复杂的多轴同步运动控制理解其工作原理并掌握配置技巧能让你在嵌入式开发中游刃有余。最好的学习方式永远是动手实践从一个简单的LED呼吸灯PWM开始再到测量一个按键的抖动时间输入捕获最后尝试用两个GPT生成一组互补带死区的电机驱动信号。过程中遇到的每一个问题都会让你对数据手册上的那些位字段有更深刻的理解。