4、换相与调制协同:编码器角度获取与SVPWM角度对齐、换相信号与PWM更新同步机制
好,咱们进入第四章。这一章讲的是协同,说白了就是怎么让编码器、换相逻辑和SVPWM这三兄弟步调一致。很多新手调电机,要么转起来抖,要么高速丢步,要么电流波形乱七八糟——十有八九都是这里没对齐。
我个人习惯把这个问题拆成两个层面:角度对齐和时序同步。角度对不齐,SVPWM给的电压矢量方向就是错的;时序不同步,换相瞬间电流会突变,轻则噪声大,重则过流保护。
4.1 编码器角度获取:从脉冲到电角度
编码器输出的原始信号是脉冲,不是角度。你需要通过计数器把脉冲数换算成机械角度,再乘以极对数得到电角度。这个过程看似简单,但坑不少。
核心公式:
θ_elec = (pulse_count / CPR) × 2π × pole_pairs
其中 CPR 是编码器每圈脉冲数(Counts Per Revolution),注意是四倍频后的值。
我在项目中遇到过一个问题:编码器刚上电时,pulse_count 是随机的。如果你直接拿这个随机值去算角度,电机第一圈会猛抽一下。解决办法很简单——上电后先读取一次编码器位置作为零点偏移,后续所有角度都减去这个偏移。
我的习惯做法:
- 上电后延时 50ms,等编码器供电稳定
- 连续读取 10 次位置,取平均值作为零点
- 如果编码器是绝对值型,直接读,但也要做一次零点校准
4.2 角度对齐:编码器零位与SVPWM的U相轴线
这是整个协同的命门。SVPWM 的电压矢量是以 U 相绕组轴线为参考的,而编码器的零位是机械安装决定的。这两个零位如果不重合,你算出来的电角度就是错的。
怎么对齐?我一般用直流注入法:
- 给电机施加一个固定的 U+ V- 直流电压(占空比 5%~10%,电流限制在额定 20%)
- 转子会自己转到 U 相轴线方向
- 此时读取编码器位置,记作 θ_align
- 后续所有电角度都减去 θ_align
注意:直流注入时电流不要太大,否则转子会剧烈抖动甚至反转。我曾经有一次电流设到 30%,结果电机直接跳起来把联轴器甩断了……嗯,从那以后我再也不敢超过 20%。
对齐完成后,你可以验证一下:手动转动转子,用示波器看 U 相反电动势过零点,同时读编码器角度。如果对齐正确,反电动势过零点应该对应电角度 0° 或 180°。
4.3 换相信号与PWM更新同步机制
角度对齐只是第一步。真正让电机平稳运行的,是换相信号和 PWM 更新的时序配合。你想想看,如果换相发生在 PWM 周期的中间,电流波形会突然跳变,产生很大的转矩脉动。
解决方案是让换相与 PWM 载波同步。具体来说:
- PWM 定时器使用中心对齐模式(Center-Aligned PWM)
- 换相动作在 PWM 载波的谷底或峰值处触发
- 利用定时器的更新中断(Update Event)来执行换相逻辑
同步时序的关键点:
| 事件 | 触发时机 | 说明 |
|---|---|---|
| 读取编码器角度 | PWM 载波谷底 | 此时电流采样噪声最小 |
| 计算 SVPWM 占空比 | PWM 载波谷底 | 利用上一个周期的电流值 |
| 更新 PWM 比较寄存器 | PWM 载波峰值 | 保证下一个周期生效 |
| 执行换相 | PWM 载波峰值 | 与占空比更新同步 |
为什么换相和占空比更新要放在峰值?因为中心对齐模式下,峰值时刻所有桥臂都处于关断状态(死区时间内),此时切换导通状态不会产生电流突变。这是我踩过坑才明白的——以前我把换相放在谷底,结果每次换相都出现电流尖峰,查了两天才发现是时序问题。
4.4 整体协同流程
把上面这些串起来,一个完整的 PWM 周期内的协同流程是这样的:
这个流程里有一个容易被忽略的点:时间余量。从谷底到峰值,中间只有半个 PWM 周期的时间(比如 10kHz 载波就是 50μs)。你要在这 50μs 内完成角度读取、电流滤波、扇区判断、占空比计算。如果 MCU 主频不够,或者代码写得不够高效,就会超时。
优化建议:
- 角度计算用查表法代替三角函数,速度能快 5~10 倍
- 扇区判断用逻辑运算,不要用 if-else 嵌套
- 占空比计算用定点数,避免浮点运算
4.5 避坑指南:我踩过的三个坑
做这个协同调优,我前前后后踩了不少坑。挑三个最典型的分享给你:
- 坑一:编码器零点漂移。 有一次调试,电机低速正常,高速就抖。查了半天发现是编码器安装松动,高速振动导致零点偏移。后来我改用锁紧螺母+螺纹胶,再也没出过问题。
- 坑二:换相瞬间电流过冲。 前面说了,换相和占空比更新不同步导致的。解决办法就是强制把换相动作放在 PWM 峰值中断里,和比较寄存器更新绑在一起。
- 坑三:角度计算延迟。 我用的是 12 位绝对值编码器,SPI 读取一次要 2μs。如果放在中断里直接读,会拖慢整个控制周期。后来我改成 DMA 后台读取,中断里只读一个缓存变量,问题解决。
最后提醒一句:协同调优不是一次就能搞定的。我建议你先在低速(100rpm)下验证角度对齐,再逐步提速到额定转速。每提高一个速度等级,都要用示波器看一次电流波形和换相点。别偷懒,偷懒的代价就是炸管。