CC27xx LGPT1定时器:从寄存器解析到PWM、电机控制与正交解码实战

CC27xx LGPT1定时器:从寄存器解析到PWM、电机控制与正交解码实战 1. LGPT1定时器从寄存器手册到实战应用的深度解析如果你正在使用TI的CC27xx系列无线MCU开发电机控制、电源管理或者需要精确时序的应用那么LGPT1低功耗通用定时器模块绝对是你绕不开的核心外设。手册里那几十页的寄存器描述密密麻麻的位域定义是不是看得头大别急我当年第一次接触时也这样。但真正搞懂之后你会发现这个定时器设计得非常精巧功能强大到超乎想象。今天我就结合自己踩过的坑和实际项目经验带你从寄存器手册的枯燥表格里跳出来看看这些寄存器在真实的PWM生成、电机控制场景下到底怎么用以及那些手册里没明说但至关重要的细节。简单来说LGPT1不是一个简单的计数器。它是一个集成了捕获/比较、PWM生成、死区插入、故障保护和正交解码于一体的多功能定时器。它的寄存器设计体现了模块化、安全性和灵活性的平衡。理解这些寄存器不仅仅是知道每个位是干什么的更要明白它们之间的联动关系以及在不同应用场景下的配置套路。比如你想用中心对齐PWM驱动一个三相无刷电机需要用到哪些寄存器顺序是什么如何避免PWM边沿的抖动故障来了怎么安全停车这些问题的答案都藏在寄存器配置的逻辑里。2. 核心寄存器功能分组与设计逻辑拆解面对四十多个寄存器直接硬啃效率很低。我的经验是先按功能把它们分成几大块理解每一块的设计意图然后再深入细节。LGPT1的寄存器大致可以分为以下几个核心功能组2.1 定时器核心控制与状态寄存器这是定时器的“大脑”负责最基础的计数和模式控制。CTL (Timer Control, 偏移 0Ch)这是总指挥。MODE字段定义了8种工作模式从简单的单次计数(UP_ONCE)、周期计数(UP_PER)到复杂的上下计数(UPDWN_PER)和正交解码模式(QDEC)。这里有个关键点写MODE字段会清空所有通道和TGT寄存器内部排队等待的更新。这意味着如果你在PWM运行过程中改变了MODE之前设置的比较值更新可能会被丢弃导致输出异常。所以手册里反复强调配置定时器时MODE应该是最后设置的一项。CNTR (Counter, 偏移 14h)当前计数值。在大多数模式下它是只读的由硬件根据PRECFG的配置自动递增/递减。只有在QDEC模式下你可以写入一个初始值。TGT (Target, 偏移 13Ch) / PTGT (Pipeline Target, 偏移 FCh)周期值。TGT定义了计数器计数的目标值对于UP_PER模式周期是TGT1对于UPDWN_PER模式周期是2*TGT。PTGT是它的“影子寄存器”你写入PTGT的值会在下一个计数器归零周期开始时才同步到TGT。这是实现无抖动、相位平滑的PWM周期更新的关键。直接写TGT会立即生效但可能在计数周期中间导致当前周期的PWM占空比计算出现混乱产生毛刺。而写PTGT则能保证在周期边界同步更新输出更干净。PRECFG (Clock Prescaler Configuration, 偏移 18h)时钟分频器。TICKSRC选择时钟源系统时钟或外部引脚TICKENTICKDIV设置分频值。定时器时钟频率 TICKSRC频率 / (TICKDIV 1)。这里要注意TICKDIV是8位宽最大分频比是256。如果你的系统时钟是48MHz想要一个1kHz的计数时钟用于生成低频PWM那么TICKDIV需要设置为47999这显然超出了8位范围。这时你就需要利用PREEVENT寄存器或者级联另一个定时器作为预分频器手册里也提到了这一点。2.2 通道配置与捕获比较寄存器这是定时器的“双手”负责具体的输入捕获和输出比较动作。LGPT1最多支持3个独立通道由DESCEX.NCH决定。CxCFG (Channel x Configuration, 偏移 C0h/C4h/C8h)通道行为定义。这是最复杂的寄存器之一核心是CCACT捕获比较动作字段它定义了15种不同的通道功能。简单可以分为几类单次动作(CCACT 1h ~ 7h)比如SET_ON_CAPT_DIS捕获后置位输出并禁用通道适用于单次事件触发。连续动作(CCACT 9h ~ Fh)比如SET_ON_ZERO_TOGGLE_ON_CMPBh归零置位比较翻转这就是生成边沿对齐PWM的标准模式。CLEAR_ON_ZERO_TOGGLE_ON_CMPAh归零清零比较翻转则用于生成中心对齐PWM。测量模式(CCACT 8h)周期和脉宽测量。这个模式很强大可以自动测量输入信号的周期和占空比结果分别存到CxCC和PCxCC。使用时必须确保CTL.MODE DIS时配置INPUT和CCACT然后再启动定时器否则可能因边沿检测电路中的残留值导致错误的捕获事件。CxCC (Channel x Capture Compare, 偏移 140h/144h/148h) / PCxCC (Pipeline... 偏移 100h/104h/108h)比较值/捕获值寄存器。在比较模式下CxCC.VAL是你设置的比较值与CNTR比较触发动作。在捕获模式下触发事件发生时当前的CNTR值会被锁存到CxCC.VAL。PCxCC是CxCC的影子寄存器功能同PTGT与TGT用于无抖动更新PWM的占空比比较值。OUTCTL (Output Control, 偏移 10h)手动输出控制。可以强制置位(SETOUTx)或清零(CLROUTx)某个输出。手动控制的优先级高于通道的自动控制。这在调试或者需要紧急输出特定电平时非常有用。2.3 高级功能与保护寄存器这些是让LGPT1能胜任工业级应用的“安全卫士”和“增强插件”。FAULT (Fault, 偏移 24h) PARK (Park, 偏移 28h)故障保护和安全停车组合。这是电机控制中的黄金搭档。当故障输入引脚通常连接过流、过温等保护电路信号有效时FAULT.CTL决定定时器如何响应立即停止(IMMEDIATE)、等计数器到零再停止(ZEROCOND)或仅触发中断(IRQ)。一旦进入停止状态PARK寄存器就接管了它定义了每个IO输出和互补输出在“停车”状态下应该保持高电平还是低电平。例如在驱动三相桥式电路时通常会将所有PWM输出设置为低电平或某个安全状态防止上下桥臂直通烧毁MOSFET。配置时需要将故障输入映射到某个通道通常是通道0的输入并通过C0CFG.EDGE设置其极性上升沿或下降沿触发。DBDLY (Dead Band Delay, 偏移 2Ch) DBCTL (Dead Band Control, 偏移 30h)死区时间控制。驱动H桥或三相逆变器时必须防止同一桥臂的上下两个开关管同时导通直通。死区就是在互补的PWM信号切换之间插入的一段两个管子都关闭的时间。DBDLY分别设置上升沿延迟(RISEDLY)和下降沿延迟(FALLDLY)单位是系统时钟周期。DBCTL则用于使能对应通道的死区功能。注意死区逻辑是在IO输出级实现的它作用于已经生成的PWM信号。CHFILT (Channel Input Filter, 偏移 20h)输入滤波。对于可能带有毛刺的输入信号如机械编码器可以通过这个滤波器进行消抖。LOAD值决定了需要连续多少个相同的采样值才认为输入有效。MODE选择滤波器的时钟源。配置滤波器必须在CTL.MODE DIS时进行否则行为不可预测。2.4 中断与DMA控制寄存器这是与CPU协同工作的“通信官”。RIS (Raw Interrupt Status, 偏移 6Ch)原始中断状态。任何中断事件计数器到目标TGT、归零ZERO、捕获比较CxCC、故障FAULT等都会置位对应的位。IMASK (Interrupt Mask, 偏移 68h)中断掩码。只有IMASK中使能的位对应的RIS事件才能传递到MISMasked Interrupt Status。MIS (偏移 70h)被屏蔽后的中断状态。通常CPU中断服务程序(ISR)查询的是这个寄存器或直接由MIS触发中断。ICLR (Interrupt Clear, 偏移 78h)中断清除。向某位写1清除对应的RIS和MIS标志。这里有个常见坑点清除中断标志是写1而不是写0。DMA (偏移 3Ch) DMARW (偏移 40h)DMA控制。可以将特定的中断事件如周期性的TGT或CxCC事件作为DMA请求源自动搬运数据例如从内存中的波形表更新PCxCC寄存器极大减轻CPU负担实现高精度、无抖动的波形合成。2.5 其他辅助寄存器IOCTL (IO Controller, 偏移 48h)IO输出覆盖控制。可以强制将某个输出驱动为高、低、反相或正常。优先级低于OUTCTL的手动控制但高于通道的自动控制。用于特殊测试或初始化。DESC/DESCEX (偏移 0h/4h)模块描述。只读用于识别IP模块的ID、版本和实例索引。在驱动程序中可用于验证外设基地址是否正确。带NC后缀的寄存器 (如TGTNC,CxCCNC)“No Clear”版本。读取或写入这些寄存器不会自动清除对应的RIS中断标志。当你需要频繁查询或修改这些值但又不想影响中断状态时就用它们。3. PWM生成实战从边沿对齐到中心对齐的配置详解理论说再多不如一行代码。我们以生成一个频率1kHz占空比可变的PWM为例看看如何配置寄存器。假设系统时钟SYSCLK 48MHz我们使用通道0输出PWM。3.1 边沿对齐PWM配置边沿对齐PWM的特点是所有通道的PWM脉冲起始边沿通常是上升沿对齐在计数达到比较值时产生动作如下降沿。步骤1计算定时器参数我们需要1kHz的PWM频率即周期T1ms。选择CTL.MODE UP_PER周期向上计数模式。在此模式下PWM周期 (TGT.VAL 1) * 定时器时钟周期。设定定时器时钟。为了获得较好的分辨率我们不希望分频太大。假设选择定时器时钟为1MHzTICKDIV 47。则定时器时钟周期 1us。计算TGT.VALPWM周期 1ms 1000us (TGT.VAL 1) * 1usTGT.VAL 999(0x3E7)。占空比 C0CC.VAL / (TGT.VAL 1)。假设需要50%占空比则C0CC.VAL 500(0x1F4)。步骤2寄存器配置流程配置顺序很重要错误的顺序可能导致意外的输出毛刺。// 1. 首先停止定时器并确保在安全状态下配置 LGPT1-CTL.MODE DIS; // 停止计数 // 2. 配置预分频器得到1MHz的定时器时钟 (假设TICKSRC使用系统时钟) LGPT1-PRECFG.TICKSRC 0; // 时钟源 系统时钟 LGPT1-PRECFG.TICKDIV 47; // 分频系数 48MHz / (471) 1MHz // 3. 设置PWM周期 (使用PTGT实现无抖动更新) LGPT1-PTGT.VAL 999; // 影子寄存器写入目标值 // 4. 配置通道0为边沿对齐PWM模式并关联到输出0 LGPT1-C0CFG.CCACT SET_ON_ZERO_TOGGLE_ON_CMP; // 0xB: 归零置位比较翻转 LGPT1-C0CFG.OUT0 1; // 通道0控制输出0 LGPT1-C0CFG.INPUT 0; // 输入源不重要我们只用输出 LGPT1-C0CFG.EDGE NONE; // 不使用输入边沿检测 // 5. 设置初始占空比 (使用PC0CC影子寄存器) LGPT1-PC0CC.VAL 500; // 50%占空比 // 6. 最后启动定时器 LGPT1-CTL.MODE UP_PER;关键点我们使用了PTGT和PC0CC这两个影子寄存器来设置周期和比较值。在CTL.MODE从DIS变为UP_PER的瞬间硬件会自动将PTGT的值加载到TGT将PC0CC的值加载到C0CC。这样确保了第一个PWM周期就是设定的周期和占空比没有中间状态。3.2 中心对齐PWM配置中心对齐PWM的脉冲中心对齐常用于电机控制能减少谐波。它需要定时器工作在UPDWN_PER上下计数模式。步骤1计算定时器参数同样生成1kHz PWM使用UPDWN_PER模式。CTL.MODE UPDWN_PER。在此模式下PWM周期 (2 * TGT.VAL) * 定时器时钟周期。保持定时器时钟1MHz。计算TGT.VAL周期 1000us 2 * TGT.VAL * 1usTGT.VAL 500(0x1F4)。占空比计算与边沿对齐不同。对于CLEAR_ON_ZERO_TOGGLE_ON_CMP模式占空比 1 - (C0CC.VAL / TGT.VAL)。50%占空比时C0CC.VAL 250(0xFA)。步骤2寄存器配置流程// 1. 停止定时器 LGPT1-CTL.MODE DIS; // 2. 配置预分频器 (同上) LGPT1-PRECFG.TICKSRC 0; LGPT1-PRECFG.TICKDIV 47; // 3. 设置PWM周期 LGPT1-PTGT.VAL 500; // 注意UPDWN_PER模式下周期是2*TGT // 4. 配置通道0为中心对齐PWM模式 LGPT1-C0CFG.CCACT CLEAR_ON_ZERO_TOGGLE_ON_CMP; // 0xA: 归零清零比较翻转 LGPT1-C0CFG.OUT0 1; LGPT1-C0CFG.INPUT 0; LGPT1-C0CFG.EDGE NONE; // 5. 设置初始占空比 LGPT1-PC0CC.VAL 250; // 50%占空比 // 6. 启动定时器为上下计数模式 LGPT1-CTL.MODE UPDWN_PER;核心差异模式(CCACT)从Bh换成了Ah定时器模式从UP_PER换成了UPDWN_PERTGT和CxCC的计算公式也变了。中心对齐PWM在计数器从0向上计数到CxCC时翻转一次从TGT向下计数到CxCC时再翻转一次形成一个对称的脉冲。3.3 动态更新PWM参数在电机控制中我们需要实时改变PWM占空比调速甚至频率变频。如何做到平滑无抖动// 假设需要在运行中改变占空比为75% uint16_t new_duty_compare 750; // 对于边沿对齐模式TGT999时75%占空比 // 错误做法直接写C0CC可能会在计数周期中间生效导致当前周期脉宽异常。 // LGPT1-C0CC.VAL new_duty_compare; // 正确做法写入管道寄存器PC0CC LGPT1-PC0CC.VAL new_duty_compare; // 硬件会在下一个CNTR归零的周期开始时自动将PC0CC的值载入C0CC实现同步更新无抖动。 // 如果需要改变频率周期 uint16_t new_period 1999; // 新的TGT值对应约500Hz (如果时钟1MHz) LGPT1-PTGT.VAL new_period; // 同样使用影子寄存器这就是影子寄存器(PTGT,PCxCC)的价值所在它们提供了一个缓冲让软件可以在任何时间安全地更新参数而硬件则在下一个规整的周期边界计数器归零进行同步完全避免了因更新时机不当导致的脉冲宽度畸变或缺失。4. 电机控制关键场景互补PWM与死区插入用单个PWM驱动一个直流电机调速很简单但驱动一个三相无刷直流电机(BLDC)或永磁同步电机(PMSM)就需要互补PWM和死区插入。4.1 互补PWM输出配置假设我们用通道0和通道1生成一对互补的PWM驱动一个H桥的上半桥和下半桥。// 配置通道0生成主PWM例如上管驱动 LGPT1-C0CFG.CCACT SET_ON_ZERO_TOGGLE_ON_CMP; // 边沿对齐归零置位比较翻转 LGPT1-C0CFG.OUT0 1; // 控制输出0假设连接上管 // 配置通道1生成互补PWM // 我们需要下管的信号与上管反相但为了插入死区我们不直接使用反相而是用另一个通道生成 LGPT1-C1CFG.CCACT CLEAR_ON_ZERO_TOGGLE_ON_CMP; // 注意这里是CLEAR_ON_ZERO LGPT1-C1CFG.OUT1 1; // 控制输出1假设连接下管 // 设置相同的比较值确保翻转点一致 LGPT1-PC0CC.VAL duty_compare; LGPT1-PC1CC.VAL duty_compare;此时OUT0和OUT1输出的就是一对反相但有重叠的PWM。直接用它驱动H桥会导致上下管直通。4.2 死区时间插入配置死区时间(Dead Time)是必须的。我们使用硬件死区生成单元。// 1. 计算需要的死区时间对应的系统时钟周期数 // 假设系统时钟48MHz需要500ns的死区时间。 // 死区时间 RISEDLY (或 FALLDLY) * SysClk_Period // SysClk_Period ≈ 20.83ns // RISEDLY 500ns / 20.83ns ≈ 24 (0x18) // 通常上升沿和下降沿延迟设相同值。 // 2. 配置死区延迟寄存器 LGPT1-DBDLY.RISEDLY 24; LGPT1-DBDLY.FALLDLY 24; // 3. 使能对应输出通道的死区功能 // 假设OUT0是参考信号OUT1是其互补信号经过死区逻辑 LGPT1-DBCTL.IO0 ENABLE; // 使能输出0及其互补输出的死区插入 // 4. 注意使能死区后硬件会自动生成互补信号。 // 因此我们可能不需要再单独配置通道1来生成反相PWM。 // 更常见的做法是只用一个通道(如通道0)控制OUT0使能死区后硬件会自动产生互补信号到IOC0IO Complementary Output 0。 // 我们需要将IOC0映射到实际的物理引脚通过GPIO复用功能配置来驱动下管。使能DBCTL.IO0后原始OUT0信号作为参考信号。硬件会生成两个新信号一个在参考信号上升沿后延迟RISEDLY个系统时钟才变高另一个在参考信号下降沿后延迟FALLDLY个系统时钟才变高。这两个信号分别作为上管和下管的驱动信号保证了在任何切换时刻两个信号都有一段同时为低电平的时间即死区时间。4.3 故障保护与安全停车配置这是工业应用的底线。// 1. 配置故障输入。假设故障信号连接到通道0的输入通过IO控制器或事件 fabric高电平有效。 LGPT1-C0CFG.INPUT 1; // 输入源选择IO控制器具体引脚需另行配置 LGPT1-C0CFG.EDGE RISE; // 上升沿触发即高电平为故障有效 // 2. 配置故障响应模式 LGPT1-FAULT.CTL IMMEDIATE; // 立即停止计数器。也可以选择ZEROCOND等待周期结束更平滑但响应慢。 // 3. 配置停车状态。发生故障时我们希望所有PWM输出都置为低电平安全状态。 LGPT1-PARK.CTL ENTER_PARK_ON_FAULT; // 故障时进入停车模式 LGPT1-PARK.IOPS0 0; // 输出0上管停车状态为低 LGPT1-PARK.IOCPS0 0; // 互补输出0下管停车状态为低 // 如果还有其他通道同样配置IOPS1, IOCPS1等。 // 4. 可选使能故障中断以便CPU能及时记录故障信息 LGPT1-IMASK.FAULT 1; // 使能FAULT中断掩码 // 在中断服务程序中需要读取RIS.FAULT标志并通过写ICLR.FAULT来清除。当故障引脚变为高电平时硬件会立即将CTL.MODE设为DIS计数器停止。同时所有输出包括经过死区处理的都会被强制驱动到PARK寄存器中定义的安全状态。这个过程是纯硬件实现的响应速度极快几个时钟周期内不依赖于软件中断响应这对于保护功率器件至关重要。5. 正交解码与输入捕获应用解析除了输出LGPT1的输入功能也很强大常用于读取编码器或测量脉冲信号。5.1 正交解码模式配置正交解码用于读取增量式编码器获取位置和速度。// 1. 配置定时器模式为正交解码 LGPT1-CTL.MODE QDEC; // 2. 配置通道输入。在QDEC模式下硬件固定分配 // IOC Input 0 - PHA (A相) // IOC Input 1 - PHB (B相) // IOC Input 2 - IDX (索引信号可选) // 需要通过IOCTL或GPIO模块将对应物理引脚映射到这些IOC输入。 // 3. 配置通道2IDX输入的边沿检测如果需要索引信号 LGPT1-C2CFG.EDGE RISE; // 例如索引信号上升沿触发 // 如果不需要索引信号则设置为NONE。 // 4. 配置预分频器。PRECFG.TICKSRC决定了正交信号的采样率。 // 采样时钟频率必须远高于编码器信号的最大预期频率通常至少4-10倍。 LGPT1-PRECFG.TICKSRC 0; // 使用系统时钟 LGPT1-PRECFG.TICKDIV 0; // 不分频获得最高采样率 // 5. 可选使能相关中断如方向改变(DIRCHNG)、索引信号(IDX)等。 LGPT1-IMASK.DIRCHNG 1; LGPT1-IMASK.IDX 1; // 6. 读取位置。在QDEC模式下CNTR寄存器自动根据A、B相信号增减。 // 当前位置 LGPT1-CNTR.VAL; // 速度可以通过定期采样CNTR值并计算差值得到。在QDEC模式下CNTR寄存器变成了位置计数器。TGT和PTGT寄存器在索引信号(IDX)事件时有特殊用途当计数器向上计数时遇到IDXCNTR被载入0向下计数时遇到IDXCNTR被载入PTGT.VAL的值。这可以用于归零或设置一个预加载值。5.2 输入捕获与脉宽测量测量外部信号的频率或占空比。// 1. 停止定时器 LGPT1-CTL.MODE DIS; // 2. 配置输入通道。假设信号连接到通道0的输入。 LGPT1-C0CFG.INPUT 1; // 从IO控制器输入 LGPT1-C0CFG.EDGE NONE; // 先关闭边沿检测这是关键步骤防止残留值触发误捕获。 LGPT1-C0CFG.CCACT PER_PULSE_WIDTH_MEAS; // 0x8: 周期和脉宽测量模式 LGPT1-C0CFG.OUT0 0; // 测量模式通常不需要控制输出 // 3. 等待至少3个定时器时钟周期根据PRECFG配置让边沿检测电路稳定。 // 这通常通过一个短暂的延时循环实现。 // 4. 启动边沿检测。我们想测量信号的周期和正脉宽所以选择上升沿。 LGPT1-C0CFG.EDGE RISE; // 5. 启动定时器单次或周期模式均可周期模式可连续测量 LGPT1-CTL.MODE UP_PER; LGPT1-PTGT.VAL 0xFFFF; // 设置一个足够大的超时值防止信号丢失时一直等待。 // 6. 等待捕获完成中断或轮询RIS.C0CC标志 while((LGPT1-RIS (1 8)) 0) { // 等待C0CC中断标志 // 超时处理可以检查RIS.TGT if(LGPT1-RIS 1) { // TGT中断表示超时 // 处理超时 LGPT1-ICLR.TGT 1; // 清除TGT中断 break; } } // 7. 读取测量结果 if(LGPT1-RIS (1 8)) { uint16_t signal_period LGPT1-C0CC.VAL; // 信号周期计数器 ticks uint16_t pulse_width LGPT1-PC0CC.VAL; // 脉冲宽度正脉宽因为EDGERISE LGPT1-ICLR.C0CC 1; // 清除捕获中断标志 // 转换为时间时间 ticks * (TICKDIV1) * SysClk_Period float period_sec (float)signal_period * (LGPT1-PRECFG.TICKDIV 1) / SYSTEM_CLOCK_FREQ; float freq_hz 1.0 / period_sec; float duty_cycle (float)pulse_width / signal_period; }测量模式的核心CCACT8h时通道会连续测量。一次完整的测量会捕获两个值整个信号的周期存入CxCC指定边沿由EDGE决定到下一个相反边沿的脉宽存入PCxCC。如果EDGERISE则PCxCC存储的是正脉宽如果EDGEFALL存储的是负脉宽。手册中强调了信号频率的限制信号周期必须大于等于2*(TICKDIV1)*定时器时钟周期且正/负脉宽必须大于等于(TICKDIV1)*定时器时钟周期。这意味着输入信号不能快于定时器采样时钟的一半且不能有极窄的毛刺。6. 中断与DMA使用技巧及常见问题排查6.1 中断处理流程与注意事项初始化流程// a. 配置IMASK使能需要的中断源如TGT, ZERO, C0CC LGPT1-IMASK.TGT 1; LGPT1-IMASK.C0CC 1; // b. 在NVIC中使能LGPT1全局中断。 // c. 启动定时器。中断服务程序(ISR)标准写法void LGPT1_IRQHandler(void) { // 1. 读取MIS或RIS确定中断源 uint32_t mis_status LGPT1-MIS; // 2. 根据中断源处理 if(mis_status (1 0)) { // TGT中断 // 处理周期事件例如更新动态波形... LGPT1-ICLR.TGT 1; // 写1清除中断标志 } if(mis_status (1 8)) { // C0CC中断 // 处理比较匹配或捕获完成事件 // 如果是捕获模式记得读取C0CC.VAL或PC0CC.VAL LGPT1-ICLR.C0CC 1; // 写1清除中断标志 } // ... 处理其他中断 // 重要清除中断标志必须在处理逻辑之后且是向ICLR对应位写1不是写0。 }常见坑点忘记清除中断标志导致ISR不断重复进入。错误地清除标志向ICLR寄存器写0是无效的必须写1。直接给ICLR赋值一个位掩码是危险操作因为它会清除所有写1的位对应的中断。安全做法是LGPT1-ICLR.TGT 1;如果外设支持位操作或使用|操作。在ISR中读取RIS而不是MISRIS包含所有原始中断即使被IMASK屏蔽了。如果查询RIS可能会处理到本应被屏蔽的中断。通常ISR应该查询MIS。6.2 使用DMA自动更新PWM波形对于需要生成复杂波形如正弦波、SPWM的应用使用DMA可以解放CPU。// 假设我们有一个存储在数组sin_table[]中的正弦波比较值序列。 // 我们希望在每个PWM周期结束时自动更新C0CC占空比。 // 1. 配置DMA寄存器 // 设置DMA请求源为TGT事件每个PWM周期结束 LGPT1-DMA.REQ 0x1; // 0x1对应RIS.TGT // 设置DMA要访问的基地址。我们要更新PC0CC寄存器偏移0x100。 // RWADDR (物理地址偏移量 / 4) 的低9位。 // 假设LGPT1基地址为0x4000A000则PC0CC地址为0x4000A100。 // 偏移量是0x100。0x100 / 4 0x40。RWADDR[8:0] 0x40。 LGPT1-DMA.RWADDR 0x40; // 设置DMA传输次数。假设sin_table有100个点。 // RWCNTR 传输次数 - 1。 LGPT1-DMA.RWCNTR 99; // 2. 配置DMA控制器这部分是DMA控制器的配置非LGPT1 // 设置DMA源地址为sin_table数组地址。 // 设置DMA目标地址为LGPT1-DMARW的地址偏移0x40。 // 设置传输数量为100宽度为16位半字。 // 设置触发源为LGPT1的DMA请求。 // 3. 启动DMA和定时器。 // DMA控制器会等待LGPT1的TGT事件。每次TGT事件发生LGPT1会发出一个DMA请求。 // DMA控制器响应请求将sin_table中的一个数据写入DMARW寄存器。 // 写入DMARW会自动将数据搬运到内部指针指向的地址初始是PC0CC并递增指针。 // 经过100次传输后DMA传输完成可以重新配置或停止。DMA模式的精妙之处DMARW寄存器像一个窗口。DMA控制器只需要不断地向DMARW写入数据LGPT1内部会根据RWADDR和内部递增的指针自动将数据分发到正确的影子寄存器PCxCC,PTGT。这实现了波形表的自动循环播放无需CPU干预。6.3 典型问题排查清单没有PWM输出检查时钟PRECFG配置是否正确TICKDIV是否过大导致时钟几乎停止检查模式CTL.MODE是否已设置为UP_PER或UPDWN_PER写MODE后是否等待了足够时间检查输出使能CxCFG.OUTx位是否设置为1对应的GPIO引脚是否已复用为LGPT1输出功能检查IO覆盖IOCTL寄存器是否强制覆盖了输出OUTCTL是否手动控制了输出PWM频率或占空比不对计算公式确认TGT和CxCC的计算公式与当前CTL.MODE和CxCFG.CCACT匹配。影子寄存器你是直接写的CxCC/TGT还是写的PCxCC/PTGT直接写可能在周期中间生效。确保在定时器停止(DIS)时或使用影子寄存器更新。寄存器位宽CNTR、TGT、CxCC都是16位根据DESCEX.CNTRW可能不同确保赋值没有溢出。中断不触发中断使能IMASK对应位使能了吗NVIC中的外设中断使能了吗事件是否发生通过调试器读取RIS寄存器看期望的中断标志位是否置1。如果没有检查定时器是否正常运行比较值设置是否合理。标志清除在ISR中是否正确地清除了中断标志清除后该标志位在RIS中是否变回0输入捕获值不准或混乱滤波配置输入信号是否有毛刺考虑配置CHFILT进行滤波。配置顺序在捕获模式下是否严格按照手册步骤先设EDGENONE再配CCACT等待最后设EDGE这是避免错误捕获的关键。信号频率超限输入信号频率是否超出了测量模式的要求周期需≥2*(TICKDIV1)*定时器时钟超时处理是否处理了RIS.TGT超时事件如果信号丢失捕获可能永远不会完成。死区时间不生效使能位DBCTL对应通道的使能位IO0等是否设置为1延迟值RISEDLY和FALLDLY设置是否合理单位是系统时钟周期不是定时器时钟周期。输出观察使用逻辑分析仪同时观察原始的OUTx信号和经过死区处理后的IOx及IOCx信号确认延迟是否按预期插入。故障保护不动作输入映射故障信号是否正确地映射到了通道0的输入检查C0CFG.INPUT和EDGE用于设置极性。FAULT.CTL模式是否设置为IMMEDIATE或ZEROCONDPARK配置PARK.CTL是否使能了故障停车IOPSx和IOCPSx设置的安全状态是否正确信号极性故障信号的有效电平是否与C0CFG.EDGE设置匹配例如故障电路输出低电平有效但EDGE设成了RISE。调试时最有效的工具是示波器和逻辑分析仪结合调试器实时查看寄存器值。特别是对于时序要求严格的PWM和死区一定要用仪器实际测量输出波形与理论计算值对比。寄存器配置就像搭积木每一块都必须放对位置顺序也不能乱。希望这份结合了手册要点和实战经验的解析能帮你把CC27xx的LGPT1定时器真正用起来用得好。