深入解析ePWM寄存器配置:从架构到实战的电机控制核心外设指南

1. 项目概述:从寄存器表到可运行的PWM波形

如果你曾经在TI的C2000或者一些高端的ARM Cortex-R/M系列MCU上做过电机控制、数字电源或者逆变器项目,那么ePWM(Enhanced Pulse Width Modulator)模块绝对是你绕不开的核心外设。手册里动辄几十页的寄存器描述和复杂的信号流图,第一次看的时候确实让人头大。我记得刚开始接触时,面对那张密密麻麻的寄存器映射表(就像你提供的Table 19-1),感觉就像在看天书,只知道每个子模块有一堆寄存器,但具体怎么把它们串起来,让两个引脚输出我想要的、带死区互补、还能响应紧急关断的PWM波,心里完全没底。

这份手册片段,恰恰是理解ePWM的“地图”和“零件清单”。它没有直接告诉你如何开车到达目的地,但它清晰地标出了所有的路口(子模块)和交通规则(寄存器配置)。ePWM的本质,是一个高度可编程的波形合成流水线。时间基准(TB)子模块是心脏,产生节拍;计数器比较(CC)子模块是乐谱,标记关键时间点;动作限定(AQ)子模块是指挥,根据乐谱和节拍指挥输出引脚动作;而死区(DB)、故障保护(TZ)等子模块则是安全员和特效师,确保动作安全并添加必要效果。我们程序员要做的,就是通过配置这些寄存器,编排好整个流水线的工作流程。

本文将带你深入这张“地图”,我们不会停留在简单翻译手册。我会结合多年在电机驱动和电源项目中的实际调试经验,拆解每个核心子模块的寄存器如何配置,信号如何流动,并解释为什么TI要这样设计。更重要的是,我会分享那些手册里不会写的“坑”和技巧,比如影子寄存器更新时机没对齐导致的波形毛刺、同步链配置错误引发的多个PWM模块相位混乱、以及如何利用数字比较(DC)模块实现更灵活的故障保护。无论你是正在评估ePWM用于新项目,还是正在调试一个棘手的PWM输出问题,相信这篇基于寄存器视角的深度解析都能给你带来直接的帮助。

2. ePWM模块整体架构与寄存器地图解析

拿到一个ePWM模块,第一件事不是急着写代码,而是理解它的整体架构和寄存器组织方式。这能帮你建立全局观,知道配置的每一个比特位最终影响了信号流图中的哪个环节。

2.1 模块化流水线:信号是如何被“加工”的

ePWM不是一个单一的功能块,而是一条精心设计的信号处理流水线。你提供的框图(图19-2,在摘要描述中提及)完美地展示了这一点。原始的时间基准信号(CTR=PRD, CTR=ZERO)和比较匹配信号(CTR=CMPA, CTR=CMPB)从左侧输入,经过一系列子模块的“加工”,最终从右侧的EPWMxA和EPWMxB引脚输出。

这条流水线的核心路径是:TB -> CC -> AQ -> DB -> PC -> Output

  • 时间基准 (TB): 产生最基础的计数节拍(TBCTR)和周期/过零事件。它是所有时序的源头。
  • 计数器比较 (CC): 在TB产生的节拍上,通过CMPA和CMPB寄存器设置两个“时间戳”,当TBCTR计数到这两个值时,产生比较匹配事件。
  • 动作限定 (AQ): 这是最关键的波形生成环节。它接收来自TB和CC的四个核心事件(CTR=PRD, ZERO, CMPA, CMPB),并根据当前计数方向(向上/向下),决定在每一个事件发生时,对输出引脚EPWMxA和EPWMxB采取什么“动作”:置高、拉低、翻转,或保持不动。通过组合这些动作,就能生成占空比可变的PWM波。
  • 死区生成 (DB): 接收AQ输出的原始波形,为互补的一对信号(通常用于驱动半桥的上管和下管)插入可编程的上升沿延迟和下降沿延迟,确保两个开关管不会同时导通(即“直通”),这是功率电路的安全生命线。
  • PWM斩波 (PC): 一个可选的子模块,用于生成高频载波对PWM信号进行调制,常用于驱动隔离变压器或IGBT/MOSFET的栅极驱动芯片。

而流水线两侧还有重要的“监控与应急”通道:

  • 故障保护 (TZ): 平行于主流水线。它监听外部故障引脚(nTZ1~nTZ3)或内部数字比较事件。一旦触发,可以立即(异步于TBCLK)强制PWM输出到预设的安全状态(高、低、高阻),实现纳秒级的硬件保护。
  • 事件触发 (ET): 监控流水线中的各种事件(如CTR=PRD, CTR=CMPA),可以产生中断(EPWMxINT)或触发ADC启动转换(EPWMxSOCA/B),实现精准的采样与控制闭环。
  • 数字比较 (DC): 一个更高级、更灵活的故障信号生成器。它可以将外部信号(如电流采样经比较器后的数字信号)与内部事件进行逻辑组合,生成故障事件送给TZ模块,或者直接生成同步信号送给TB模块。

理解这个架构,你就明白了:配置ePWM,本质上是在配置这条流水线上每一个加工环节的行为规则。

2.2 寄存器映射表:你的配置工具箱

Table 19-1 不是一张简单的地址列表,它是整个ePWM模块的硬件功能索引。TI的工程师按照子模块对寄存器进行了分组,这非常符合我们的编程逻辑。

首先看“Address Offset”: 这是寄存器相对于该ePWM模块实例基地址的偏移量。例如,ePWM1的基地址可能是0x6800,那么TBCTL寄存器的地址就是0x6800 + 0x0002 = 0x6802。每个ePWM模块(EPWM1, EPWM2...)都有完全相同的一套寄存器组,只是基地址不同,这种设计使得驱动代码可以高度复用。

关键列解析:

  • Shadow (影子寄存器): 这是ePWM可靠性的关键设计。标记为“Yes”的寄存器(如TBPRD, CMPA, CMPB)拥有影子寄存器。当你写入这个寄存器地址时,数据先进入影子寄存器,不会立即影响正在运行的PWM波形。只有在特定的“加载点”(如CTR=ZERO或CTR=PRD),影子寄存器的值才会被硬件自动加载到“活动寄存器”中,从而生效。这避免了在PWM周期中间修改参数导致的脉冲宽度异常或毛刺。标记为“No”的寄存器(如TBCTL, AQCTLA)则是直接生效,需谨慎操作。
  • Privileged Mode Write Only?: 标记为“Yes”的寄存器(主要是TZ和DC子模块相关)只能在CPU的特权模式下写入。这通常是为了安全考虑,防止应用程序代码意外修改故障保护配置,你需要在初始化阶段于特权模式下配置好它们。

一个重要的实操心得: 在系统初始化时,我习惯先配置所有“Shadow”寄存器(如TBPRD, CMPA, CMPB),然后再配置控制寄存器(如TBCTL)来启动计数器。因为控制寄存器可能立即生效,而周期/比较值若未提前设置,可能会产生非预期的初始脉冲。对于TZ等安全相关寄存器,一定要在进入main()后的初始化阶段,确保处于特权模式下完成配置。

3. 核心子模块深度配置与实战要点

了解了全局地图,现在我们深入最重要的几个“车间”,看看如何操作这些“机器”(寄存器)。

3.1 时间基准(TB)子模块:一切节拍的起源

TB子模块定义了PWM的“心跳”。其核心寄存器是TBCTL、TBPRD、TBPHS和TBCTR。

3.1.1 计数模式与频率计算

TBCTL[CTRMODE]位域决定了计数模式,直接影响PWM频率和波形对称性。

  • 向上计数模式 (Up-Count): TBCTR从0计数到TBPRD,然后归零。PWM周期Tpwm = (TBPRD + 1) * Ttbclk。这种模式产生不对称PWM,事件只在计数器递增时发生一次。适用于简单的开关控制。
  • 向下计数模式 (Down-Count): TBCTR从TBPRD递减到0,然后重载TBPRD。周期公式同上。也产生不对称PWM。
  • 向上向下计数模式 (Up-Down-Count): TBCTR从0递增到TBPRD,再递减回0,如此循环。PWM周期Tpwm = 2 * TBPRD * Ttbclk。这种模式产生对称PWM,中心对齐,谐波特性更好,是电机控制和数字音频的首选模式,因为每个周期内,CTR=CMPA和CTR=CMPB事件会各发生两次(一次递增,一次递减),为精细控制提供了更多可能性。

计算示例: 假设系统时钟SYSCLK = 200MHz,TBCTL[HSPCLKDIV:CLKDIV] 配置为 /2,则 TBCLK = 100MHz,Ttbclk = 10ns。若需要产生20kHz的对称PWM,则:TBPRD = (1 / (2 * Fpwm * Ttbclk)) = (1 / (2 * 20kHz * 10ns)) = 2500。 在代码中,我们这样设置:

EPwm1Regs.TBPRD = 2500; // 设置周期值 EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // 设置为上下计数模式 EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2; // 高速时钟预分频 EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // 时钟预分频

3.1.2 同步与相位控制

这是实现多路PWM协调工作的核心。假设我们有一个三相逆变器,需要6路PWM,且互差120度相位。

  • 硬件同步链: 如图19-6所示,EPWM1的SYNCO可以连接到EPWM2的SYNCI,EPWM2的SYNCO连接到EPWM3的SYNCI,以此类推。通过配置TBCTL[SYNCOSEL],可以指定SYNCO信号的来源(如CTR=ZERO)。当EPWM1的计数器归零时,它会发出一个同步脉冲给EPWM2,EPWM2在收到脉冲后,可以根据TBCTL[PHSEN]和TBPHS寄存器进行相位调整。
  • 相位控制: 在从模块(如EPWM2)中,使能相位加载(TBCTL[PHSEN]=1),并设置TBPHS寄存器为一个非零值。当从模块收到同步脉冲(SYNCI)时,不是将TBCTR重置为0,而是加载TBPHS的值。例如,EPWM1的TBPRD=6000,要实现120度相位差,则相位差对应的计数值为(120/360) * 2 * TBPRD = (1/3) * 12000 = 4000(对称模式,一个电气周期为2*TBPRD)。那么EPWM2的TBPHS可设为4000。这样,EPWM2的波形就会滞后EPWM1三分之一周期。

注意: 同步和相位加载是一个容易出错的地方。务必确保在启用同步(PHSEN)前,主模块的同步输出已正确配置,并且从模块的计数器模式、周期与主模块一致。否则可能导致不可预测的相位关系。我建议的初始化顺序是:1) 停止所有相关ePWM模块的时钟(TBCLKSYNC=0);2) 配置所有模块的TBPRD、TBPHS;3) 配置主模块的SYNCOSEL;4) 配置从模块的PHSEN和同步源;5) 同时启动所有模块的时钟(TBCLKSYNC=1)。

3.2 计数器比较(CC)与动作限定(AQ)子模块:波形的雕刻师

CC和AQ子模块是紧密协作的,CC定义“时刻”,AQ定义在该“时刻”的“动作”。

3.2.1 影子寄存器与加载模式

CMPA和CMPB寄存器都有影子寄存器。CMPCTL[LOADAMODE]和[LOADBMODE]控制加载时机:

  • LOADMODE = 0: 在CTR=ZERO时,从影子寄存器加载到活动寄存器。
  • LOADMODE = 1: 在CTR=PRD时加载。
  • LOADMODE = 2: 在CTR=ZERO或CTR=PRD时都加载(即立即加载,失去缓冲作用,慎用)。
  • LOADMODE = 3: 冻结,不自动加载。

在对称PWM(上下计数)模式下的一个关键技巧: 通常将加载点设置为CTR=ZERO。这样,你在一个PWM周期内(从0到PRD再到0)的任何时间更新CMPA/CMPB的影子寄存器,新的比较值都会在下一个周期开始时(CTR=ZERO)生效,确保整个PWM周期的占空比是一致的,避免了半个周期更新导致的波形不对称。这对于电机控制中需要平滑改变占空比的场合至关重要。

3.2.2 动作限定逻辑:将事件转化为边沿

这是ePWM最精妙的部分之一。AQ子模块通过AQCTLA和AQCTLB两个寄存器,独立控制EPWMxA和EPWMxB在每个事件发生时的动作。

以生成一对互补的对称PWM为例(EPWMxA高电平有效,EPWMxB低电平有效):

  1. 在向上计数过程中
    • CTR = CMPA(向上) 时: 我们希望EPWMxA置低,EPWMxB置高(因为互补)。
    • CTR = PRD时: 计数器达到峰值,开始向下计数。这个时刻通常不改变输出(除非需要特殊波形)。
  2. 在向下计数过程中
    • CTR = CMPA(向下) 时: 我们希望EPWMxA置高,EPWMxB置低
    • CTR = ZERO时: 计数器归零,开始向上计数。这个时刻通常也不改变输出。

对应的寄存器配置如下:

// 配置CMPA的值,用于控制占空比。假设TBPRD=2500,需要50%占空比。 EPwm1Regs.CMPA.half.CMPA = 1250; // 配置AQCTLA - 控制EPWMxA输出 EPwm1Regs.AQCTLA.bit.ZRO = AQ_NO_ACTION; // CTR=ZERO时不动作 EPwm1Regs.AQCTLA.bit.PRD = AQ_NO_ACTION; // CTR=PRD时不动作 EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // 向上计数时,CTR=CMPA则清除(置低) EPwm1Regs.AQCTLA.bit.CAD = AQ_SET; // 向下计数时,CTR=CMPA则置高 // 配置AQCTLB - 控制EPWMxB输出 (与EPWMxA互补) EPwm1Regs.AQCTLB.bit.ZRO = AQ_NO_ACTION; EPwm1Regs.AQCTLB.bit.PRD = AQ_NO_ACTION; EPwm1Regs.AQCTLB.bit.CAU = AQ_SET; // 向上计数时,CTR=CMPA则置高(与A相反) EPwm1Regs.AQCTLB.bit.CAD = AQ_CLEAR; // 向下计数时,CTR=CMPA则清除(与A相反)

通过这样的配置,我们就得到了一个中心对齐、占空比为50%的互补PWM对。改变CMPA的值,就能线性地改变占空比。

避坑指南: 在调试AQ逻辑时,最容易混淆的是“向上”和“向下”对应的动作。一个简单的记忆方法是:在对称PWM中,一个完整的PWM脉冲(高电平)通常开始于向下计数匹配CMPA(CAD SET),结束于向上计数匹配CMPA(CAU CLEAR)。你可以用示波器触发在EPWMxA的上升沿,然后单步增减CMPA的值,观察波形变化,来直观理解这个逻辑。

3.3 死区(DB)子模块:功率电路的安全阀

死区模块接收来自AQ的原始信号(EPWMxA和EPWMxB),并对其边沿进行延迟,生成最终的输出信号EPWMxA和EPWMxB(通常命名为EPWMxA_DB和EPWMxB_DB)。

核心寄存器: DBCTL(控制模式)、DBRED(上升沿延迟)、DBFED(下降沿延迟)。

工作模式: DBCTL[MODE]决定了死区如何应用。最常用的是标准互补模式,即对其中一个信号(如AH)插入上升沿延迟,对另一个信号(如AL)插入下降沿延迟,确保在任何切换瞬间,两个信号都有一段同时为低(关断)的时间。

  • DBRED: 以TBCLK为单位的延迟计数,应用于选定信号的上升沿。
  • DBFED: 应用于选定信号的下降沿。

计算与配置: 假设TBCLK=100MHz (10ns),需要插入500ns的死区时间。DeadTime = 500ns / 10ns = 50 TBCLK cycles。 我们可以将50均分,或根据开关管特性调整。例如,设置DBRED=25, DBFED=25。

EPwm1Regs.DBRED = 25; EPwm1Regs.DBFED = 25; EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // 使能两路输出的死区 EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // 主动高互补模式(根据你的驱动电路极性调整) EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL; // EPWMxA作为源

一个关键检查点: 配置完死区后,一定要用示波器同时测量AQ模块输出的原始信号(如果引脚可复用)和经过DB模块后的最终信号,验证死区时间是否准确,以及极性是否正确。错误的死区配置是导致桥臂直通、烧毁功率管的常见原因。

3.4 故障保护(TZ)子模块:最后的防线

TZ模块是硬件安全回路,响应速度极快,不依赖CPU。其配置逻辑是“选择信号 -> 定义动作 -> 配置模式”。

  1. 选择故障源 (TZSEL): 选择哪些故障引脚(nTZ1, nTZ2, nTZ3)或数字比较事件(DCAEVT1/2, DCBEVT1/2)可以触发本ePWM模块的故障响应。
  2. 定义动作 (TZCTL): 当故障发生时,强制EPWMxA和EPWMxB输出到什么状态(高、低、高阻)。高阻状态常用于驱动外部栅极驱动芯片,可以快速关断功率管
  3. 配置响应模式 (TZCTL)
    • 单次触发 (One-Shot): 故障发生后,输出被强制到安全状态,直到软件通过写TZCLR寄存器清除故障标志(TZFLG)后,PWM输出才能恢复。适用于需要人工干预的严重故障。
    • 周期循环 (Cycle-By-Cycle): 故障发生后,输出被强制到安全状态,但仅持续当前PWM周期。下一个PWM周期开始时,如果故障信号已解除,输出自动恢复正常;如果故障仍存在,则再次强制。适用于过流保护等需要自动恢复的场景。

配置示例: 将nTZ1引脚配置为周期循环过流保护,触发时强制两路输出为高阻。

EALLOW; // 需要EALLOW保护 EPwm1Regs.TZSEL.bit.OSHT1 = 1; // 使能nTZ1作为单次触发源(这里用OSHT, CBC用CBC1) // 更常用CBC: EPwm1Regs.TZSEL.bit.CBC1 = 1; EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_HI_Z; // TZ事件时,EPWMxA强制高阻 EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_HI_Z; // EPWMxB强制高阻 EPwm1Regs.TZCTL.bit.CBCPULSE = TZ_CBC_ONCE; // 配置为CBC模式 // 对于OSHT模式,还需要配置TZEINT来使能中断,在中断中清除标志 EDIS;

重要安全实践: 故障引脚的硬件连接必须可靠,通常需要加上拉/下拉电阻,并确保故障信号在异常时能有效触发。在软件中,初始化阶段必须配置好TZ模块,并且不要轻易在运行中禁用或修改它。对于周期循环保护,确保你的故障清除逻辑(通常是ADC采样比较)足够快,能在下一个PWM周期开始前解除故障,否则输出会持续被钳位。

4. 高级功能与协同工作实战

掌握了基本子模块后,我们可以组合它们实现更复杂的功能。

4.1 利用事件触发(ET)实现精准ADC采样

在电机控制中,我们常常需要在PWM周期的特定时刻(如中点)进行电流采样,以消除开关噪声。ET模块完美胜任。

  1. 选择触发事件: 在ETSEL寄存器中,选择触发ADC启动转换的事件。例如,ETSEL[SOCAEN] = 1使能EPWMxSOCA信号,并选择ETSEL[SOCASEL] = ET_CTR_U_CMPA,即在向上计数匹配CMPA时触发。
  2. 设置触发分频: ETPS寄存器可以设置每第N次事件才触发一次SOC。例如,ETPS[SOCAPRD] = ET_1ST,表示每次事件都触发。
  3. 连接ADC: 在CPU或DMA中,将EPWMxSOCA信号映射到指定的ADC序列启动源。

这样,每次PWM波形的中点(假设CMPA设置在周期中点),硬件都会自动触发一次ADC转换,实现了与PWM严格同步的采样,精度远高于软件定时触发。

4.2 数字比较(DC)模块:灵活的故障与同步生成器

DC模块是ePWM的高级功能,它允许你将外部数字信号(DCAH/DCAL, DCBH/DCBL)与内部事件(如CTR=PRD)进行逻辑比较,产生事件(DCAEVT1/2, DCBEVT1/2)。这个事件可以送给TZ模块作为故障源,也可以送给TB模块作为同步源。

一个典型应用: 实现逐周期电流斩波保护。

  1. 硬件连接: 将电流采样信号经过比较器后,接到DCAH引脚。
  2. DC模块配置: 配置DCACTL,设置当DCAH为高时,在特定的滤波条件后,产生DCAEVT1事件。
  3. TZ模块配置: 在TZSEL寄存器中,使能DCAEVT1作为周期循环(CBC)故障源。
  4. 结果: 一旦电流超过比较器阈值,DCAH变高,DC模块几乎立即产生故障事件,TZ模块强制PWM输出为安全状态(如高阻),关断电流。整个过程由硬件完成,响应延迟仅在几十纳秒量级,比任何软件中断保护都要快得多。

4.3 多模块同步与相移:构建三相系统

回到最初的三相逆变器例子。假设我们需要EPWM1/2/3产生三相对称的PWM,相位互差120度。

  1. 时钟同步: 按照3.1.2节的描述,配置EPWM1为同步主模块(SYNCOSEL设为CTR=ZERO),EPWM2和EPWM3的SYNCI分别连接前一级的SYNCO。
  2. 相位设置: 三个模块都设置为上下计数模式,且TBPRD相同。计算相位差计数值PhaseOffset = (DesiredPhaseShift / 360) * 2 * TBPRD
    • EPWM1: TBPHS = 0 (主模块)
    • EPWM2: TBPHS = PhaseOffset (例如 4000)
    • EPWM3: TBPHS = 2 * PhaseOffset (例如 8000, 或 -PhaseOffset,取决于相序)
  3. 使能相位加载: 在EPWM2和EPWM3中,设置TBCTL[PHSEN]=1。这样,当它们收到同步脉冲时,会将TBCTR加载为TBPHS的值,从而实现固定的相位差。
  4. 全局时钟启动: 按照手册流程,先配置所有模块,最后将TBCLKSYNC置1,让所有ePWM模块的时基计数器在同一时刻开始运行。

调试技巧: 在验证同步和相位时,可以暂时将各个ePWM模块的同步输出信号(EPWMxSYNCO)映射到普通GPIO引脚上输出,用逻辑分析仪或示波器观察同步脉冲的时序,确保链路的正确性。同时,观察各模块的CTR=ZERO事件(可以通过ET模块触发一个IO翻转),检查它们的相位关系是否符合预期。

5. 常见问题排查与调试心得实录

即使理解了所有原理,实际调试中还是会遇到各种问题。下面是我总结的一些典型问题及排查思路。

5.1 问题排查速查表

现象可能原因排查步骤与解决方法
无PWM输出1. ePWM模块时钟未使能。
2. GPIO复用未配置到ePWM功能。
3. TZ模块强制输出为高阻且故障未清除。
4. 输出动作(AQCTL)全部配置为“无动作”。
1. 检查系统控制模块中对应ePWM的外设时钟使能位。
2. 检查GPIO MUX寄存器,确认引脚已配置为ePWM功能。
3. 检查TZFLG寄存器是否有故障标志,并检查TZ引脚电平。清除标志或解除故障。
4. 检查AQCTLA/B寄存器,确保至少有一个事件(如CAU/CAD)配置了SET或CLEAR动作。
PWM频率不对1. TBPRD计算错误或配置错误。
2. 时基时钟(TBCLK)预分频器(HSPCLKDIV/CLKDIV)配置错误。
3. 计数模式(CTRMODE)选择错误(上/下 vs 上下)。
1. 重新计算TBPRD,并用示波器测量周期验证。公式:Fpwm = 1 / ( (TBPRD+1)*Ttbclk )(Up/Down) 或Fpwm = 1 / ( 2*TBPRD*Ttbclk )(Up-Down)。
2. 核对TBCTL[HSPCLKDIV]和[CLKDIV]位域,确认TBCLK频率符合预期。
3. 确认应用需求是对称PWM还是非对称PWM,并检查CTRMODE设置。
占空比不受控或异常1. CMPA/CMPB影子寄存器未正确加载。
2. 在错误的时刻(如半个周期)更新了CMP影子寄存器。
3. AQCTL中向上/向下计数的动作配置反了。
4. CMPA值大于TBPRD(在上下计数模式中,这会导致该事件在整个周期内都不发生)。
1. 检查CMPCTL[LOADAMODE/LOADBMODE],确保在正确的时刻(如CTR=ZERO)加载。调试时可先禁用影子模式(SHDWAMODE=1),直接写活动寄存器测试。
2. 确保在PWM周期边界(如CTR=ZERO中断里)更新CMP影子寄存器。
3. 参考3.2.2节的配置逻辑,用示波器观察,单步修改CMPA值,验证动作逻辑。
4. 确保软件限制CMPA/B的值在0到TBPRD之间。
死区时间无效或不对1. DB子模块未使能(DBCTL[OUT_MODE])。
2. 输入模式(DBCTL[IN_MODE])选择错误,未正确选择源信号。
3. DBRED/DBFED寄存器值为0。
4. 极性选择(DBCTL[POLSEL])错误,导致逻辑反相。
1. 确认DBCTL[OUT_MODE]不为0(禁用)。
2. 确认IN_MODE选择了正确的源(通常是DBA来自EPWMxA)。
3. 计算并设置正确的死区计数值。
4. 用示波器观察DB模块输入(若可复用)和输出信号,根据驱动电路要求的有效电平调整POLSEL。
多路PWM不同步1. 同步链未正确连接或配置。
2. 从模块的相位加载(PHSEN)未使能。
3. TBCLKSYNC未正确使用,各模块时钟启动时刻不一致。
4. 各模块的TBPRD不一致。
1. 检查主模块SYNCOSEL配置,以及从模块的同步输入源配置。
2. 检查从模块的TBCTL[PHSEN]是否置1,TBPHS是否设置正确。
3. 严格按照手册流程:停时钟(TBCLKSYNC=0) -> 配置所有模块 -> 启时钟(TBCLKSYNC=1)。
4. 确保所有需要同步的模块TBPRD值相同。
故障保护不动作1. TZ子模块未使能对应故障源(TZSEL)。
2. TZ引脚硬件连接问题(如上拉/下拉)。
3. 输出动作(TZCTL)配置为“忽略”。
4. 对于数字比较故障,DC模块配置错误,未产生事件。
1. 仔细检查TZSEL寄存器,确保你使用的故障源(引脚或DC事件)已被使能。
2. 用万用表或示波器检查故障引脚电平,在故障条件下是否为有效电平(低有效或高有效)。
3. 检查TZCTL[TZA/TZB]是否配置为FORCE_HIGH/LOW/HIZ。
4. 检查DCACTL/DCBCTL等寄存器,确认滤波、逻辑条件配置正确。可以通过强制拉高/低DCAH引脚测试。

5.2 调试心得与高级技巧

  1. 善用仿真器与CCS的寄存器视图: TI的Code Composer Studio (CCS) 寄存器视图是动态的。在调试时,让代码运行起来,然后暂停,查看各个ePWM寄存器的值,特别是TBCTR、CMPA/B活动寄存器的值,以及TZFLG、ETFLG等标志位。这比单看代码直观得多。
  2. 波形生成的“分步调试法”: 如果复杂的PWM波形出不来,不要一次性配置所有子模块。按这个顺序来:TB -> CC+AQ -> DB -> TZ/ET
    • 第一步:只配置TB,让计数器跑起来,用ET模块在CTR=PRD或ZERO时触发一个IO翻转,用示波器看这个翻转信号的频率,确认时基正确。
    • 第二步:加上CC和AQ,配置简单的非互补PWM,先让一个引脚出波,确认占空比可控。
    • 第三步:加上AQ的互补逻辑和DB,观察死区。
    • 第四步:最后加上TZ保护功能。这样能快速定位问题所在子模块。
  3. 影子寄存器的“双缓冲”思维: 一定要建立“影子寄存器是后台,活动寄存器是前台”的概念。在需要频繁更新PWM参数(如电机控制中的电压矢量)的应用中,永远只在特定的同步点(如CTR=ZERO中断)更新影子寄存器。同时,为了避免写入冲突,可以在更新前检查CMPCTL[SHDWAFULL]位(如果支持),或者通过软件标志确保一个周期内只更新一次。
  4. 数字比较(DC)滤波的妙用: DC模块的DCFCTL寄存器可以配置滤波窗口和偏移。这对于消除比较器输出的毛刺噪声非常有用。例如,设置一个合适的滤波窗口,只有当故障信号持续超过N个TBCLK周期才被确认,可以避免噪声误触发保护。这在电流采样信号质量不佳的场合是必备的。
  5. 利用ET中断进行软件补偿: 虽然ePWM是硬件模块,但有些复杂逻辑仍需软件。例如,可以在CTR=PRD中断中,计算下一个PWM周期需要的CMPA/B值,并写入影子寄存器。同时,在这个中断里可以读取ADC结果(由ET在周期中点触发转换),完成整个控制环的计算。确保中断服务程序执行时间远小于PWM周期,否则会影响实时性。

ePWM模块的强大之处在于其高度可配置性和可靠性。最初的学习曲线可能比较陡峭,但一旦你掌握了这套寄存器映射和子模块协同工作的思维模型,就能游刃有余地设计出满足各种复杂需求的PWM波形,并构建出坚固的硬件保护网络。记住,多动手实践,用示波器验证每一个假设,是掌握ePWM的最佳途径。