4. PWM 基础与死区配置:ePWM 模块原理、频率与分辨率、死区插入

各位工程师,大家好。欢迎来到第四章。

这一章,我们聊聊伺服系统里最基础、也最关键的环节——PWM 生成。说白了,电机转得快不快、稳不稳,最终都得靠 PWM 波去驱动功率管。而 ePWM 模块,就是 C2000 干这活的“心脏”。

我刚开始接触 C2000 时,总觉得 PWM 配置就是设个频率、占空比,没什么难的。直到有一次,驱动器在满载时突然炸管……嗯,从那以后,我才真正重视起死区配置和分辨率这些细节。今天,我把这些经验掰开揉碎了讲给你听。

4.1 ePWM 模块的核心架构

C2000 的 ePWM 模块,每个模块包含两个独立的 PWM 输出:ePWMxA 和 ePWMxB。它们可以配置成互补输出,也可以独立工作。每个模块内部,主要由以下几个部分组成:

  • 时基模块 (TB):负责产生计数时钟和周期。
  • 比较模块 (CC):设定占空比和比较值。
  • 动作模块 (AQ):根据计数状态和比较结果,决定输出是高电平还是低电平。
  • 死区模块 (DB):插入死区时间,防止上下桥臂直通。
  • 事件触发模块 (ET):产生中断或启动 ADC 转换。

你想想看,这五个模块协同工作,才构成了一个完整的 PWM 通道。我个人习惯,在配置任何 PWM 之前,先画一张模块连接图,理清信号流向。下面这张图,就是 ePWM 模块的内部数据流。

ePWM 模块内部数据流 时基模块 (TB) CLK / 周期 / 计数 比较模块 (CC) CMPA / CMPB 动作模块 (AQ) 置高 / 置低 / 翻转 死区模块 (DB) 上升沿 / 下降沿 事件触发 (ET) 中断 / ADC 启动 PWMxA/B 💡 说明: 时基模块驱动整个 PWM 时序。 比较模块决定占空比。 死区模块在互补输出时插入延迟。

从这张图你可以看到,信号从时基模块出发,经过比较、动作、死区,最终输出到功率管。每个环节都影响最终的 PWM 质量。

4.2 PWM 频率与分辨率设置

PWM 频率,由时基模块的时钟分频和周期寄存器共同决定。公式很简单:

PWM 频率 = SYSCLKOUT / (TBCLK 分频系数 × TBPRD + 1)

举个例子,假设系统时钟 SYSCLKOUT = 100 MHz,我们想要 20 kHz 的 PWM 频率。如果 TBCLK 不分频(分频系数 = 1),那么:

TBPRD = 100,000,000 / 20,000 - 1 = 4999

这里要注意,TBPRD 的值决定了 PWM 的周期。值越大,周期越长,频率越低。

💡 我的经验: 伺服系统常用的 PWM 频率在 10 kHz ~ 20 kHz 之间。频率太低,电机噪音大;频率太高,开关损耗增加。我个人习惯,通用伺服选 16 kHz,既能避开人耳敏感区,又能平衡损耗。

4.2.1 分辨率问题

分辨率,说白了就是 PWM 占空比能细调到什么程度。它由时基计数器的位数决定。C2000 的 ePWM 模块使用 16 位计数器,理论上分辨率是 1/65536。但实际中,受限于系统时钟和 PWM 频率,有效分辨率会下降。

为什么会这样?因为 PWM 周期越长,每个计数步长对应的时间就越长,占空比调节的粒度就越粗。举个例子:

PWM 频率 系统时钟 TBPRD 占空比步长
10 kHz 100 MHz 9999 0.01%
50 kHz 100 MHz 1999 0.05%
100 kHz 100 MHz 999 0.1%

你看,频率越高,分辨率越低。对于高精度伺服,我建议 PWM 频率不要超过 20 kHz,否则电流环的调节精度会受影响。

⚠️ 注意: 我曾经在一个高速主轴项目中,为了追求低噪音,把 PWM 频率设到了 40 kHz。结果电流环抖动厉害,电机发热严重。后来才发现,分辨率太低,导致电流纹波过大。所以,频率和分辨率之间,一定要权衡。

4.3 死区时间插入

死区时间,是伺服系统里绝对不能忽视的一环。它的作用,是防止上下桥臂的功率管同时导通。你想想看,如果上下管同时导通,电源直接短路,瞬间大电流就会烧毁功率管。

死区模块的工作原理,是在 PWM 信号的上升沿或下降沿插入一段延迟。C2000 的死区模块支持多种模式:

  • 上升沿延迟:只在上升沿插入死区。
  • 下降沿延迟:只在下降沿插入死区。
  • 上升沿和下降沿都延迟:双边插入。
  • 互补输出模式:自动生成互补 PWM,并插入死区。

我个人最常用的是互补输出模式。配置起来也很简单:

// 死区配置示例
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // 使能死区
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIGH;     // 高电平有效
EPwm1Regs.DBRED.bit.DBRED = 100;               // 上升沿死区 100 个 TBCLK
EPwm1Regs.DBFED.bit.DBFED = 100;               // 下降沿死区 100 个 TBCLK

这段代码配置了 100 个 TBCLK 周期的死区时间。如果 TBCLK = 100 MHz,那么死区时间就是 1 µs。

4.3.1 死区时间怎么选?

死区时间不是越大越好,也不是越小越好。太大会导致波形失真,影响电流控制精度;太小又可能无法完全防止直通。

一般来说,死区时间取决于功率管的开关特性。IGBT 的开关速度较慢,死区时间通常在 1 µs ~ 3 µs;MOSFET 的开关速度快,死区时间可以短到 200 ns ~ 500 ns。

🔧 避坑指南: 我曾经在一个项目中,为了追求极致的电流响应,把死区时间设到了 100 ns。结果在满载测试时,功率管瞬间炸裂。后来检查发现,MOSFET 的关断延迟时间本身就超过 100 ns,死区时间根本不够。所以,死区时间一定要大于功率管的最大关断延迟时间,并留出 20%~30% 的余量。

4.4 实战配置步骤

好了,理论讲完了,我们直接上手配置。下面是一个完整的 ePWM 初始化流程:

  1. 使能 ePWM 模块时钟:在系统控制寄存器中使能对应外设时钟。
  2. 配置 GPIO 复用功能:将 GPIO 引脚设置为 ePWM 输出模式。
  3. 配置时基模块:设置时钟分频、计数模式(向上/向下/上下)、周期值。
  4. 配置比较模块:设置 CMPA 和 CMPB 的初始值。
  5. 配置动作模块:定义计数到零、周期、比较匹配时的输出动作。
  6. 配置死区模块:选择死区模式,设置上升沿和下降沿延迟。
  7. 配置事件触发:如果需要中断或 ADC 触发,配置 ET 模块。
  8. 启动时基计数器:使能计数器开始工作。

下面是一个完整的初始化代码示例:

void EPwm1_Init(void)
{
    // 1. 使能 ePWM1 时钟
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;  // 停止所有 ePWM 时钟
    CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;      // 使能 ePWM1 时钟

    // 2. 配置 GPIO0 和 GPIO1 为 ePWM1A 和 ePWM1B
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;    // GPIO0 = EPWM1A
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;    // GPIO1 = EPWM1B

    // 3. 时基配置:100 MHz TBCLK,向上计数,周期 5000(20 kHz)
    EPwm1Regs.TBCTL.bit.CLKDIV = 0;        // 不分频
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;     // 高速时钟不分频
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 向上计数
    EPwm1Regs.TBPRD = 5000;                // 周期值

    // 4. 比较配置:初始占空比 50%
    EPwm1Regs.CMPA.bit.CMPA = 2500;

    // 5. 动作配置:计数到零时置高,匹配 CMPA 时置低
    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;

    // 6. 死区配置:互补输出,死区时间 1 µs(100 个 TBCLK)
    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIGH;
    EPwm1Regs.DBRED.bit.DBRED = 100;
    EPwm1Regs.DBFED.bit.DBFED = 100;

    // 7. 启动时基
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;  // 启动所有 ePWM 时钟
}

这段代码配置了一个 20 kHz 的互补 PWM 输出,死区时间 1 µs。你可以直接复制到你的工程里,稍作修改就能用。

💡 小技巧: 调试时,我习惯先用示波器观察 PWM 波形,确认频率和死区时间是否正确。特别是死区时间,一定要放大看,确保没有重叠。我曾经遇到过死区配置正确,但波形仍有重叠的情况,最后发现是 GPIO 的压摆率设置太慢导致的。所以,别忘了检查 GPIO 的驱动能力。

4.5 本章小结

这一章,我们深入探讨了 ePWM 模块的原理、频率与分辨率的关系,以及死区时间的配置方法。记住几个关键点:

  • PWM 频率和分辨率是矛盾的,需要根据应用场景权衡。
  • 死区时间必须大于功率管的关断延迟,并留出余量。
  • 配置时,按照时基→比较→动作→死区的顺序,不容易出错。