简述FOC电机控制之SVPWM原理(下)

电子说

1.3w人已加入

描述

2.3 计算相邻两个基本矢量电压的作用时间:

扇区判断结束后,就是计算相邻两个基本矢量电压的作用时间

在扇区1时,由U6和U4合成,设在一个时间周期Ts内,U4作用的时间为T4,U6作用的时间为T6。由 基本矢量电压在αβ轴上的投影 和 目标矢量电压在αβ轴上的投影 分别相等建立等式:

FOC

FOC

FOC

FOC

FOC

FOC

到这里,计算出来的公式看着有点复杂,所以我们通过下面的方式稍稍简化一下,记:

FOC

则在各个扇区内的作用时间就分别为:

FOC

到这里,合成目标矢量电压Uref需要的两个相邻矢量电压Ux,Uy以及分别作用的时间Tx,Ty就计算好了,但这里计算出来的时间不一定刚好满足Tx+Ty=Ts,当Tx+Ty>Ts时需要进行等比例缩小处理,处理方式如下:

FOC

当Tx+Ty

FOC

2.4 三路PWM占空比计算

目标矢量电压的所在扇区知道了,相邻两个基本矢量电压及其作用时间也知道了,接下来就是7段式SVPWM的生成了。所谓的7段式SVPWM,即在一个周期Ts内,基本电压矢量的作用顺序为

FOC

作用的时间分别为:

FOC

以在第1扇区为例:基本电压矢量作用的顺序为

FOC

对应的三相电压波形为:

FOC

这里,可能会问,Tx,Ty和U4,U6是怎么对应的呢?为什么要先U4再U6呢?把各个扇区的作用顺序竖着列出来就能看出来了:

扇区 U0 Ux Uy U7 Uy Ux U0
1 0 4 6 7 6 4 0
2 0 2 6 7 6 2 0
3 0 2 3 7 3 2 0
4 0 1 3 7 3 1 0
5 0 1 5 7 5 1 0
6 0 4 5 7 5 4 0
1 0 4 6 7 6 4 0

可以看出,从一个扇区进入相邻的另一个扇区时,只有一个基本矢量电压发生改变。即通过这样的作用顺序,可以减小开关管的切换次数,从而减少开关损耗,尤其是在负载电流较大时更应该减小开关切换次数。

然后就是根据基本矢量电压的作用时间去计算逆变H桥的占空比了,

仍然先以第1扇区为例:基本矢量电压作用的顺序为

FOC

即在一个周期Ts时间内,前面定义的开关函数

S(C)=1的时间为FOC

S(B)=1的时间为FOC

S(A)=1的时间为FOC

对应的ABC三路PWM的占空比就分别为FOC。注意的是,看上面的三相电压波形可知,输出的PWM波时高电平中间对齐,所以在对你所使用的微控制器MCU的PWM定时器进行配置的时候要注意设置好计数方向(一般先向上计数在向下计数)和输出极性(超过阈值为高电平)。

对于其他几个扇区类似,这里不再重复详细叙述,列个表出来

FOC

FOC

这里说明一下,前面进行Clarke变换和park变换的所有电压电流参数都是标幺值,这里的Uα和Uβ采用的也是标幺值。

我们合成的输出目标矢量电压也用标幺值表示(令Uref_max=1),并令Ts=1时,这里的系数K就等于常数1,这样的话,我们计算的时间Ta,Tb,Tc就等于占空比。下面简单证明一下why。

仍以第1扇区为例:

已知最终的目标矢量电压最大不失真的幅值为FOC

FOC,我们已经计算的有FOC

FOC(这里的Ux,Uy已经是标幺值)

令Uref_max=1把目标矢量电压标幺值化,再令Ts=1,就可以把非零电压作用的时间转化为标幺值。

所以,我们在程序计算处理的时候,直接令K=1,然后按照上面列表计算出来的Ta,Tb,Tc就可以直接作为占空比了,占空比再乘以PWM定时器的计数周期值,就可以得到比较寄存器的值了,这样计算量就减小很多了,然后就完成了整个SVPWM的操作。

剩下的就是PWM定时器相关的操作了,这里不详说,后面有时间我再针对DSP和STM32这两款处理器做简要介绍。

04.算法流程

接着上一篇的坐标变换(上一篇链接:https://mp.weixin.qq.com/s/4PbY2FbnXcN2ai4aolGVcg)

上篇已经介绍,由park逆变换计算得到Uα,Uβ

step1:扇区判断

计算FOC,根据U1,U2,U3的符号计算N=4C+2B+A,再结合扇区表判断所处的扇区。

C语言代码示例:

v.U1 = v.Ubeta;                                         \\
    v.U2 = ( v.Ualpha*0.8660254) - (v.Ubeta*0.5);           \\
    v.U3 = (-v.Ualpha*0.8660254) - (v.Ubeta*0.5);           \\
    v.Sector = 0;                                           \\
    if(v.U1 > 0)    v.Sector += 1;                          \\
    if(v.U2 > 0)    v.Sector += 2;                          \\
    if(v.U3 > 0)    v.Sector += 4;                          \\

step2:计算基本矢量电压作用时间(占空比)

计算FOC,并根据扇区确定相邻两个基本矢量电压及其作用时间,然后对作用时间进行等比例缩小处理或引入零矢量电压处理,使得总的作用时间等于Ts,或总的占空比等于1。

C语言代码示例:

v.Tx = v.Ubeta;                                         \\
    v.Ty = ( v.Ualpha*0.8660254) + (v.Ubeta*0.5);           \\
    v.Tz = (-v.Ualpha*0.8660254) + (v.Ubeta*0.5);           \\
    switch(v.Sector)                                        \\
    {                                                       \\
        case 1:{                                            \\
            v.t1=v.Tz; v.t2=v.Ty;                           \\
            if((v.t1+v.t2)>1){                              \\
                v.t1 = v.t1/(v.t1+v.t2);                    \\
                v.t2 = v.t2/(v.t1+v.t2);                    \\
            }                                               \\
            v.Tb = 0.5*(1-v.t1-v.t2);                       \\
            v.Ta = v.Tb + v.t1;                             \\
            v.Tc = v.Ta + v.t2;}break;                      \\
        case 2:{                                            \\
            v.t1=v.Ty; v.t2=-v.Tx;                          \\
            if((v.t1+v.t2)>1){                              \\
                v.t1 = v.t1/(v.t1+v.t2);                    \\
                v.t2 = v.t2/(v.t1+v.t2);                    \\
            }                                               \\
            v.Ta = 0.5*(1-v.t1-v.t2);                       \\
            v.Tc = v.Ta + v.t1;                             \\
            v.Tb = v.Tc + v.t2;}break;                      \\
        case 3:{                                            \\
            v.t1=-v.Tz; v.t2=v.Tx;                          \\
            if((v.t1+v.t2)>1){                              \\
                v.t1 = v.t1/(v.t1+v.t2);                    \\
                v.t2 = v.t2/(v.t1+v.t2);                    \\
            }                                               \\
            v.Ta = 0.5*(1-v.t1-v.t2);                       \\
            v.Tb = v.Ta + v.t1;                             \\
            v.Tc = v.Tb + v.t2;}break;                      \\
        case 4:{                                            \\
            v.t1=-v.Tx; v.t2=v.Tz;                          \\
            if((v.t1+v.t2)>1){                              \\
                v.t1 = v.t1/(v.t1+v.t2);                    \\
                v.t2 = v.t2/(v.t1+v.t2);                    \\
            }                                               \\
            v.Tc = 0.5*(1-v.t1-v.t2);                       \\
            v.Tb = v.Tc + v.t1;                             \\
            v.Ta = v.Tb + v.t2;}break;                      \\
        case 5:{                                            \\
            v.t1=v.Tx; v.t2=-v.Ty;                          \\
            if((v.t1+v.t2)>1){                              \\
                v.t1 = v.t1/(v.t1+v.t2);                    \\
                v.t2 = v.t2/(v.t1+v.t2);                    \\
            }                                               \\
            v.Tb = 0.5*(1-v.t1-v.t2);                       \\
            v.Tc = v.Tb + v.t1;                             \\
            v.Ta = v.Tc + v.t2;}break;                      \\
        case 6:{                                            \\
            v.t1=-v.Ty; v.t2=-v.Tz;                         \\
            if((v.t1+v.t2)>1){                              \\
                v.t1 = v.t1/(v.t1+v.t2);                    \\
                v.t2 = v.t2/(v.t1+v.t2);                    \\
            }                                               \\
            v.Tc = 0.5*(1-v.t1-v.t2);                       \\
            v.Ta = v.Tc + v.t1;                             \\
            v.Tb = v.Ta + v.t2;}break;                      \\

step3:计算PWM定时器比较寄存器值

这个很简单,就是用占空比乘以定时器的计数周期

C语言代码如下:

EPwm1Regs.CMPA.half.CMPA = (int16)(MPeriod * Svpwm1.Ta);
EPwm2Regs.CMPA.half.CMPA = (int16)(MPeriod * Svpwm1.Tb);
EPwm3Regs.CMPA.half.CMPA = (int16)(MPeriod * Svpwm1.Tc);
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分