050 FOC的C语言实现:SVPWM生成
一、从一次电机尖叫说起
去年调试一个50W的伺服电机,上电后电机没转,反而发出尖锐的啸叫声,频率大概在2kHz左右。示波器抓了相电流,波形像被狗啃过一样,全是毛刺。当时第一反应是电流环PI参数没调好,调了半天没改善。后来用逻辑分析仪看PWM输出,才发现SVPWM的扇区判断出了bug——在扇区切换的边界,占空比跳变了一个不连续的值,导致电流环直接炸了。
这个坑让我意识到:SVPWM的C语言实现,看似就是几个公式套用,但实际工程中,定点数精度、扇区边界处理、死区补偿、载波同步这些细节,任何一个没处理好,电机都会给你“颜色”看。
二、SVPWM的数学骨架:从αβ到占空比
先回顾一下核心公式。假设我们已经通过Clark变换得到了αβ轴电压Uα、Uβ,SVPWM要干的事就是:用8个基本电压矢量(6个非零矢量+2个零矢量)去合成目标电压矢量。
2.1 扇区判断——别用atan2,用查表
教科书上判断扇区的方法是用atan2(Uβ, Uα)算角度,再除以60°取整。但在嵌入式里,atan2的运算量太大,一个浮点atan2要几百个时钟周期,对于20kHz的PWM周期来说,这简直是灾难。
工程上通用的做法是:根据Uα、Uβ的符号和相对大小,用三个中间变量判断。
// 定义三个中间变量,注意这里用