1. 项目概述与ePWM核心价值在嵌入式系统尤其是电机控制、数字电源和逆变器这类对时序和功率精度要求极高的领域脉冲宽度调制PWM技术是绝对的基石。我们常说的PWM本质上是利用数字信号的通断时间来等效模拟电平通过调节占空比来控制平均电压或电流。然而当项目从简单的LED调光升级到驱动一个三相无刷电机或者构建一个多相交错的DC-DC变换器时简单的定时器PWM输出就捉襟见肘了。你需要的不只是单个PWM通道而是一个能精确同步、相位可调、死区可控、事件触发灵活的完整波形生成系统。这就是增强型PWMePWM模块大显身手的地方。我接触过不少从标准PWM转向ePWM的工程师初期往往会被其众多的子模块和寄存器搞得头晕——时间基准TB、计数器比较CC、动作限定器AQ、死区DB、事件触发ET等等。但一旦理清其核心逻辑你会发现它是一套设计极其精妙的“乐高积木”让你能像搭积木一样构建出几乎任何你能想到的复杂PWM波形。今天我就结合自己调试电机驱动和数字电源的实际经验深入拆解ePWM最核心的三个部分时间基准子模块TB、计数器比较子模块CC和动作限定器子模块AQ。理解这三者的协同工作是玩转ePWM的关键。无论你是正在评估TI C2000系列芯片还是已经上手但对其内部机制感到模糊这篇文章都将带你从“知道怎么配寄存器”深入到“明白为什么这么配”从而在复杂系统中游刃有余。2. 时间基准TB子模块一切节奏的起源如果把整个ePWM模块比作一个交响乐团那么时间基准Time-Base, TB子模块就是乐团的指挥。它决定了整个PWM波形的“节拍”——频率、相位和计数模式。所有其他子模块CC, AQ等的动作都严格遵循TB子模块提供的“时间轴”来执行。2.1 核心计数器与工作模式TB子模块的核心是一个16位的向上/向下计数器TBCTR。它的行为模式由TBCTL[CTRMODE]位域控制主要有四种向上计数模式Asymmetrical Up计数器从0开始递增到周期值TBPRD然后归零重新开始。这种模式生成的是非对称PWM波形其周期为(TBPRD 1) * T_{TBCLK}。这是最基础的模式常用于简单的单边调制。向下计数模式Asymmetrical Down计数器从TBPRD开始递减到0然后重新加载TBPRD。同样生成非对称波形周期计算同上。在某些特定调制策略中会用到。向上-向下计数模式Symmetrical Up-Down计数器从0开始递增到TBPRD然后立即递减回0如此循环。这是生成对称中心对齐PWM波形的关键其周期为2 * TBPRD * T_{TBCLK}。在电机控制和全桥变换器中对称PWM能显著减少谐波是更常用的模式。冻结模式Frozen计数器停止在当前值用于调试或紧急停止。选择哪种模式这完全取决于你的应用。驱动一个H桥的半桥通常使用向上-向下模式来生成对称PWM以减少电磁干扰EMI。而如果你只是做一个简单的降压转换器Buck向上计数模式可能就足够了。在我的一个伺服电机项目中为了精确控制电流环就采用了向上-向下模式因为其波形的中心对称性使得电流采样的时刻更加明确和一致。2.2 同步机制多模块协同的基石单个ePWM模块能力有限真正的威力在于多个ePWM模块的协同工作。例如一个三相逆变器需要6个PWM通道每相上下桥臂且它们之间必须有严格的相位关系。TB子模块的同步输入EPWMxSYNCI和同步输出EPWMxSYNCO功能正是为此而生。同步的本质是让一个模块从模块的计数器TBCTR在特定时刻被强制加载为主模块设定的相位值TBPHS。这个“特定时刻”就是同步脉冲到来的时刻。配置TBCTL[PHSEN] 1即可启用此功能。这里有三个关键的同步源外部同步脉冲EPWMxSYNCI通常来自上一个ePWM模块的EPWMxSYNCO输出形成同步链。例如ePWM1作为主模块其EPWM1SYNCO连接到 ePWM2 的EPWM2SYNCI以此类推。软件强制同步通过写TBCTL[SWFSYNC] 1来产生一个同步脉冲。这在初始化或动态调整相位时非常有用。数字比较事件同步高级功能当某些外部或内部数字比较条件满足时如过流保护信号可以触发同步实现基于事件的全局相位重置。相位控制是同步的精髓。通过为每个从模块设置不同的TBPHS值你可以让它们的PWM波形相对于主模块产生固定的相位差。比如在交错并联的Boost电路中两个通道的PWM需要相差180度相位以减小输入电流纹波。假设主模块ePWM1的TBPRD1000向上-向下模式一个完整周期计数2000次要让ePWM2滞后180度只需设置ePWM2.TBPHS 500。这样当同步脉冲到来ePWM2的计数器会从500开始计数其波形自然就滞后了半个周期。实操心得同步链的延迟手册中提到同步信号从主模块传到从模块有1 TBCLK或2 x VCLK3的延迟。这个延迟在超高开关频率例如几百kHz下必须考虑。如果你的多个通道要求绝对的同时性纳秒级可能需要使用全局时钟同步功能TBCLKSYNC位。正确的启用顺序是先停止所有时钟TBCLKSYNC0配置好各模块的预分频器和模式再同时启动TBCLKSYNC1。这样可以确保所有ePWM模块的TBCLK第一个上升沿严格对齐从根本上消除因模块使能时间不同步带来的微小相位差。2.3 时钟与周期配置TBCLK是TB子模块的计数时钟源由系统时钟SYSCLKOUT经过高速时钟预分频器HSPCLKDIV和时钟预分频器CLKDIV两级分频得到。TBPRD寄存器则决定了计数器的周期值。计算PWM频率的公式向上/向下计数模式PWM Frequency 1 / [(TBPRD 1) * T_{TBCLK}]向上-向下计数模式PWM Frequency 1 / [2 * TBPRD * T_{TBCLK}]其中T_{TBCLK} 1 / (SYSCLKOUT / (HSPCLKDIV * CLKDIV))。配置步骤示例假设系统时钟SYSCLKOUT 100 MHz需要生成一个20 kHz的对称PWM。选择向上-向下计数模式。设定分频。为了获得较高的计数器分辨率通常尽量让TBPRD大一些。设HSPCLKDIV和CLKDIV均为1则TBCLK 100 MHzT_{TBCLK} 10 ns。计算TBPRDTBPRD 1 / (2 * PWM Frequency * T_{TBCLK}) 1 / (2 * 20k * 10e-9) 2500。验证实际频率 1 / (2 * 2500 * 10e-9) 20 kHz。注意事项影子寄存器TBPRD寄存器也有影子寄存器由TBCTL[PRDLD]控制。在波形运行中更新TBPRD时强烈建议使用影子模式TBCTL[PRDLD] 0并选择在CTR0或CTRTBPRD时加载。这样可以避免在计数器运行中途更新周期值而导致当前周期波形畸变确保PWM频率切换平滑无毛刺。3. 计数器比较CC子模块定义关键时间点如果说TB子模块定义了时间的“标尺”那么计数器比较Counter-Compare, CC子模块就是在标尺上“刻下”关键的事件点。它的工作很简单但至关重要持续比较时间基准计数器TBCTR的值与两个用户定义的比较寄存器CMPA和CMPB的值当相等时产生CTR CMPA和CTR CMPB这两个事件。3.1 比较事件与影子寄存器CMPA和CMPB是决定PWM占空比或脉冲位置的核心寄存器。在向上计数模式下CMPA的值直接决定了输出高电平或低电平的时长。在向上-向下计数模式下CMPA和CMPB可以分别控制上升沿和下降沿的位置从而实现对称调制。CC子模块最精妙的设计之一是影子寄存器机制。CMPA和CMPB各有一个对应的影子寄存器。在影子模式下CMPCTL[SHDWAMODE] 0你软件写入的值是进入影子寄存器而硬件真正用于比较的是“活动寄存器”。影子寄存器向活动寄存器加载的时机由CMPCTL[LOADAMODE]和[LOADBMODE]控制通常选择在CTR0或CTRPRD的时刻。为什么需要影子寄存器想象一下你在电机运行中需要动态调整PWM占空比比如响应速度指令。如果没有影子寄存器你直接在任意时刻写CMPA可能会发生这种情况你写入新值时计数器刚好跨过这个值导致本次周期比较事件丢失或产生一个极窄的脉冲glitch这可能会引起功率管误开通造成短路影子寄存器确保了更新只发生在周期或零点的安全边界保证了一个完整的PWM周期内比较值保持不变波形稳定。3.2 不同计数模式下的比较行为理解比较事件在不同计数模式下的触发次数对于正确配置动作限定器至关重要。向上计数模式TBCTR从0到TBPRD单向变化。因此CTRCMPA和CTRCMPB事件每个PWM周期只发生一次。向下计数模式与向上模式类似每个周期每个比较事件也只发生一次。向上-向下计数模式TBCTR先上后下。如果比较值CMPx在0和TBPRD之间不包括0和TBPRD那么CTRCMPx事件每个PWM周期会发生两次一次在递增过程中一次在递减过程中。如果CMPx等于0或TBPRD则只会在计数器等于该值时触发一次。这个特性是生成对称PWM的基础。例如要生成一个中心对称的PWM我们通常配置在CTRCMPA且计数器递增时CAU事件设置输出高在CTRCMPA且计数器递减时CAD事件清除输出低。这样高电平脉冲就以周期点为中心对称分布。3.3 比较值大于周期值的特殊情况手册中特别提到了一个容易忽略的边界情况当CMPA或CMPB的值大于TBPRD时比较事件的行为会发生变化。向上计数模式如果CMPx TBPRD则CTRCMPx事件永远不会发生因为计数器最大只到TBPRD。向下计数模式如果CMPx TBPRD则CTRCMPx事件会在CTRPRD即计数器起始点时发生。向上-向下计数模式如果CMPx TBPRD则递增过程中的比较事件会在CTRPRD时发生递减过程中的比较事件也会在CTRPRD时发生实际上合为一次。这个特性可以被巧妙利用。例如在向上计数模式下如果你想实现0%-100%的占空比范围一种配置方法是在CTR0时置高输出在CTRCMPA时拉低输出。那么当CMPA0时一上来就拉低占空比0%当CMPATBPRD时在周期点拉低占空比接近100%当CMPATBPRD1大于周期时比较事件永不发生输出始终为高占空比100%。这就实现了全范围调节。避坑指南影子寄存器加载时机与脉冲丢失在向上-向下模式生成对称PWM时如果你选择在CTR0的时刻加载影子寄存器到活动寄存器那么你的CMPA/CMPB值必须大于等于1。为什么假设TBPRD1000你在CTR0时加载了CMPA0。那么在本周期活动寄存器的CMPA就是0。在计数器从0递增的瞬间TBCTR就等于CMPA会立即触发一个CAU事件。但这个事件可能过于短暂或者与CTR0的事件在优先级上冲突导致预期的动作比如置高被忽略造成一个PWM周期内没有脉冲输出。同理如果在CTRPRD时加载则CMPA/CMPB值应小于等于 TBPRD-1。这个小细节是很多人在调试时发现占空比无法调到0%或100%的根源。4. 动作限定器AQ子模块事件的执行者时间基准提供了节拍计数器比较定义了音符出现的时刻而动作限定器Action-Qualifier, AQ子模块就是乐手负责在正确的时刻执行正确的动作——控制输出引脚EPWMxA和EPWMxB的电平。它是将时间事件转化为实际波形的最终环节。4.1 事件、动作与配置AQ子模块的输入是来自TB和CC子模块的四种事件CTR PRD: 计数器等于周期值。CTR ZERO: 计数器等于零。CTR CMPA: 计数器等于比较值A。CTR CMPB: 计数器等于比较值B。对于每个输出通道EPWMxA和EPWMxBAQ子模块都可以独立配置当上述某个事件发生时要执行何种“动作”置高Set High将输出引脚驱动为高电平。拉低Clear Low将输出引脚驱动为低电平。翻转Toggle输出引脚当前电平取反。无操作Do Nothing保持引脚当前电平不变。注意即使配置为无操作该事件仍然可以触发中断或ADC启动转换。配置是通过AQCTLA和AQCTLB寄存器完成的。这些寄存器的位域非常直观例如AQCTLA.CAU AQ_SET就表示当CTRCMPA事件发生且计数器处于递增Up状态时对EPWMxA执行置高动作。4.2 事件优先级一个关键问题是如果多个事件在同一时刻同一个TBCLK边沿发生听谁的AQ子模块有严格的硬件优先级。基本原则是软件强制事件优先级最高然后是发生在“当前计数方向”上的比较事件最后是周期/零点事件。以最复杂的向上-向下计数模式为例其优先级如下表所示优先级 (1最高)TBCTR 递增时 (0 - PRD)TBCTR 递减时 (PRD - 0)1软件强制事件软件强制事件2CTR CMPB(递增)CTR CMPB(递减)3CTR CMPA(递增)CTR CMPA(递减)4CTR ZEROCTR PRD5CTR CMPB(递减)CTR CMPB(递增)6CTR CMPA(递减)CTR CMPA(递增)为什么需要优先级考虑一个常见场景在向上-向下模式中如果你设置CMPA TBPRD那么在计数器到达峰值TBPRD时CTRCMPA递减事件因为接下来要递减和CTRPRD周期事件会同时发生。根据上表此时CTRPRD的优先级高于CTRCMPA递减。如果你同时配置了这两个事件对同一个引脚产生动作那么只有高优先级的CTRPRD动作会生效。理解优先级可以避免波形出现非预期的行为。4.3 典型波形生成配置解析手册中给出了多个经典配置的代码示例这里我挑两个最常用的结合我的经验深入解读配置一向上计数非对称PWM独立调制两路输出图21-20这是最基础的配置常用于两个独立的开关管控制。// 初始化代码片段 EPwm1Regs.TBCTL.bit.CTRMODE TB_COUNT_UP; // 向上计数模式 EPwm1Regs.AQCTLA.bit.ZRO AQ_SET; // CTR0 时EPWM1A 置高 EPwm1Regs.AQCTLA.bit.CAU AQ_CLEAR; // CTRCMPA(递增)时EPWM1A 拉低 EPwm1Regs.AQCTLB.bit.ZRO AQ_SET; // CTR0 时EPWM1B 置高 EPwm1Regs.AQCTLB.bit.CBU AQ_CLEAR; // CTRCMPB(递增)时EPWM1B 拉低波形分析两路输出都在期开始时CTR0变高然后分别在CMPA和CMPB时刻变低。CMPA和CMPB独立控制两路输出的占空比。占空比 CMPx / (TBPRD 1)。实操要点CMPA和CMPB必须在[0, TBPRD]范围内。如果CMPx 0则CAU/CBU事件与ZRO事件同时发生根据优先级ZRO最低CAU/CBU的清除动作会生效导致输出始终为低0%占空比。如果CMPx TBPRD则清除动作发生在周期末尾占空比接近100%。配置二向上-向下计数对称PWM互补输出带死区图21-24这是全桥或半桥驱动的标准配置生成两路互补的对称PWM并且通过CMPA和CMPB的差值天然形成死区。// 初始化代码片段 EPwm1Regs.TBCTL.bit.CTRMODE TB_COUNT_UPDOWN; // 向上-向下计数模式 EPwm1Regs.AQCTLA.bit.CAU AQ_SET; // CTRCMPA(递增)时EPWM1A 置高 EPwm1Regs.AQCTLA.bit.CAD AQ_CLEAR; // CTRCMPA(递减)时EPWM1A 拉低 EPwm1Regs.AQCTLB.bit.CBU AQ_CLEAR; // CTRCMPB(递增)时EPWM1B 拉低 EPwm1Regs.AQCTLB.bit.CBD AQ_SET; // CTRCMPB(递减)时EPWM1B 置高波形分析EPWM1A在计数器递增到CMPA时变高递减到CMPA时变低形成一个以周期点为中心的高电平脉冲。EPWM1B则相反在递增到CMPB时变低递减到CMPB时变高。如果CMPB CMPA则EPWM1A的高电平区间被EPWM1B的低电平区间所包围两者之间就有了(CMPB - CMPA) * T_{TBCLK}的死区时间防止上下管直通。死区计算死区时间 (CMPB - CMPA) * T_{TBCLK}。通过分别调节CMPA和CMPB可以独立控制占空比和死区时间非常灵活。但请注意这种方式产生的死区会同时影响脉冲的前沿和后沿。对比专用死区模块ePWM还包含一个独立的死区DB子模块它可以提供更传统的、基于上升沿延迟和下降沿延迟的死区生成方式并且可以独立于占空比进行配置。对于大多数桥式驱动应用我更喜欢使用DB模块因为它将占空比调节通过CC模块和死区插入通过DB模块解耦逻辑更清晰不易出错。AQ模块生成互补波形的能力更适合用于不需要可变死区或者需要特殊脉冲位置控制的场景。经验之谈调试AQ模块的“三板斧”先静态后动态首先在初始化代码中固定TBPRD、CMPA、CMPB的值用示波器观察输出波形是否与预期一致。确认基础配置正确后再尝试在运行中动态修改比较值。善用软件强制AQSFRC寄存器可以软件强制输出高、低或翻转。在调试初期你可以通过强制输出特定的电平来快速验证GPIO引脚、驱动电路是否正常排除硬件问题。关注影子加载时机动态更新CMPA/CMPB时务必确认CMPCTL[LOADxMODE]的设置与你当前的计数模式匹配。在向上-向下模式下如果你在CTRZERO时加载而你的CMPA新值设为0就可能会遇到前面提到的脉冲丢失问题。一个稳健的做法是在运行中更新比较值时先写入影子寄存器然后通过检查CMPCTL[SHDWAFULL]或CMPCTL[SHDWBFULL]位来确认影子寄存器是否已满即新值已就绪或者简单地确保你的更新速度远慢于PWM周期。5. 从理论到实践一个完整的配置流程与调试案例理解了三大子模块的原理后我们来看一个完整的实战案例配置一个ePWM模块用于驱动一个三相逆变器中的其中一相上下桥臂互补对称PWM带死区。5.1 需求分析与配置规划目标生成一对互补的、中心对称的PWM波形EPWM1A和EPWM1B开关频率20kHz死区时间2us。系统时钟SYSCLKOUT 100 MHz。选用模式向上-向下计数模式生成对称PWM使用动作限定器AQ生成互补波形但死区通过专用的死区DB模块插入以获得更稳定独立的控制。计算参数TBCLK配置为简化且获得高分辨率设HSPCLKDIV1,CLKDIV1, 则TBCLK 100 MHz,T_{TBCLK} 10 ns。TBPRD计算TBPRD 1 / (2 * 20kHz * 10ns) 2500。死区时间换算死区时间T_{dead} 2 us 2000 ns。需要的死区计数器值DBRED DBFED T_{dead} / T_{TBCLK} 200假设使用对称上升/下降沿延迟模式。5.2 分步配置代码与注释以下是基于TI C2000系列芯片的典型驱动库代码风格// 步骤1: 配置时间基准 (TB) 子模块 EPwm1Regs.TBCTL.bit.CTRMODE TB_COUNT_UPDOWN; // 向上-向下计数模式 EPwm1Regs.TBCTL.bit.PHSEN TB_DISABLE; // 本例作为主模块禁用相位加载 EPwm1Regs.TBCTL.bit.PRDLD TB_SHADOW; // TBPRD使用影子寄存器 EPwm1Regs.TBCTL.bit.SYNCOSEL TB_CTR_ZERO; // 在CTR0时产生同步输出供其他模块同步 EPwm1Regs.TBCTL.bit.HSPCLKDIV TB_DIV1; // 高速时钟预分频 1 EPwm1Regs.TBCTL.bit.CLKDIV TB_DIV1; // 时钟预分频 1 EPwm1Regs.TBPHS.half.TBPHS 0; // 相位寄存器清零 EPwm1Regs.TBPRD 2500; // 设置周期值对应20kHz EPwm1Regs.TBCTR 0; // 计数器清零 // 步骤2: 配置计数器比较 (CC) 子模块 // 假设我们初始占空比为50%即高电平时间占半个周期。对于对称PWMCMPA值决定了脉冲宽度。 // 在向上-向下模式高电平时间 2 * (TBPRD - CMPA) * T_TBCLK? 不对。 // 更直观我们希望EPWM1A在计数到CMPA时置高计数到CMPA时拉低对称。 // 对于50%占空比高电平应覆盖整个周期的一半即CMPA应设置在TBPRD/2附近。 // 但注意AQ动作是在CAU和CAD事件。如果我们设置CAUSET, CADCLEAR。 // 那么高电平时间就是从CAU事件到CAD事件即 (TBPRD - CMPA) * 2 * T_TBCLK? 推导一下 // 计数器从0到TBPRD再到0。CAU发生在计数上升沿等于CMPA时CAD发生在计数下降沿等于CMPA时。 // 两点之间的计数值差为 (TBPRD - CMPA) (TBPRD - CMPA) 2*(TBPRD - CMPA)。 // 因此高电平时间 2*(TBPRD - CMPA) * T_TBCLK。 // 占空比 高电平时间 / 周期 [2*(TBPRD - CMPA) * T_TBCLK] / [2*TBPRD*T_TBCLK] (TBPRD - CMPA) / TBPRD。 // 所以CMPA TBPRD * (1 - DutyCycle)。 // 对于50%占空比CMPA 2500 * 0.5 1250。 EPwm1Regs.CMPA.half.CMPA 1250; // 初始50%占空比 // CMPB在本例中暂未用于占空比控制可设为任意值例如0或用于其他事件触发。 EPwm1Regs.CMPCTL.bit.SHDWAMODE CC_SHADOW; // CMPA使用影子寄存器 EPwm1Regs.CMPCTL.bit.SHDWBMODE CC_SHADOW; // CMPB使用影子寄存器 EPwm1Regs.CMPCTL.bit.LOADAMODE CC_CTR_ZERO; // 在CTR0时加载CMPA影子值 EPwm1Regs.CMPCTL.bit.LOADBMODE CC_CTR_ZERO; // 在CTR0时加载CMPB影子值 // 步骤3: 配置动作限定器 (AQ) 子模块生成互补波形 // EPWM1A: 递增过CMPA时置高递减过CMPA时拉低。 EPwm1Regs.AQCTLA.bit.CAU AQ_SET; EPwm1Regs.AQCTLA.bit.CAD AQ_CLEAR; // EPWM1B: 我们希望它与EPWM1A互补。 // 一种简单配置EPWM1B在递增过CMPA时拉低递减过CMPA时置高。 // 但这样没有死区。更常见的做法是AQ生成不带死区的互补信号然后交给DB模块插入死区。 // 我们先配置AQ生成完全互补无死区的信号 EPwm1Regs.AQCTLB.bit.CAU AQ_CLEAR; EPwm1Regs.AQCTLB.bit.CAD AQ_SET; // 此时EPWM1A和EPWM1B是瞬间互补的存在直通风险。 // 步骤4: 配置死区 (DB) 子模块插入死区 EPwm1Regs.DBCTL.bit.OUT_MODE DB_FULL_ENABLE; // 使能EPWM1A和EPWM1B的上升沿和下降沿延迟 EPwm1Regs.DBCTL.bit.POLSEL DB_ACTV_HIC; // 高电平互补模式。EPWM1A为参考信号EPWM1B为其反相。 EPwm1Regs.DBCTL.bit.IN_MODE DBA_ALL; // EPWM1A作为上升沿和下降沿延迟的源 EPwm1Regs.DBRED 200; // 上升沿延迟200个TBCLK 2us EPwm1Regs.DBFED 200; // 下降沿延迟200个TBCLK 2us // 经过DB模块后最终的EPWM1A和EPWM1B输出会自动插入2us的死区。 // EPWM1A的上升沿延迟2usEPWM1B的下降沿延迟2us相对于原始的、瞬间互补的信号。 // 步骤5: 配置事件触发 (ET) 和中断可选 // 例如我们可以在CTR0时触发ADC采样电流采样。 EPwm1Regs.ETSEL.bit.SOCAEN 1; // 使能ADC开始转换A组事件 EPwm1Regs.ETSEL.bit.SOCASEL ET_CTR_ZERO; // 选择CTR0作为触发源 EPwm1Regs.ETPS.bit.SOCAPRD ET_1ST; // 每个事件触发一次5.3 调试中常见问题与排查即使按照上述步骤配置在实际硬件调试中仍可能遇到问题。以下是我总结的常见问题排查清单现象可能原因排查步骤与解决方法完全没有PWM输出1. ePWM模块时钟未使能。2. GPIO复用功能未配置到ePWM。3.TBCLK分频过大或TBPRD为0。4. 输出被Trip-Zone强制拉高/低。1. 检查系统控制模块中对应ePWM的外设时钟使能位例如PCLKCR0寄存器。2. 检查GPIO MUX寄存器将对应引脚配置为ePWM功能。3. 用仿真器读取TBCTR寄存器看它是否在循环计数。检查TBCTL[CLKDIV]和HSPCLKDIV。4. 检查TZCTL寄存器确保Trip-Zone未强制动作或正确配置了错误处理方式。PWM频率不对1.TBPRD计算错误或写入错误。2.TBCLK分频配置错误。3. 计数模式选择错误向上 vs 向上-向下。1. 复核频率计算公式和系统时钟频率。2. 确认SYSCLKOUT频率检查TBCTL中的分频位。3. 确认TBCTL[CTRMODE]设置。用示波器测量周期向上模式周期(TBPRD1)*T_TBCLK向上-向下模式周期2*TBPRD*T_TBCLK。占空比无法调节或调节异常1.CMPA/CMPB影子寄存器未正确加载。2.CMPA/CMPB值超出有效范围如大于TBPRD。3. AQ事件配置错误例如CAU和CAD动作设反。4. 在错误的时间点更新了活动寄存器无影子模式或加载时机不对。1. 确认CMPCTL[LOADxMODE]设置并确保在CTR0或PRD时更新影子寄存器。运行时先写CMPA/CMPB影子寄存器等待一个PWM周期后再观察。2. 确保CMPA/CMPB值在[0, TBPRD]内对于对称PWM通常还要避开0和TBPRD。3. 对照手册波形图仔细检查AQCTLA和AQCTLB寄存器的每一位配置。4. 启用影子模式并确保在安全点CTR0/PRD加载。两路PWM互补但有重叠无死区1. 死区模块未使能或配置错误。2. AQ模块生成的原始信号就不是互补的。3. 死区时间值DBRED/DBFED设置过小或为0。1. 检查DBCTL[OUT_MODE]是否使能了死区生成。2. 暂时旁路死区模块DBCTL[OUT_MODE]0直接观察AQ输出的原始信号是否互补。3. 计算并确认DBRED/DBFED值对应的死区时间符合预期T_dead DBRED * T_TBCLK。同步功能不起作用1. 主模块的SYNCOUT未正确配置或输出。2. 从模块的SYNCI未使能相位加载PHSEN0。3. 同步链中时钟分频不一致导致计数器无法对齐。4. 同步脉冲在从模块计数器禁止时发出。1. 检查主模块TBCTL[SYNCOSEL]确保其能在特定事件如CTR0产生同步脉冲。2. 检查从模块TBCTL[PHSEN]是否置1并设置了正确的TBPHS。3. 确保同步链上所有ePWM模块的TBCLK分频设置HSPCLKDIV,CLKDIV完全一致。4. 确保在启动同步前所有模块的计数器已使能TBCLKSYNC1。一个真实的调试故事在一次电机驱动板调试中我发现其中一相PWM的占空比在高速时90%会突然跳动。示波器显示波形偶尔会缺失一个脉冲。排查了很久最终发现是中断服务程序ISR中更新CMPA的代码执行时间过长。虽然使用了影子寄存器但我的ISR可能在某个PWM周期内被多次触发导致影子寄存器在尚未被加载到活动寄存器之前就被再次写入发生了数据覆盖。解决方法是将占空比计算和寄存器更新放在后台循环中仅由ISR设置一个标志位或者使用ePWM自身的事件触发中断ET确保每个PWM周期只更新一次。这个坑让我深刻理解了“影子寄存器不是万能的”软件与硬件的协同时序至关重要。6. 进阶应用与性能优化思考掌握了基础配置后ePWM还有一些高级特性可以挖掘以提升系统性能。1. 利用数字比较DC和Trip-ZoneTZ进行高级保护ePWM的DC子模块可以监控外部引脚或内部信号如比较器输出并与CMPA/CMPB等内部事件进行逻辑组合产生特定事件。TZ子模块则可以在故障信号如过流、过压发生时强制PWM输出进入安全状态高阻、拉高或拉低。将两者结合可以实现逐周期电流限制。例如用ADC采样电流通过比较器产生一个数字信号连接到TZ输入。当电流超限TZ模块可以立即关闭PWM输出。同时DC模块可以监控这个故障信号并产生同步事件在故障清除后让所有ePWM模块重新同步启动确保多相之间的相位关系不乱。2. 高分辨率PWMHRPWM对于需要极高精度占空比控制的应用如LLC谐振变换器的频率调节标准ePWM的占空比分辨率受限于TBCLK周期。HRPWM技术通过一个微边沿定位MEP逻辑在TBCLK的粗调基础上实现了次周期的精细调节精度可达150ps级别。这需要特定的芯片支持如C2000的Delfino系列并配合特殊的HRMSTEP校准流程使用。启用HRPWM后CMPA寄存器的一部分位会用于MEP控制从而获得远超TBCLK频率限制的分辨率。3. 动态相位调整与载波移相在并联交错或级联系统中常常需要动态调整各相PWM之间的相位差。ePWM的同步和相位寄存器TBPHS为此提供了硬件支持。你可以在运行中通过软件修改从模块的TBPHS值并在下一个同步脉冲到来时生效实现相位的平滑迁移。这对于实现功率因数校正PFC的相位 shedding或多相VRM的负载均衡非常有用。4. 最小化中断延迟与CPU开销ePWM的事件触发ET子模块可以精确定时地触发ADC转换实现无延迟的采样。将电流采样点配置在PWM周期的中点对于对称PWM或开关管关断时刻可以避开开关噪声获得最准确的采样值。同时应尽量利用ePWM的硬件自动动作减少CPU干预。例如通过配置AQ和CC让PWM波形完全由硬件产生CPU只需在后台更新CMPA/CMPB即可改变占空比。将ADC结束中断与PWM周期中断错开可以平衡CPU负载避免在同一个时间点处理过多任务。ePWM模块的深度和灵活性远不止于此但时间基准、计数器比较和动作限定器这三个核心子模块是其灵魂。从理解计数器如何跳动到比较器如何标记时刻再到动作器如何执行指令这条链路贯穿了所有ePWM应用。我个人的体会是初期多花时间研究手册里的波形图并用开发板的GPIO输出这些波形用示波器亲自观察CTRPRD、CTRCMPA这些事件对应的边沿比读十遍代码都管用。当你脑中能清晰地浮现出计数器在波形图上滑动并在各个比较点触发动作的画面时你就真正驾驭了ePWM。