前言在搞懂了 FOC 的电流环后很多同学兴冲冲地写好了代码结果电机不仅不转MOS 管还烫得能煎鸡蛋。问题往往出在“发波”环节。很多人试图直接把正弦波塞给 PWM 寄存器这叫 SPWM结果发现不仅电机没劲母线电压还浪费了很大一部分。现代 FOC 驱动无刷电机100% 都在使用SVPWM空间矢量脉宽调制。今天我们不扯枯燥的微积分用最直白的话和核心代码带你手撕 SVPWM 的正六边形魔法。一、 为什么不用普通的正弦波SPWMSPWM 的思路很简单你要三相交流电我就给你生成三个正弦波形状的 PWM 占空比。致命缺点在 SPWM 中相电压的最大幅值只能达到母线电压$V_{bus}$的 $\frac{1}{2}$。也就是说如果你用 12V 供电电机内部真正感受到的有效电压连 6V 都不到极大浪费了电源能力。SVPWM 的降维打击SVPWM 不是独立去看待三相电压而是把三相逆变器的 6 个 MOS 管当成一个整体。它通过巧妙的开关组合能在电机内部合成一个完美的圆形旋转磁场并且母线电压利用率比 SPWM 高出整整 15.4%二、 六边形结界8 个基本矢量无刷电机的驱动板有三个半桥U、V、W每个半桥有上下两个 MOS 管。我们规定上管开、下管关记为1上管关、下管开记为0。这三个半桥一共有 $2^3 8$ 种开关组合。这 8 种组合在空间中会产生 8 个电压矢量6 个非零矢量$V_1$ ~ $V_6$它们互成 60°刚好构成一个正六边形。2 个零矢量$V_0, V_7$三个上管全开或者三个下管全开。电机引脚被短接没有电压差这就是“刹车”状态。三、 魔法时刻如何合成任意矢量时间拼凑法现在PID 算法告诉我们“我需要一个指向 45°、大小为 5V 的目标矢量 $V_{ref}$”。但我们手里只有那 6 个固定在 0°、60°、120°... 的基本矢量怎么办SVPWM 的核心原理平行四边形法则 时间平均扇区判断Sector先看 $V_{ref}$ 落在哪个 60° 的扇区里比如 45° 落在第一扇区由 $V_1(0^\circ)$ 和 $V_2(60^\circ)$ 包围。时间分配T1, T2在极短的 PWM 周期比如 100us内我们让逆变器先输出一段时间的 $V_1$设为 $T_1$再输出一段时间的 $V_2$设为 $T_2$。塞入零矢量T0如果 $T_1 T_2$ 小于总周期 100us剩下的时间怎么办全部输出零矢量$V_0$ 或 $V_7$靠着在微秒级时间里疯狂切换这三个状态电机的电感会把它们“积分”平滑掉最终电机感受到的就是一个完美的 $V_{ref}$四、 灵魂代码生成传说中的“马鞍波”如果你把 SVPWM 最终算出来的 U、V、W 三相 PWM 占空比画出来你会发现它根本不是正弦波而是一个中间凹陷的“马鞍波”Saddle Wave正是因为这个奇特的马鞍波本质是注入了三次谐波才让 SVPWM 突破了供电电压的限制。核心代码实现七段式发波精简版// 假设已计算出扇区 sector以及作用时间 T1, T2 // T_pwm 为 PWM 总周期 void SVPWM_Generate(uint8_t sector, float T1, float T2, float T_pwm) { float Ta, Tb, Tc; // 三相的比较寄存器值 (占空比) float T0 (T_pwm - T1 - T2) / 2.0f; // 零矢量平分构成七段式发波减小谐波 // 根据不同扇区分配 MOS 管的导通时间 switch(sector) { case 1: Ta T0; // A相先开 Tb T0 T1; // B相后开 Tc T0 T1 T2; // C相最后开 break; case 2: Ta T0 T2; Tb T0; Tc T0 T1 T2; break; // ... (省略 case 3~6原理相同只是相序互换) } // 将 Ta, Tb, Tc 写入 STM32 高级定时器的 CCR1, CCR2, CCR3 寄存器 TIM1-CCR1 (uint16_t)Ta; TIM1-CCR2 (uint16_t)Tb; TIM1-CCR3 (uint16_t)Tc; }五、 总结SVPWM 就是单片机里的“调酒师”。它手里只有 6 瓶烈酒基本矢量和 1 瓶白水零矢量却能通过精确控制每种液体的倒入时间为你调出任意度数、任意口味的完美鸡尾酒旋转磁场。搞懂了 SVPWM你的无刷电机才算真正拥有了灵魂。今日互动你在写 SVPWM 的时候有没有遇到过“扇区判断错误”导致电机剧烈抖动、甚至烧 MOS 管的惨痛经历你最后是怎么定位到 bug 的欢迎在评论区对线