FOC SVPWM过调制(学习记录)

过调制的原理:

(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
相关推荐
AI职业加油站2 小时前
AI 校招现状:大模型应用工程师证书,助力简历能力证明
大数据·运维·人工智能·学习·职场发展
千里马022 小时前
STM32读取AD7606-4(HAL库)
stm32·单片机·嵌入式硬件
陈年老古董3 小时前
Hive 函数学习笔记(上):单行函数与炸裂函数
hive·笔记·学习
喜欢打篮球的普通人3 小时前
MiniMind 学习笔记(十八):速通强化学习——从 MDP 到 PPO 的概念与算法地图
笔记·深度学习·学习
不会代码的小猴4 小时前
中断(NVIC)
单片机·嵌入式硬件
老王爱玩车4 小时前
动态内存管理
c语言·开发语言·学习·面试
糖糖单片机设计4 小时前
基于STM32的空气污染检测与报警系统设计与实现
stm32·单片机·嵌入式硬件
zhangzhangkeji4 小时前
stm32 15-2 flash 闪存:代码部分二
stm32