4、PWM信号生成:ePWM模块详解、载波与调制波设置、死区时间插入、PWM频率与分辨率计算
好,咱们进入第四节。这一节可以说是电机控制的“心脏”——PWM信号生成。你想想看,不管你的控制算法写得多么花哨,最后都得靠PWM把数字世界的电压指令变成电机绕组上的实际电压。dSPACE里的ePWM模块,就是干这个活的。
我个人习惯把ePWM模块比作一个“精密的时间雕刻师”。它用数字电路的方式,把时间轴切成一段一段,然后在每一段里精确控制高低电平的占空比。说白了,就是靠开关管的通断时间来模拟正弦波。
4.1 ePWM模块内部结构
dSPACE的ePWM模块,其实是从TI的C2000系列DSP里继承过来的。它的核心由几个子模块组成:
- 时基模块(TB):负责产生计数时钟,决定PWM的周期和频率。
- 比较模块(CC):把计数器的值和用户设定的比较值做对比,产生跳变沿。
- 动作模块(AQ):根据比较结果,决定输出是高电平还是低电平。
- 死区模块(DB):插入死区时间,防止上下桥臂直通。
- 事件触发模块(ET):产生中断或触发ADC采样。
嗯,这里要注意:在dSPACE的图形化界面里,你不需要像写DSP寄存器那样逐位配置。但理解这些子模块的作用,能帮你快速定位问题。我在项目中遇到过,有人调了半天PWM没输出,最后发现是时基模块的时钟分频设错了。
4.2 载波与调制波设置
PWM的核心思想,就是“载波”和“调制波”的比较。载波通常是高频的三角波或锯齿波,调制波就是我们想要输出的电压指令。
在dSPACE里,设置载波很简单:
// 伪代码示例:载波频率设置
ePWM模块.TBPRD = 系统时钟频率 / (2 * PWM频率) - 1;
// 比如系统时钟100MHz,想要10kHz PWM
ePWM模块.TBPRD = 100e6 / (2 * 10e3) - 1; // 结果为4999
调制波呢?就是你的控制算法算出来的电压指令,比如SVPWM里的Ualpha和Ubeta。dSPACE的ePWM模块支持多种调制方式:
- 对称调制(Up-Down计数):载波先增后减,适合三相电机控制,谐波小。
- 非对称调制(Up计数):载波只增不减,适合单相或DC-DC。
我个人习惯用对称调制。为什么?因为它的有效开关频率是载波频率的两倍,而且输出波形对称,谐波含量更低。你想想看,同样的开关损耗,对称调制能获得更好的波形质量。
4.3 死区时间插入
死区时间,这是新手最容易忽略、老手最不敢马虎的地方。说白了,就是防止上下两个开关管同时导通。因为开关管有导通和关断延迟,如果上管还没完全关断,下管就导通了,那就直接短路——炸管子。
我在项目中遇到过,有一次调试一台30kW的电机驱动器,上电瞬间IGBT模块直接炸了。后来查原因,就是死区时间设得太短,只有1微秒,而IGBT的关断延迟是1.5微秒。嗯,从那以后,我设置死区时间都会留至少2倍的余量。
在dSPACE里设置死区时间:
// 死区时间设置示例
ePWM模块.DBRED = 死区时间 / (1 / 系统时钟频率);
// 比如系统时钟100MHz,想要2us死区
ePWM模块.DBRED = 2e-6 / (1 / 100e6); // 结果为200个时钟周期
ePWM模块.DBFED = 200; // 上升沿和下降沿死区通常设成一样
4.4 PWM频率与分辨率计算
PWM频率和分辨率,是一对矛盾体。频率越高,分辨率越低。为什么?因为计数器的位数是有限的。
咱们来算一笔账:
| 系统时钟 | PWM频率 | 计数周期数 | 分辨率(位) |
|---|---|---|---|
| 100 MHz | 10 kHz | 5000 | ~12.3 位 |
| 100 MHz | 20 kHz | 2500 | ~11.3 位 |
| 100 MHz | 100 kHz | 500 | ~9.0 位 |
你看,当PWM频率从10kHz升到100kHz,分辨率从12位掉到了9位。9位分辨率意味着什么?意味着你的电压指令只能分成512份,精度严重下降。电机低速运行时,这种低分辨率会导致明显的电流纹波和噪声。
我建议:对于大多数电机控制应用,PWM频率选在8kHz到20kHz之间比较合适。既能避开人耳听觉范围(减少噪声),又能保证足够的分辨率。如果你非要跑高频,比如100kHz以上,那就得考虑使用高分辨率PWM(HRPWM)模块了。dSPACE的DS1104和MicroLabBox都支持HRPWM,可以把分辨率提升到150皮秒级别。
好了,这一节的内容就到这里。PWM生成看似简单,但里面的门道不少。你想想看,一个占空比信号,背后牵涉到频率、分辨率、死区、调制方式这么多因素。下次你在dSPACE里拖一个ePWM模块时,希望能想起今天聊的这些内容。