过调制的原理:
(1)过调制区判断:过调制分两个区,分别是过调制一区和过调制二区。下面是过调制的判断:
从上面的图片可以看出来,过调制的判断其实就是去计算电机的调制比M的大小。电机的基准电压Ubase = 2*Udc/pi = 0.6366Udc(Ud是母线电压的大小)。
通过计算出 M = |Us| / Ubase去计算调制比M。如果M < 1表示内切圆、1< M < 1.1547表示调制比1区、1.1547 < M < 2表示调制比2区。
(2)调制算法实现:
区分过调制1区和过调制2区的主要目的就是为了让电机,从矢量圆过度到过调制的时候更加的平滑。
不同的过调制区使用的办法不一样,比如过调制1区可以通过最小相位误差法。过调制2区使用最小幅值误差法。
最小相位误差法:原理就是当合成矢量|Us| > Udc / sqrt(3)的时候。通过等比例缩放,将赋值缩放到六边形上面。
在过调制1区里面,马鞍波是被削顶,最后会变成方波控制。
最小幅值误差法:原理是将 |Us| 与 六边型做垂直的线,求出另外一条边。这条边是最大的。
上面图片显示 |Us| = |Uref|。做垂直线算出Uy,这个Uy就是最小幅值误差计算出来的值。
在过调制2区里面,需要根据合成矢量 | Us| 的值去计算出黄色区域的角度范围(图片里面值展示扇区1和扇区2的部分内容)。在蓝色区域内使用“六步换相”的方式去控制,在黄色区域使用“等比例缩放到六边形”的方式去控制。
过调制算法的实现步骤:
(1)过调制算法并不难,其核心就是去计算出电机的 |Us| 的大小,然后去判断电机位于那个过调制区。|Us|的大小可以通过 |Us| = sqrt(Uα^2 + Uβ^2) 计算获取。
Us = sqrt(Uα^2 + Uβ^2)
if(Us < Udc/sqrt()3)
//矢量圆
else if (Us < 2*Udc/3)
//过调制1区
else if(Us < 2*Udc/sqrt(3))
//过调制2区
(2) 求取gamma的范围
这个角度的求取也是比较简单的,使用的是三角函数去求解。
arg = 2 * Udc / (3 * U) * sin(2 * pi / 3);
gamma_base = pi - 2 *pi / 3 - asin(arg);
然后就可以根据电机位于那个扇区去判断电机的电角度是否位于对于的角度范围之内。来决定是使用六步换相去控制,还是通过等比例缩放到六边形的控制。
下面是Matlab的m文件,仅提供参考:
function [Ua, Ub, Uc, mode, MI] = SVPWM_OverMod(U_alpha, U_beta, Udc) %----符号取反(适配FOC方向) U_alpha = -U_alpha; U_beta = -U_beta; %----单精度常里---- sqrt3 = single(1.7320508075688772); pi_val = single(3.141592653589793); two_pi = single(6.283185307179586); two_thirds = single(0.6666666666666666); %----计算幅值与角度 U = sqrt(U_alpha*U_alpha + U_beta*U_beta); %----计算调制比MI(核心输出) MI = U / (udc / sqrt3); MI = single(MI); %确保单精度 if U < single(1e-6) Ua = single(0.5); Ub = single(0.5); Uc = single(0.5); mode = uint8(0); MI = single(0); return; end theta = atan2(U_beta, U_alpha); if theta < 0 theta = theta + two_pi; elseif theta >= two_pi theta = theta - two_pi; end % ----扇区判断 if U_beta > 0 A = 0; else A = 1; end if U_beta - sqrt3 * U_alpha < 0 B = 0; else B = 1; end if U_beta + sqrt3 * U_alpha < 0 C = 0; else C = 1; end Sector = 4*A + 2*B + C; % ---临时变里统一初始化为single---- T1 = single(0); T2 = single(0); T0 = single(0); scale = single(0); gamma = single(0) ; HA = single(0); HB = single(0); HC = single(0); mode = uint8(0); % 默认线性区 %----调制区域计算 if U <= Udc / sqrt3 %-线性调制区- mode = uint8(0); switch Sector case 1 T1 = sqrt3 * U / Udc * sin(pi_val/3 - theta); T2 = sqrt3 * U / Udc * sin(theta); T0 = single(1) - T1 - T2; HA = T0 / single(2); HB = T0 / single(2) + T1; HC = T0 / single(2) + T1 + T2; case 2 T1 = sqrt3 * U / Udc * sin(pi_val - theta); T2 = sqrt3 * U / Udc sin(theta - single(2)*pi_val/3); T0 = single(1) - T1 - T2; HA = T0 / single(2) + T1 + T2; HB = T0 / single(2); HC = T0 / single(2) + T1; case 3 T1 = sqrt3 * U / Udc sin(single(2)*pi_val/3 - theta); T2 = sqrt3 * U / Udc * sin(theta - pi_val/3); T0 = single(1) - T1 - T2; HA = T0 / single(2) + T2; HB = T0 / single(2); HC = T0 / single(2) + T1 + T2; case 4 T1 = sqrt3 * U / Udc * sin(single(5)*pi_val/3 - theta); T2 = sqrt3 * U / Udc * sin(theta - single(4)*pi_val/3); T0 = single(1) - T1 - T2; HA = T0 / single(2) + T1; HB = T0 / single(2) + T1 + T2; HC = T0 / single(2); case 5 T1 = sqrt3 * U / Udc sinl-theta); T2 = sqrt3 * U / Udc * sin(theta - single(5)*pi_val/3); T0 = single(1) - T1 - T2; HA = T0 / single(2); HB = T0 / single(2) + T1 + T2; HC = T0 / single(2) + T2; case 6 T1 = sqrt3 * U / Udc * sin(single(4)*pi_val/3 - theta); T2 = sqrt3 * U / Ude * sin(theta - pi_val); T0 = single(1) - T1 - T2; HA = T0 / single(2) + T1 + T2; HB = T0 / single(2) + T2; HC = T0 / single(2); end end elseif U <= (single(2) / single(3)) * Udc mode = uint8(1); switch Sector case 1 T1 = sqrt3 * U / Udc * sin(pi_val/3 - theta); T2 = sqrt3 * U / Udc * sin(theta); if T1 + T2 > single(1) scale = single(1) / (T1 + T2); T1 = T1 * scale; T2 = T2 * scale; T0 = single(0); else T0 = single(1) - T1 - T2; end HA = T0 / single(2); HB = T0 / single(2) + T1; HC = T0 / single(2) + T1 + T2; case 2 T1 = sqrt3 * U / Udc * sin(pi_val - theta); T2 = sqrt3 * U / Udc * sin(theta - single(2)*pi_val/3); if T1 + T2 > single(1) scale = single(1) / (T1 + T2); T1 = T1 * scale; T2 = T2 * scale; T0 = single(0); else T0 = single(1) - T1 - T2; end HA = T0 / single(2) + T1 + T2; HB = T0 / single(2); HC = T0 / single(2) + T1; case 3 T1 = sqrt3 * U / Udc * sin(single(2)*pi_val/3 - theta); T2 = sqrt3 * U / Udc * sin(theta - pi_val/3); if T1 + T2 > single(1) scale = single(1) / (T1 + T2); T1 = T1 * scale; T2 = T2 * scale; T0 = single(0); else T0 = single(1) - T1 - T2; end HA = T0 / single(2) + T2; HB = T0 / single(2); HC = T0 / single(2) + T1 + T2; case 4 T1 = sqrt3 * U / Udc * sin(single(5)*pi_val/3 - theta); T2 = sqrt3 * U / Udc * sin(theta - single(4)*pi_val/3); if T1 + T2 > single(1) scale = single(1) / (T1 + T2); T1 = T1 * scale; T2 = T2 * scale; T0 = single(0); else T0 = single(1) - T1 - T2; end HA = T0 / single(2) + T1; HB = T0 / single(2) + T1 + T2; HC = T0 / single(2); case 5 T1 = sqrt3 * U / Udc * sin(-theta); T2 = sqrt3 * U / Udc * sin(theta - single(5)*pi_val/3); if T1 + T2 > single(1) scale = single(1) / (T1 + T2); T1 = T1 * scale; T2 = T2 * scale; T0 = single(0); else T0 = single(1) - T1 - T2; end HA = T0 / single(2); HB = T0 / single(2) + T1 + T2; HC = T0 / single(2) + T2; case 6 T1 = sqrt3 * U / Udc * sin(single(4)*pi_val/3 - theta); T2 = sqrt3 * U / Ude * sin(theta - pi_val); if T1 + T2 > single(1) scale = single(1) / (T1 + T2); T1 = T1 * scale; T2 = T2 * scale; T0 = single(0); else T0 = single(1) - T1 - T2; end HA = T0 / single(2) + T1 + T2; HB = T0 / single(2) + T2; HC = T0 / single(2); end end elseif U < (single(2) / sqrt3) * Udc mode = uint8(2); mode = uint8(2); arg = single(2) * Udc / (single(3) * U) * sin(single(2)*pi_val/3); if arg > single(1) arg = single(1); end if arg < -single(1) arg = -single(1); end gamma_base = pi_val - single(2)*pi_val/3 - asin(arg); switch Sector case 1 T1 = sqrt3 * U / Udc * sin(pi_val/3 - theta); T2 = sqrt3 * U / Udc * sin(theta); gamma = gamma_base; if (theta <= gamma) || (theta >= pi_val/3 - gamma) if T1 >= T2 T1 = single(1); T2 = single(0); T0 = single(0); else T1 = single(0); T2 = single(1); T0 = single(0); end else if T1 + T2 > single(1) scale = single(1) / (T1 + T2); T1 = T1 * scale; T2 = T2 * scale; T0 = single(0); else T0 = single(1) - T1 - T2; end end HA = T0 / single(2); HB = T0 / single(2) + T1; HC = T0 / single(2) + T1 + T2; case 2 T1 = sqrt3 * U / Udc * sin(pi_val - theta); T2 = sqrt3 * U / Udc * sin(theta - single(2)*pi_val/3); gamma = gamma_base + single(2)*pi_val/3; if (theta <= gamma) || (theta >= single(5)*pi_val/3 - gamma) if T1 >= T2 T1 = single(1); T2 = single(0); T0 = single(0); else T1 = single(0); T2 = single(1); T0 = single(0); end else if T1 + T2 > single(1) scale = single(1) / (T1 + T2); T1 = T1 * scale; T2 = T2 * scale; T0 = single(0); else T0 = single(1) - T11 - T2; end end HA = T0 / single(2) + T1 + T2; HB = T0 / single(2); HC - T0 / single(2) + T1; case 3 T1 = sqrt3 * U / Udc * sin(single(2)*pi_val/3 - theta); T2 = sqrt3 * U / Udc * sin(theta - pi_val/3); gamma = gamma_base + pi_val/3; if (theta <= gamma) || (theta >= single(3)*pi_val/3 - gamma) if T1 >= T2 T1 = single(1); T2 = single(0); T0 = single(0); else T1 = single(0); T2 = single(1); T0 - single(0); end else if T1 + T2 > single(1) scale - single(1) / (T1 + T2); T1 = T1 * scale; T2 = T2 * scale; T0 = single(0); else T0 = single(1) - T1 - T2; end end HA = T0 / single(2) + T2; HB = T0 / single(2); HC = T0 / single(2) + T1 + T2; case 4 T1 = sqrt3 * U / Udc * sin(singleT5)*pi_val/3 - theta); T2 = sqrt3 * U / Udc * sin(theta - single(4)*pi_val/3); gamma - gamma_base + single(4)*pi_val/3; if (theta <= gamma) || (theta >= single(9)*pi_val/3 - gamma) if T1_ratio >= T2_ratio T1 = single(1); T2 = single(0); T0 = single(0); else T1 = single(0); T2 = single(1); T0 - single(0); end else if T1 + T2 > single(1) scale = single(1) / (T1 + T2); T1 = T1 * scale; T2 = T2 * scale; T0 = single(0); else T0 = single(1) - T1 - T2; end end HA = T0 / single(2) + T1; HB = T0 / single(2) + T1 + T2; HC = T0 / single(2); case 5 T1 = sqrt3 * U / Udc * sin(-theta); T2 = sqrt3 * U / Udc * sin(theta - single(5)*pi_val/3); gamma = gamma_base + single(5)*pi_val/3; if (theta <= gamma) || (theta >= single(11)*pi_val/3 - gamma) if T1 >= T2 T1 = single(1); T2 = single(0); T0 = single(0); else T1 = single(0); T2 = single(1); T0 = single(0); end else if T1 + T2 > single(1) scale = single(1) / (T1 + T2); T1 = T1 * scale; T2 = T2 * scale; T0 = single(0); else T0 = single(1) - T1 - T2; end end HA = T0 / single(2); HB = T0 / single(2) + T1 + T2; HC = T0 / single(2) + T2; case 6 T1 = sqrt3 * U / Udc * sin(single(4)*pi_val/3 - theta); T2 = sqrt3 * U / Udc * sin(theta - pi_val); gamma = gamma_base + single(3)*pi_val/3; if (theta <= gamma) || (theta >= single(7)*pi_val/3 - gamma) if T1 >= T2 T1 = single(1); T2 = single(0); T0 = single(0); else T1 = single(0); T2 = single(1); T0 = single(0); end else if T1 + T2 > single(1) scale = single(1) / (T1 + T2); T1 = T1 * scale; T2 = T2 * scale; T0 = single(0); else T0 = single(1) - T1 - T2; end end HA = T0 / single(2) + T1 + T2; HB = T0 / single(2) + T2; HC = T0 / single(2); end end else mode = uint8(2); switch Sector case 1 T1 = sqrt3 * U / Udc * sin(pi_val/3 - theta); T2 = sqrt3 * U / Udc * sin(theta); if T1 >= T2 T1 = single(1); T2 = single(0); T0 = single(0); else T1 = single(0); T2 = single(1); T0 = single(0); end HA = T0 / single(2); HB = T0 / single(2) + T1; HC = T0 / single(2) + T1 + T2; case 2 T1 = sqrt3 * U / Udc * sin(pi_val - theta); T2 = sqrt3 * U / Udc * sin(theta - single(2)*pi_val/3); if T1 >= T2 T1 = single(1); T2 = single(0); T0 = single(0); else T1 = single(0); T2 = single(1); T0 = single(0); end HA = T0 / single(2) + T1 + T2; HB = T0 / single(2); HC = T0 / single(2) + T1; case 3 T1 = sqrt3 * U / Udc * sin(single(2)*pi_val/3 - theta); T2 = sqrt3 * U / Udc * sin(theta - pi_val/3); if T1 >= T2 T1 = single(1); T2 = single(0); T0 = single(0); else T1 = single(0); T2 = single(1); T0 = single(0); end HA = T0 / single(2) + T2; HB - T0 / single(2); HC - T0 / single(2) + T1 + T2; case 4 T1 = sqrt3 * U / Udc * sin(single(5)*pi_val/3 - theta); T2 = sqrt3 * U / Udc * sin(theta - single(4)*pi_val/3); if T1 >= T2 T1 = single(1); T2 = single(0); T0 = single(0); else T1 = single(0); T2 = single(1); T0 = single(0); end HA = T0 / single(2) + T1; HB = T0 / single(2) + T1 + T2; HC = T0 / single(2); case 5 T1 = sqrt3 * U / Udc * sin(-theta); T2 = sqrt3 * U / Udc * sin(theta - single(5)*pi_val/3); if T1 >= T2 T1 = single(1); T2 = single(0); T0 = single(0) ; else T1 = single(0); T2 = single(1); T0 = single(0); end HA = T0 / single(2); HB = T0 / single(2) + T1 + T2; HC = T0 / single(2) + T2; case 6 T1 = sqrt3 * U / Udc * sin(single(4)*pi_val/3 - theta); T2 = sqrt3 * U / Udc * sin(theta - pi_val); if T1 >= T2 T1 = single(1); T2 = single(0); T0 = single(0); else T1 = single(0); T2 = single(1); T0 = single(0); end HA = T0 / single(2) + T1 + T2; HB = T0 / single(2) + T2; HC = T0 / single(2); end end % ----输出占空比,限幅并转为single---- Ua = min(max(HA, single(0)), single(1)); Ub = min(max(HB, single(0)), single(1)); Uc = min(max(HC, single(0)), single(1)); Ua = single(Ua); Ub = single(Ub); Uc = single(Uc); end