4. ePWM模块深度解析:时基单元、计数器比较、动作限定器、死区插入、斩波与故障捕获

各位工程师朋友,欢迎来到ePWM模块的深度解析。说实话,在C2000系列里,ePWM是最核心也最灵活的外设之一。我做了这么多年电机控制,可以说90%的控制精度都取决于你对ePWM的理解深度。这一章,咱们就把ePWM的六个关键模块掰开揉碎了讲清楚。

核心认知:ePWM不是简单的PWM发生器,而是一个完整的波形合成引擎。它由时基单元、计数器比较、动作限定器、死区插入、斩波和故障捕获六个子模块组成,每个模块都可以独立配置,协同工作。

ePWM模块内部结构框架图 ePWM模块内部结构框架图 时基单元 TBPRD, TBCLK, 计数模式 计数器比较 CMPA, CMPB, 影子寄存器 动作限定器 AQCTLA, AQCTLB 死区插入 DBCTL, DBRED, DBFED 斩波 PCCTL, 高频载波 故障捕获 TZCTL, 强制高/低/高阻 ePWMxA/B 💡 数据流说明: 时基单元产生计数时钟 → 计数器比较模块产生比较事件 → 动作限定器根据事件决定输出电平 → 死区插入模块插入上升/下降沿延时 → 斩波模块叠加高频载波(可选) → 故障捕获模块在异常时强制输出安全电平 → 最终输出ePWMxA/ePWMxB

4.1 时基单元:PWM的脉搏

时基单元是整个ePWM模块的心脏。它决定了PWM的频率和计数模式。说白了,就是给PWM一个时间基准。

我个人习惯把时基单元比作一个钟摆。TBPRD(周期寄存器)决定了钟摆摆动的幅度,TBCLK(时基时钟)决定了摆动的速度。两者配合,就得到了我们想要的PWM频率。

经验之谈:我在做伺服驱动器时,发现很多人把TBPRD设得太大,导致PWM频率过低,电机噪音大得吓人。一般电机控制建议PWM频率在8kHz-20kHz之间,TBPRD的计算公式很简单:TBPRD = SYSCLKOUT / (2 × TBCLK分频系数 × PWM频率)。

时基单元支持三种计数模式:

  • 递增计数(Up):计数器从0递增到TBPRD,然后复位到0。适合不对称PWM。
  • 递减计数(Down):计数器从TBPRD递减到0,然后复位到TBPRD。用得较少。
  • 递增递减计数(Up-Down):计数器从0递增到TBPRD,再递减到0。这是电机控制最常用的模式,因为可以产生对称PWM,谐波小。

嗯,这里要注意:递增递减模式下,PWM频率是递增模式的一半。因为一个完整周期包含了上升和下降两个阶段。

4.2 计数器比较:精准的时刻触发

计数器比较模块负责在特定计数值到达时产生事件。CMPA和CMPB是两个比较寄存器,它们与当前计数值实时比较。

你想想看,如果没有比较模块,我们只能控制PWM的周期,却无法控制占空比。比较模块就是用来干这个的——当计数值等于CMPA时,触发一个事件;等于CMPB时,触发另一个事件。

影子寄存器机制:CMPA和CMPB都有影子寄存器。什么意思呢?就是你在运行时写入的新值不会立即生效,而是等到特定同步事件(如TBCTR=0或TBCTR=TBPRD)时才加载到活动寄存器。这样做的好处是避免PWM周期中途突然改变占空比,导致波形畸变。

我曾经在调试一个BLDC驱动时,因为没配置影子寄存器加载时机,导致PWM波形在周期中间出现毛刺,电机一抖一抖的。后来把影子寄存器配置为TBCTR=0时加载,问题立刻解决。

4.3 动作限定器:决定输出电平

动作限定器(AQ)是ePWM的决策中心。它根据比较事件(CMPA、CMPB、TBCTR=0、TBCTR=PRD等)来决定ePWMxA和ePWMxB的输出电平。

动作限定器支持以下动作:

动作 描述 典型应用
Set(置高) 事件发生时输出高电平 递增模式下的占空比起始
Clear(置低) 事件发生时输出低电平 递增模式下的占空比结束
Toggle(翻转) 事件发生时输出电平翻转 对称PWM生成
Do Nothing(无动作) 事件发生时输出不变 用于屏蔽某些事件

举个例子,在递增计数模式下,要产生一个占空比为50%的PWM,可以这样配置:TBCTR=0时Set,TBCTR=CMPA时Clear。这样从0到CMPA输出高,CMPA到TBPRD输出低。

避坑指南:我曾经在配置动作限定器时,不小心把Set和Clear的事件搞反了,结果PWM波形完全反相。电机控制中,反相意味着电流方向错误,轻则电机反转,重则烧毁MOSFET。所以配置完一定要用示波器确认波形极性。

4.4 死区插入:保护你的功率管

死区插入是电机控制中绝对不能省略的环节。为什么?因为功率管(MOSFET/IGBT)的开关速度不是无限的。当一个管关断、另一个管开通时,如果没有任何延时,就会出现上下管同时导通——这就是可怕的直通(Shoot-through),瞬间烧毁功率管。

死区插入模块在ePWMxA和ePWMxB之间插入一个延时,确保一个管完全关断后,另一个管才开通。

死区配置参数:

  • DBRED(上升沿延时):ePWMxA上升沿相对于原始信号的延时。
  • DBFED(下降沿延时):ePWMxB下降沿相对于原始信号的延时。
  • DBCTL(死区控制寄存器):配置死区模式,如独立模式、上升沿/下降沿模式等。

我的建议:死区时间不是越大越好。死区太大,会导致波形失真,电流谐波增加,电机效率下降。一般MOSFET的死区时间在100ns-500ns,IGBT在1μs-3μs。具体值要看功率管的datasheet,留出20%-30%的余量。

4.5 斩波:高频载波调制

斩波模块(PC)是一个可选功能,它在PWM信号上叠加一个高频载波。说白了,就是把PWM信号再切碎成更小的脉冲。

为什么要这么做?主要是为了驱动脉冲变压器。在一些隔离驱动方案中,PWM信号需要通过变压器传输,而变压器无法传递直流分量。斩波模块把PWM信号变成高频脉冲串,变压器就能正常工作了。

斩波模块的配置参数:

  • 斩波频率:载波频率,通常远高于PWM频率(如MHz级别)。
  • 斩波占空比:载波脉冲的占空比,一般设为50%。
  • 第一个脉冲宽度:第一个脉冲可以设置得更宽,用于快速建立变压器磁通。

说实话,斩波模块在普通电机控制中用得不多。我只有在做高压IGBT驱动时用过一次,当时变压器驱动一直不稳定,加上斩波后信号传输就可靠了。

4.6 故障捕获:安全第一

故障捕获模块(TZ)是ePWM的安全卫士。当检测到外部故障信号(如过流、过压、过热)时,它能立即强制ePWM输出到安全状态,而不需要CPU干预。

故障捕获支持以下动作:

动作 描述 应用场景
强制高 输出强制为高电平 某些制动场景
强制低 输出强制为低电平 关断功率管
强制高阻 输出为高阻态 电机自由停机
无动作 输出不变 仅记录故障

重要提醒:故障捕获的响应时间是硬件级别的,通常在几十纳秒内。我曾经见过一个案例,工程师只靠软件检测过流,结果CPU还没反应过来,MOSFET已经烧了。所以,过流保护一定要用硬件故障捕获,不要依赖软件。

故障捕获的配置要点:

  • 触发源选择:选择哪个GPIO作为故障输入,支持多个故障源。
  • 触发极性:高电平触发还是低电平触发。
  • 周期模式:一次性触发(锁存)还是周期性触发(自动恢复)。
  • 中断使能:故障发生时是否产生中断,通知CPU。

我个人习惯把过流故障配置为一次性触发+强制低+中断。这样一旦发生过流,PWM立即关断,同时CPU收到中断,记录故障信息并进入安全状态。等故障排除后,软件手动清除故障标志,才能重新启动PWM。

4.7 实战配置示例

下面是一个完整的ePWM配置代码示例,用于电机控制中的对称PWM生成:

// ePWM1配置:对称PWM,频率10kHz,死区500ns
void EPWM1_Init(void)
{
    // 1. 时基单元配置
    EPwm1Regs.TBPRD = 6000;              // 周期值,假设SYSCLK=120MHz,TBCLK分频=1
    EPwm1Regs.TBPHS.half.TBPHS = 0;      // 相位偏移为0
    EPwm1Regs.TBCTR = 0;                 // 计数器清零
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;  // 递增递减模式
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;         // 禁止相位加载
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;        // 高速时钟分频
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;           // 低速时钟分频

    // 2. 计数器比较配置
    EPwm1Regs.CMPA.half.CMPA = 3000;     // 占空比50%
    EPwm1Regs.CMPB.half.CMPB = 3000;     // 用于互补输出
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;     // CMPA影子寄存器模式
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;     // CMPB影子寄存器模式
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;   // 计数器为0时加载
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    // 3. 动作限定器配置
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;   // 递增时CMPA匹配置高
    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // 递减时CMPA匹配置低
    EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; // 递增时CMPB匹配置低
    EPwm1Regs.AQCTLB.bit.CBD = AQ_SET;   // 递减时CMPB匹配置高

    // 4. 死区插入配置
    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;  // 使能上升沿和下降沿死区
    EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;       // 极性控制:ePWMxA高有效,ePWMxB低有效
    EPwm1Regs.DBRED = 60;                // 上升沿死区:60个TBCLK周期 ≈ 500ns
    EPwm1Regs.DBFED = 60;                // 下降沿死区:60个TBCLK周期 ≈ 500ns

    // 5. 故障捕获配置
    EPwm1Regs.TZSEL.bit.OSHT1 = 1;       // 使能TZ1作为一次性触发故障源
    EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LOW;  // 故障时ePWMxA强制低
    EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LOW;  // 故障时ePWMxB强制低
    EPwm1Regs.TZEINT.bit.OST = 1;        // 使能一次性触发中断

    // 6. 启动PWM
    EPwm1Regs.TBCTL.bit.SWFSYNC = 1;     // 软件强制同步
}

调试技巧:配置完ePWM后,我建议先用示波器看波形,确认频率、占空比、死区时间都正确。特别是死区时间,用示波器的延迟测量功能,看上升沿和下降沿之间的间隔是否等于你配置的值。这一步能帮你避免很多硬件故障。

好了,ePWM模块的六个核心部分就讲到这里。从时基单元到故障捕获,每个模块都有它的独特作用。理解它们之间的数据流和协同关系,是掌握C2000电机控制的关键。记住,ePWM不是孤立的,它和ADC、EQEP等模块配合,才能构成完整的电机控制系统。