当前位置: 首页 > news >正文

CC35xx通用定时器GPT深度解析:从PWM生成到输入捕获的嵌入式实战

1. 项目概述:为什么通用定时器是嵌入式开发的基石

在嵌入式系统开发中,尤其是面对电机控制、电源管理、传感器数据采集这类对时序精度要求苛刻的场景,软件延时循环(delay())是绝对不够看的。它不仅会独占CPU,让系统响应变得迟钝,更无法应对微秒甚至纳秒级的精确时间控制需求。这时,硬件通用定时器(GPT)的价值就凸显出来了。它就像系统内部一个独立、精准的“秒表”或“节拍器”,能够自主运行,在预设的时间点或外部事件发生时,自动完成诸如翻转引脚电平、触发ADC采样、发出中断通知CPU等任务,从而将CPU从繁重的定时任务中解放出来,专注于更复杂的逻辑处理。

TI的CC35xx系列无线MCU,作为面向物联网的低功耗高性能芯片,其内置的GPT模块功能相当强大。它远不止一个简单的计数器。根据技术手册,它集成了32位计数器、8位预分频器、4个独立通道,并支持多达15种通道动作模式。这意味着,开发者可以用它来生成复杂且无抖动的PWM波形驱动电机或调光LED,可以精准捕获外部信号的上升/下降沿以测量频率或脉宽,甚至可以实现正交编码器解码、红外信号调制等高级功能。理解并掌握GPT,是进行CC35xx乃至任何现代MCU深度开发的基本功。本文将以CC35xx的GPT模块为蓝本,拆解其核心原理,并聚焦于两个最经典的应用——PWM生成与事件捕获,通过具体的寄存器配置步骤和代码逻辑,让你不仅能“配出来”,更能明白“为什么这么配”。

2. GPT模块架构与核心工作机制拆解

要驾驭GPT,必须先理解它的“五脏六腑”。CC35xx的GPT模块可以看作一个精密的定时事件处理引擎,其核心部件协同工作,共同构成了灵活且强大的定时功能基础。

2.1 核心组件:从时钟源到动作执行

一个GPT定时器的完整工作流,始于时钟,终于对引脚或内部事件的控制,中间经过多个可配置环节。

预分频器与计数器:时间的尺度这是所有定时功能的基石。系统时钟(例如CC35xx的80MHz)对于很多定时任务来说太快了,直接计数会很快溢出。预分频器的作用就是“降速”。它是一个8位计数器,你可以通过PRECFG.TICKDIV寄存器设置一个分频值N。预分频器会以系统时钟频率进行递减计数,从N数到0,然后重置为N,如此循环。每完成一个“N+1”个系统时钟的循环,它就会产生一个“滴答”(Tick),这个“滴答”就是定时器时钟,它才是驱动核心32位计数器(CNTR)更新的真正节拍。

关键理解定时器时钟频率 = 系统时钟频率 / (PRECFG.TICKDIV + 1)。例如,系统时钟80MHz,TICKDIV设为39,则定时器时钟为2MHz,每个计数周期代表0.5微秒。这为你提供了第一个时间精度调节旋钮。

计数器模式:时间流逝的“方向”32位计数器CNTR在定时器时钟的驱动下工作,但其计数模式决定了它的行为轨迹,这直接影响了PWM的生成方式:

  • UP_ONCE (单次向上计数):从0开始,计数到设定的目标值TGT后停止。适用于单次延时或触发。
  • UP_PER (周期向上计数):从0开始,计数到TGT后自动复位到0,并重新开始。这是生成边沿对齐PWM的典型模式。
  • UPDWN_PER (周期向上向下计数):从0开始,计数到TGT,然后递减回0,如此反复。这是生成中心对齐PWM的必需模式。
  • QDEC (正交解码模式):在此模式下,计数器不再由内部时钟驱动,而是由两个外部相位信号(PHA, PHB)的边沿变化来驱动增减,用于解码旋转编码器信号。

通道:多功能输入输出端口每个GPT有4个通道,这是模块与外界交互的触手。每个通道都可以被独立配置为输入(捕获)或输出(比较)模式,功能极其灵活:

  • 输入逻辑路径:外部信号通过GPIO或事件管理器进入通道后,首先经过一个可配置的数字滤波器CHFILT),可以滤除短于(LOAD+1)个滤波时钟周期的毛刺。滤波后的信号进入边沿检测器(由CnCFG.EDGE配置为上升沿、下降沿或双边沿),最终产生一个捕获事件。
  • 输出逻辑路径:当计数器满足特定条件(如等于0、等于比较值CnCC)时,会根据通道配置的动作(CnCFG.CCACT)产生“置位”、“清零”、“翻转”或“脉冲”等请求。这些请求被送到一个输出仲裁器,结合手动控制(OUTCTL寄存器)的优先级,最终决定物理引脚IO[n]的输出电平。高级功能如死区插入(防止电机驱动中上下桥臂直通)和故障停车PARK模式,在故障时强制输出安全状态)也在此逻辑中实现。

2.2 寄存器组概览与配置哲学

配置GPT本质上就是读写一系列内存映射的寄存器。理解几个关键寄存器组的作用,能让配置过程变得清晰:

  1. 全局控制寄存器 (CTL):决定定时器的“总开关”和基本模式,如使能/禁用(EN)、选择计数模式(MODE)。
  2. 预分频配置 (PRECFG):设置定时器时钟的源头(TICKSRC)和分频值(TICKDIV)。
  3. 目标值寄存器 (TGT,PTGT)TGT是当前计数周期的目标值。PTGT是“管道目标值”,可在计数器为0时自动加载到TGT,用于实现PWM周期或占空比的无抖动更新。
  4. 通道配置寄存器 (CnCFG):每个通道都有一个。这是最核心的配置寄存器,决定了该通道是输入还是输出、执行什么动作(CCACT)、控制哪个物理输出(OUTn)、监听哪个输入源(INPUT)、检测哪种边沿(EDGE)。
  5. 通道比较/捕获寄存器 (CnCC,PCnCC)CnCC是当前生效的比较/捕获值。PCnCC是“管道比较/捕获值”,在特定时刻(如计数器归零)自动加载到CnCC,用于实现PWM占空比的无抖动更新。
  6. 中断与事件寄存器 (IMASK,RIS,ICLR)IMASK用于使能哪些事件(如计数到零ZERO、计数到目标TGT、捕获事件CAP)可以触发中断。RIS是原始中断状态位,ICLR用于清除中断标志。
  7. DMA与ADC触发寄存器 (DMA,ADCTRG):配置特定定时器事件(如捕获完成)直接触发DMA传输或ADC开始采样,实现极高效率的数据搬运,完全无需CPU干预。

实操心得:配置GPT时,建议遵循“从整体到局部”的顺序:先配置全局时钟和模式(PRECFG,CTL.MODE),再配置各个通道的功能(CnCFG),接着设置具体的比较/捕获值(CnCC,TGT),最后配置中断/DMA等高级功能。在启动定时器(CTL.EN)前,确保所有静态配置已完成。对于需要动态更新的值(如PWM占空比),优先考虑使用管道寄存器(PTGT,PCnCC)来避免毛刺。

3. 核心应用一:PWM信号生成全解析

PWM是嵌入式系统中最常见的模拟控制方式,广泛应用于电机速度控制、LED调光、开关电源稳压等。GPT生成PWM的核心原理,就是利用计数器和比较器,在引脚上自动产生周期和占空比均可编程的方波。

3.1 PWM生成的基本原理与模式选择

PWM信号有两个关键参数:周期(Period)占空比(Duty Cycle)。在GPT中:

  • 周期由计数器的计数模式和目标值TGT共同决定。在UP_PER模式下,周期 =(TGT + 1) * 定时器时钟周期。在UPDWN_PER模式下,周期 =2 * TGT * 定时器时钟周期
  • 占空比由通道的比较值CnCC决定。它定义了在一个周期内,输出高电平或低电平的时间���例。

GPT支持两种主流的PWM对齐方式,它们由计数模式通道动作共同决定:

边沿对齐PWM

  • 计数模式UP_PER(周期向上计数)。计数器从0线性增加到TGT,然后归零,循环往复。
  • 通道动作SET_ON_0_TGL_ON_CMP(在0置位,在比较值翻转)。
  • 工作原理:计数器从0开始瞬间,输出被置为高电平。当计数器值增加到等于比较值CnCC时,输出翻转变为低电平,并保持到本周期结束(计数器归零)。下一个周期开始,输出再次被置为高电平,如此循环。
  • 波形特点:所有PWM脉冲的起始边沿(这里是上升沿)都与计数器归零的时刻严格对齐,故名“边沿对齐”。这是最常用的PWM模式。

中心对齐PWM

  • 计数模式UPDWN_PER(周期向上向下计数)。计数器从0增加到TGT,再减少回0,循环往复。
  • 通道动作CLR_ON_0_TGL_ON_CMP(在0清零,在比较值翻转)。
  • 工作原理:计数器从0开始瞬间,输出被清零(低电平)。在计数器向上计数过程中,当值等于CnCC时,输出翻转变为高电平。随后计数器到达TGT后开始向下计数,当再次等于同一个CnCC值时,输出再次翻转变回低电平,直至本周期结束。
  • 波形特点:PWM脉冲的中心与计数周期的中心对齐。这种模式产生的谐波特性更好,常用于电机驱动和音频应用,能降低电磁干扰。

3.2 边沿对齐PWM配置实战与防抖动技巧

假设我们需要在CC35xx的某个GPIO(映射到GPT0通道0输出)上生成一个频率为1kHz,占空比为30%的边沿对齐PWM波。系统时钟为80MHz。

步骤1:计算定时器参数

  1. PWM周期 T = 1 / 1kHz = 1ms = 0.001秒。
  2. 选择定时器时钟。为了有较高的占空比分辨率,我们让计数器每个滴答对应1us。则定时器时钟频率应为1MHz。
  3. 计算预分频值:PRECFG.TICKDIV = (系统时钟频率 / 定时器时钟频率) - 1 = (80MHz / 1MHz) - 1 = 79
  4. UP_PER模式下,周期值TGT = (周期T / 定时器时钟周期) - 1 = (1ms / 1us) - 1 = 999
  5. 占空比30%,则比较值C0CC = TGT * 占空比 = 999 * 0.3 ≈ 299(取整)。

步骤2:寄存器配置代码逻辑(以伪代码/C风格表示)

// 1. 配置全局时钟源与分频 (假设使用系统时钟) GPT0.PRECFG.TICKSRC = 0; // 时钟源选择系统时钟 GPT0.PRECFG.TICKDIV = 79; // 分频至1MHz // 2. 配置通道0为PWM输出模式 GPT0.C0CFG.CCACT = SET_ON_0_TGL_ON_CMP; // 动作:0置位,比较翻转 -> 边沿对齐PWM GPT0.C0CFG.OUT0 = 1; // 通道0控制输出0 GPT0.C0CFG.INPUT = 0; // 非捕获模式,输入配置无关(或设为特定值) GPT0.C0CFG.EDGE = NONE; // 非捕获模式,边沿检测无关 // 3. 设置周期和初始占空比 GPT0.TGT = 999; // PWM周期 GPT0.C0CC = 299; // 初始比较值(占空比) // 4. 配置计数器模式并启动 GPT0.CTL.MODE = UP_PER; // 周期向上计数模式 GPT0.CTL.EN = 1; // 使能定时器

配置完成后,对应的GPIO就会自动输出1kHz,占空比30%的PWM波,无需CPU持续干预。

步骤3:动态更新占空比与无抖动技巧在实际应用中,我们经常需要动态改变PWM占空比(例如调节电机速度)。直接写入C0CC寄存器存在风险:如果写入时机不当,恰好在计数器值介于旧C0CC和新C0CC值之间,可能会导致当前周期产生一个极窄或极宽的异常脉冲,即“抖动”。

解决方案是使用管道比较寄存器PCnCC。在UP_PER模式下,硬件会在计数器归零的瞬间,自动将PCnCC的值加载到CnCC中。因此,安全的更新流程是:

// 在任何时候(最好在中断服务程序中)更新占空比 uint32_t new_duty_compare = calculate_new_duty(); // 计算新的比较值 GPT0.PC0CC = new_duty_compare; // 写入管道寄存器 // 硬件会在下一个PWM周期开始时(CNTR==0)自动应用新值,整个过程无抖动。

同理,如果需要动态改变PWM频率(周期),应使用管道目标寄存器PTGT来更新TGT值。

3.3 中心对齐PWM与互补输出带死区控制

对于电机驱动全桥电路等应用,需要一对互补的PWM信号(高侧和低侧开关管驱动),并且两者之间必须插入一段同时为低电平的“死区时间”,防止上下管直通短路。

中心对齐PWM配置配置与边沿对齐类似,但模式不同:

GPT0.PRECFG.TICKDIV = 79; // 1MHz定时器时钟 GPT0.C0CFG.CCACT = CLR_ON_0_TGL_ON_CMP; // 动作:0清零,比较翻转 -> 中心对齐PWM GPT0.C0CFG.OUT0 = 1; // 主输出 GPT0.C0CFG.OUT1 = 1; // 同时控制互补输出(如果硬件支持) GPT0.TGT = 499; // 注意:中心对齐模式下,计数器从0到TGT再到0,周期为 2*TGT*时钟周期 // 要得到1ms周期:2 * TGT * 1us = 1ms => TGT = 500 // 但手册示例常以TGT为半周期值,这里需根据实际波形验证。假设目标半周期值。 GPT0.C0CC = 150; // 占空比设置,需根据中心对齐波形计算 GPT0.CTL.MODE = UPDWN_PER; // 向上向下计数模式 GPT0.CTL.EN = 1;

死区插入配置CC35xx的GPT模块通常集成死区插入单元(通过DBCTL,DBDLY等寄存器控制)。其原理是对同一个通道产生的原始PWM信号,生成两个相位相反且带有可编程延迟的输出。

  1. 使能死区:设置DBCTL.EN = 1
  2. 配置死区时间:向DBDLY寄存器写入一个值。死区时间 =DBDLY * 定时器时钟周期。例如,需要500ns的死区,定时器时钟1MHz(周期1us),则DBDLY = 0.5us / 1us = 0.5,但寄存器通常为整数,可能需要调整时钟分频以获得更精细的控制。
  3. 指定输出对:配置通道同时控制主输出(如IO[0])和互补输出(如IO_C[0])。死区逻辑会自动确保在一路输出关闭后,延迟一段死区时间,再开启另一路输出。

注意事项:死区时间的设置至关重要。时间太短无法防止直通,太长则会降低有效输出电压并增加损耗。需要根据所驱动的功率器件(MOSFET/IGBT)的开关特性(开通延迟、关断延迟)来精确计算。

4. 核心应用二:输入捕获与信号测量

输入捕获功能是GPT的另一大核心应用,用于精确测量外部信号的时序参数,如周期、脉宽、频率等。其原理是利用外部信号的边沿来“冻结”计数器当前的值,CPU或DMA随后读取这个被捕获的值进行计算。

4.1 周期与脉宽测量模式详解

GPT提供了一个非常强大的通道动作:Period and Pulse Width Measurement(周期与脉宽测量)。该模式下,一个通道可以自动连续测量输入信号的周期和脉宽。

工作原理

  1. 通道被配置为该模式后,会等待指定的输入边沿(如上升沿)。
  2. 当第一个边沿到来时,定时器计数器CNTR同步清零,并开始计数。
  3. 当第二个边沿(例如,对于脉宽测量,可能是同极性的下一个边沿;对于周期测量,是下一个同向边沿)到来时,硬件会自动将CNTR的当前值捕获到通道的PCnCC(脉宽)和CnCC(周期)寄存器中,并同时产生捕获完成事件(可触发中断)。
  4. 此后,计数器再次等待下一个同步边沿,循环往复。

配置实例:测量一个未知数字信号���周期假设信号连接至GPT0的通道0输入引脚。

// 1. 配置定时器基础时钟(设置一个合适的测量范围,例如最大测量1秒) GPT0.PRECFG.TICKDIV = 7999; // 80MHz / (7999+1) = 10kHz,每个计数0.1ms GPT0.TGT = 0xFFFFFFFF; // 32位最大值,在单次模式下作为最大计时,或周期模式忽略 // 2. 配置通道0为周期捕获模式 GPT0.C0CFG.CCACT = PER_PULSE_WIDTH_MEAS; // 周期与脉宽测量模式 GPT0.C0CFG.INPUT = 1; // 输入源选择IO Mux(即GPIO引脚) GPT0.C0CFG.EDGE = RISING; // 在上升沿进行捕获和同步 // 注意:此模式下,OUT字段可能用于触发内部事件,若无需可设为0 GPT0.C0CFG.OUT0 = 0; // 3. 使能捕获中断(可选,也可以用轮询) GPT0.IMASK.CAP0 = 1; // 使能通道0捕获中断 NVIC_EnableIRQ(GPT0_IRQn); // 使能CPU中断 // 4. 启动定时器 GPT0.CTL.MODE = UP_PER; // 使用周期模式,计数器在捕获边沿会被同步清零 GPT0.CTL.EN = 1; // 5. 在中断服务程序(ISR)中读取测量值 void GPT0_IRQHandler(void) { if (GPT0.RIS.CAP0) { // 检查通道0捕获中断标志 uint32_t period_ticks = GPT0.C0CC; // 读取周期值(计数器滴答数) uint32_t pulse_width_ticks = GPT0.PC0CC; // 读取脉宽值(高电平时间) float period_ms = (float)period_ticks * 0.1f; // 转换为时间(单位:ms) float freq_hz = 10000.0f / period_ticks; // 频率 = 1 / (period_ticks * 0.1ms) // ... 处理数据 ... GPT0.ICLR.CAP0 = 1; // 清除中断标志 } }

4.2 数字滤波器配置与抗干扰设计

在工业环境或长线传输中,输入信号容易带有毛刺。GPT的输入通道滤波器是抑制毛刺、确保捕获准确性的关键硬件手段。

滤波器原理:它是一个数字消抖滤波器。你需要设定一个加载值CHFILT.LOAD(例如N)。滤波器会连续检查输入信号,只有当信号电平保持稳定持续(N+1)个滤波器时钟周期后,这个电平变化才会被传递到后面的边沿检测器。任何短于这个时间的抖动都会被滤除。

配置步骤与计算

  1. 选择滤波器时钟(CHFILT.MODE):
    • BYPASS:禁用滤波器。
    • CLK:使用80MHz系统时钟,滤波精度最高,但能滤除的毛刺宽度最小。
    • TIMERCLK:使用定时器时钟(即经过预分频后的时钟)。当定时器时钟较慢时,可以滤除更宽的毛刺。
    • TICKCLK:使用与预分频器相同的时钟源。
  2. 设置加载值(CHFILT.LOAD):决定需要连续稳定的周期数。
  3. 计算滤波窗口滤波窗口时间 = (LOAD + 1) * 滤波器时钟周期
    • 例如,选择TIMERCLK为滤波器时钟,定时器时钟为1MHz(周期1us),设置LOAD = 4,则滤波窗口为5 * 1us = 5us。所有宽度小于5us的毛刺将被滤除。

重要约束滤波器时钟周期必须大于定时器时钟周期。即(1/滤波器频率) * (LOAD+1) > (1/定时器频率)。如果不满足,可能出现毛刺被误认为有效边沿,或者有效边沿被滤除的情况。例如,定时器时钟为1MHz(1us),滤波器时钟也为1MHz,那么LOAD必须至少为1,以确保滤波窗口(至少2us)大于定时器时钟周期(1us)。

4.3 多通道协同与高精度时间戳应用

单个GPT的多个通道可以独立工作,也可以协同完成复杂测量。

场景:同时测量两路信号的频率和相位差

  • 通道0:配置为对信号A的上升沿进行周期捕获。
  • 通道1:配置为对信号B的上升沿进行周期捕获。
  • 关键点:两个通道共享同一个计数器CNTR。当信号A的上升沿触发通道0捕获时,它同时会将计数器清零(在PER_PULSE_WIDTH_MEAS模式下)。这意味着信号B的捕获值是基于信号A边沿清零后的时间。通过比较两个通道的捕获值,可以计算出信号B相对于信号A的上升沿延迟,从而得到相位差。

高精度时间戳:对于稀疏但需要精确记录发生时刻的事件,可以将通道配置为简单的“捕获模式”(例如SET_ON_CAP单次动作)。当事件边沿发生时,CNTR的当前值被锁存到CnCC。只要计数器一直在运行(例如在UP_PER模式下以恒定频率运行),这个捕获值就是一个高精度的时间戳。通过记录连续事件的时间戳,可以分析事件的时间间隔分布,广泛应用于协议分析、性能 profiling 等场景。

实操心得:在进行高精度测量时,要注意计数器的溢出。如果测量间隔可能超过计数器满量程时间,必须启用溢出中断,并在中断中维护一个软件扩展的高位计数器(例如overflow_count)。最终的时间戳应为(overflow_count << 32) + CnCC。此外,中断响应延迟会引入误差,对于极高精度或高频测量,应优先考虑使用DMA将捕获值直接搬运到内存,再行处理。

5. 高级功能与系统集成

除了基本的PWM和捕获,CC35xx的GPT还集成了若干高级功能,能够满足更复杂的系统需求。

5.1 正交编码器接口实现

正交编码器常用于测量电机转速和位置。GPT的QDEC模式直接硬件解码A、B两相90度相位差的方波信号。

  • 接线:编码器的A相、B相接至GPT的通道0和通道1输入(通过CnCFG.INPUT配置为IOC)。
  • 配置模式CTL.MODE = QDEC
  • 工作原理:硬件根据A、B相的边沿变化顺序,自动判断方向(正转/反转)并递增或递减计数器CNTR。计数器的值直接反映了相对位置信息。
  • 索引信号:编码器的Z相(索引信号)可接至通道2,用于在每圈零点产生一个同步信号,可将计数器复位或产生中断,实现绝对位置归零。
  • 采样率设置:必须通过PRECFG设置合适的采样时钟,其频率应远高于编码器信号的最大预期频率(通常4-10倍),以避免丢失计数或误判方向。手册中的IMASK.DBLTRANS中断就是用来提示采样率可能过低的。

5.2 与DMA和ADC的联动

GPT可以无缝触发DMA和ADC,构建高效的数据采集或控制流水线,几乎零CPU开销。

DMA联动更新PWM:在电机矢量控制等场景中,需要实时更新多路PWM的占空比。可以配置GPT在计数器为零(RIS.ZERO)时产生DMA请求。DMA控制器收到请求后,自动从内存中预存的数据表里,将新的PTGTPC0CCPC1CC等值依次搬运到GPT的对应管道寄存器中。这样,PWM波形就能按照预定的序列自动、无抖动地更新。

ADC触发同步采样:在电机控制中,需要在特定PWM时刻(如中心点或下桥臂导通中点)进行相电流采样。可以配置GPT的某个通道在比较匹配时(RIS.CMPx)产生ADC触发信号。ADC收到触发后立即启动一次转换,从而确保采样时刻与PWM波形严格同步,消除因软件延迟带来的采样误差,这对于FOC(磁场定向控制)算法至关重要。

5.3 故障保护与安全停车机制

在功率驱动应用中,安全至关重要。GPT的故障输入和停车逻辑提供了硬件级保护。

  1. 故障输入:将一个代表故障状态(如过流、过温)的GPIO信号连接到GPT的故障输入引脚(通常是通道0的复用功能)。
  2. 配置故障模式(FAULT.CTL):
    • IMMEDIATE:故障信号有效时,计数器立即停止,PWM输出立即被强制为安全状态(通过PARK寄存器配置)。
    • ZEROCOND:故障信号有效时,计数器继续运行至0后再停止。这可以保证当前PWM周期完整结束,避免非对称关断,是更平滑的关断方式。
  3. 停车状态配置(PARK):当故障导致定时器停止时,PARK寄存器可以指定每个输出引脚应被驱动至高电平、低电平或高阻态。这确保了电机驱动桥臂处于安全的关断状态。
  4. 中断响应:故障事件会触发中断,CPU在中断服务程序中可以进行故障记录、系统状态保存等处理。

这个“故障检测-硬件强制停车-软件后续处理”的机制,极大地提高了系统的可靠性和响应速度。

6. 调试技巧与常见问题排查

即使理解了原理和配置,在实际调试中仍会遇到各种问题。以下是一些常见坑点及排查思路。

6.1 PWM输出异常排查清单

现象可能原因排查步骤
无输出1. 定时器未使能 (CTL.EN=0)。
2. GPIO引脚未正确复用为GPT输出功能。
3. 通道未绑定到物理输出 (CnCFG.OUTn位未设置)。
4. 输出被手动覆盖 (OUTCTL寄存器)。
1. 检查CTL.EN位。
2. 检查芯片数据手册的引脚复用表,配置IOCONFIG寄存器。
3. 确认CnCFG.OUT0OUT1等位是否对应到目标引脚。
4. 检查OUTCTL寄存器,确保没有手动设置输出电平。
频率不对1. 系统时钟频率配置错误。
2. 预分频器(PRECFG.TICKDIV)计算或设置错误。
3. 计数器模式(CTL.MODE)理解有误(如将UPDWN_PER的周期误认为是TGT)。
1. 确认系统时钟源和频率。
2. 重新计算:定时器时钟 = 系统时钟/(TICKDIV+1)。
3. 牢记:UP_PER周期=(TGT+1)*时钟周期UPDWN_PER周期=2*TGT*时钟周期
占空比不对或不可调1. 比较值CnCC大于目标值TGT
2. 更新CnCC的时机不对,导致抖动或错误。
3. 使用了错误的通道动作(CCACT)。
1. 确保0 <= CnCC <= TGT
2. 使用管道寄存器PCnCC在计数器为零时更新。
3. 检查CCACT:边沿对齐用SET_ON_0_TGL_ON_CMP,中心对齐用CLR_ON_0_TGL_ON_CMP
输出有毛刺1. 动态更新CnCCTGT时未使用管道寄存器,且更新时机在计数器有效范围内。
2. 软件同时操作了OUTCTL手动控制位,与通道自动输出冲突。
1. 强制使用PCnCCPTGT进行更新。
2. 避免在PWM生成时手动操作OUTCTL,或确保优先级逻辑符合预期。

6.2 输入捕获不准或失效排查

现象可能原因排查步骤
捕获不到任何事件1. 输入引脚复用配置错误。
2. 通道配置为输出模式而非输入捕获模式(CCACT)。
3. 边沿检测配置(CnCFG.EDGE)与实际信号边沿不符。
4. 滤波器(CHFILT)设置过于苛刻,滤除了有效信号。
1. 确认GPIO配置为输入,并复用至GPT。
2. 确认CCACT是捕获类动作(如PER_PULSE_WIDTH_MEAS)。
3. 用示波器观察信号,确认配置的边沿(上升、下降)存在。
4. 暂时禁用滤波器(CHFILT.MODE=BYPASS)测试。
捕获值波动大1. 信号本身有抖动或噪声。
2. 定时器时钟频率太低,导致捕获分辨率不足。
3. 中断处理延迟大,导致多次捕获事件堆积或丢失。
1. 启用并合理配置通道滤波器。
2. 提高定时器时钟频率(减小TICKDIV)。
3. 优化中断服务程序,尽快读取CnCC并清除标志。考虑使用DMA。
测量周期值恒为0或极大1. 在PER_PULSE_WIDTH_MEAS模式下,信号周期超过了计数器在两次捕获间的最大计数值(即溢出)。
2. 中断标志未及时清除,导致后续中断丢失。
1. 提高定时器时钟分频,延长单个计数代表的时间。或使用软件扩展计数器。
2. 确保在中断服务程序中读取RISICLR寄存器。

6.3 中断与DMA相关调试要点

  • 中断不触发:首先检查IMASK寄存器是否使能了特定事件中断。然后检查RIS寄存器,看中断状态位是否被置起。如果RIS置位而CPU未进入中断,检查NVIC(嵌套向量中断控制器)是否使能了该GPT的中断,以及中断优先级设置。
  • DMA不工作:首先确认GPT的DMA请求事件已正确配置(DMA.REQ字段)。其次,检查芯片的DMA控制器是否已正确初始化,并配置了从GPT数据寄存器到内存的传输任务。最关键的是,GPT的DMA请求输出需要连接到DMA控制器的特定请求输入线,这通常在系统级事件路由寄存器中配置,这一步极易遗漏。
  • 寄存器读写副作用:务必注意,读取某些寄存器(如CnCC)会自动清除对应的中断标志(RIS.CAP)。如果你的程序既用中断又用轮询,或者在中断中多次读取,可能导致标志被意外清除。在只需要读取值而不想清除标志时,使用对应的“无清除”寄存器(如果存在,如CnCC_NC)。

调试GPT这类复杂外设,逻辑分析仪示波器是必不可少的工具。直接观察引脚上的实际波形,与软件中配置的参数和预期的逻辑进行对比,是定位问题最直接有效的方法。同时,充分利用芯片的寄存器查看功能,在调试器中实时监控关键寄存器(CNTR,RIS,CnCC)的变化,能帮助你深入理解定时器的实时行为。

http://www.cnnetsun.cn/news/3508584.html

相关文章:

  • STM32串口通信基础与HAL库实现
  • ARM GIC中断路由机制与GICD_IROUTER寄存器配置详解
  • 安卓网络请求框架android-async-http详解与优化
  • Android面试核心知识体系与高频问题解析
  • TI ISP寄存器深度解析:CBUFF与CSI1B模块配置实战指南
  • 会计与大数据专业大学四年最好的规划
  • ChatGPT Work实战:如何把一次性对话改造成可复用的任务工作流
  • 深入解析OMAP4460时钟与电源管理:寄存器配置与低功耗设计实战
  • JavaScript 异常捕获完全指南
  • Ubuntu 22.04编译AOSP Android 13完整指南
  • Wallpaper Engine资源逆向全解析:3步掌握PKG解密与TEX纹理转换技术
  • Winform多线程UI操作简化与优化实践
  • 【mimo-硬件损伤-预编码】加权融合预编码 —— 从“单项冠军”到“全能战队”
  • Unity与VS2013/2015调试集成:原理、配置与实战排错指南
  • CANoe CAPL中Checksum与Counter的实现与应用
  • WAIC 2026|范式展出全栈 AI 底座与产业落地成果,构筑 AI 2.0 Token 工厂
  • 多模型网关 Token 账单对不上:流式响应、重试与团队成本归因的实现
  • ShaderGraph沃罗诺伊噪声:从原理到实战,打造程序化纹理与材质
  • 安卓网络请求框架android-async-http详解与优化实践
  • ShaderGraph三角波节点深度解析:从数学原理到UI动效与游戏特效实战
  • ASP.NET Core Identity高级定制与安全实践
  • 支持JavaScript基础语法和数据类型,以及数组、集合、字典、对象操作。 支持require引用模块。 二、安装 1 install-package AScript 2 install-pac
  • Python新手入门:环境搭建与基础语法详解
  • 博客导航系统设计:提升老文章阅读量的技术方案
  • C++多线程编程:跨平台互斥锁原理与实战指南
  • AI自动化不是写脚本,而是重构工程思维:资深架构师拆解4层抽象模型与交付验收标准
  • 期末作业(1)
  • 2026年权威榜单安全触边装置推荐,助你提升工业安全性
  • 2021年Android面试趋势与核心技术解析
  • 3个简单步骤彻底告别键盘连击烦恼:让老旧机械键盘重获新生