本帖最后由 瓜弟 于 2019-12-27 19:18 编辑
本贴主要介绍SVPWM的实现与仿真分析。
在电机控制中,我们希望使用一个特定的空间磁场向量,来“拉”动转子,SVPWM技术使我们可以得到一个相对圆滑的旋转磁场向量。
在I区,由基本向量合成目标向量如下图所示:
为PWM的周期,
、
分别为两个基础向量的作用时间,根据正弦定理可得:

其中,
,
为目标向量的幅值,
为目标向量与基础向量的夹角,将上式化简后,得到:


在八个基础向量中,还有两个零向量,合理分配两个零向量,使MOS桥上下桥臂负载均衡:

通过以上推导,我们得到基本的占空比信号,但这并不能直接用于PWM信号生成,如下图所示,
在我们得到各个占空比后,在生成PWM时,我们需要关注这四个占空比信号与逆变桥的的PWM信号之间的关系,则:
逆变桥A相上半桥的占空比信号为
逆变桥B相上半桥的占空比信号为
逆变桥C相上半桥的占空比信号为
通过上述推导,我们得到了空间向量的模、角度与逆变器的PWM之间的关系,下面则是代码实现:
- #include "SVPWM_generator.h"
- #include "math.h"
-
-
- #ifdef _USE_SIMULINK
- long int Timer;
- #endif
-
- float PWM_Table[6];
-
-
-
- void SVPWM_generator(float TargetPhaseAngle, float TargetPhaseMoldRate)
- {
- float t1,t2;
- #ifdef _USE_SIMULINK
- Timer ++;
- if(Timer >= _SIMULIN_DIVIDE_COUNTER_THREHOLD)
- {
- Timer = 0;
- #endif
-
- if(( TargetPhaseAngle>=0 )&&(TargetPhaseAngle < 60))
- {
- TargetPhaseAngle = TargetPhaseAngle - 0;
- t1 = 1.732 * TargetPhaseMoldRate * sin((60-TargetPhaseAngle)*PI/180);
- t2 = 1.732 * TargetPhaseMoldRate * sin(TargetPhaseAngle*PI/180);
- PWM_Table[0] = (1+t1+t2)/2;
- PWM_Table[2] = (1-t1+t2)/2;
- PWM_Table[4] = (1-t1-t2)/2;
- }
- else if(( TargetPhaseAngle>=60 )&&(TargetPhaseAngle < 120))
- {
- TargetPhaseAngle = TargetPhaseAngle - 60;
- t1 = 1.732 * TargetPhaseMoldRate * sin((60-TargetPhaseAngle)*PI/180);
- t2 = 1.732 * TargetPhaseMoldRate * sin(TargetPhaseAngle*PI/180);
- PWM_Table[0] = (1+t1-t2)/2;
- PWM_Table[2] = (1+t1+t2)/2;
- PWM_Table[4] = (1-t1-t2)/2;
- }
- else if(( TargetPhaseAngle>=120 )&&(TargetPhaseAngle < 180))
- {
- TargetPhaseAngle = TargetPhaseAngle - 120;
- t1 = 1.732 * TargetPhaseMoldRate * sin((60-TargetPhaseAngle)*PI/180);
- t2 = 1.732 * TargetPhaseMoldRate * sin(TargetPhaseAngle*PI/180);
- PWM_Table[0] = (1-t1-t2)/2;
- PWM_Table[2] = (1+t1+t2)/2;
- PWM_Table[4] = (1-t1+t2)/2;
- }
- else if(( TargetPhaseAngle>=180 )&&(TargetPhaseAngle < 240))
- {
- TargetPhaseAngle = TargetPhaseAngle - 180;
- t1 = 1.732 * TargetPhaseMoldRate * sin((60-TargetPhaseAngle)*PI/180);
- t2 = 1.732 * TargetPhaseMoldRate * sin(TargetPhaseAngle*PI/180);
- PWM_Table[0] = (1-t1-t2)/2;
- PWM_Table[2] = (1+t1-t2)/2;
- PWM_Table[4] = (1+t1+t2)/2;
- }
- else if(( TargetPhaseAngle>=240 )&&(TargetPhaseAngle < 300))
- {
- TargetPhaseAngle = TargetPhaseAngle - 240;
- t1 = 1.732 * TargetPhaseMoldRate * sin((60-TargetPhaseAngle)*PI/180);
- t2 = 1.732 * TargetPhaseMoldRate * sin(TargetPhaseAngle*PI/180);
- PWM_Table[0] = (1-t1+t2)/2;
- PWM_Table[2] = (1-t1-t2)/2;
- PWM_Table[4] = (1+t1+t2)/2;
- }
- else if(( TargetPhaseAngle>=300 )&&(TargetPhaseAngle < 360))
- {
- TargetPhaseAngle = TargetPhaseAngle - 300;
- t1 = 1.732 * TargetPhaseMoldRate * sin((60-TargetPhaseAngle)*PI/180);
- t2 = 1.732 * TargetPhaseMoldRate * sin(TargetPhaseAngle*PI/180);
- PWM_Table[0] = (1+t1+t2)/2;
- PWM_Table[2] = (1-t1-t2)/2;
- PWM_Table[4] = (1+t1-t2)/2;
- }
-
- PWM_Table[0] = (PWM_Table[0] >= 0)? PWM_Table[0] : 0;
- PWM_Table[2] = (PWM_Table[2] >= 0)? PWM_Table[2] : 0;
- PWM_Table[4] = (PWM_Table[4] >= 0)? PWM_Table[4] : 0;
-
- PWM_Table[0] = (PWM_Table[0] <= 1)? PWM_Table[0] : 1;
- PWM_Table[2] = (PWM_Table[2] <= 1)? PWM_Table[2] : 1;
- PWM_Table[4] = (PWM_Table[4] <= 1)? PWM_Table[4] : 1;
-
- #ifdef _USE_SIMULINK
- }
- #endif
-
- }
在SVPWM_generator.h文件中,主要定义了仿真步长、频率等参数,如下:
- #ifndef __SVPWM_GENERATOR_H
- #define __SVPWM_GENERATOR_H
-
- #define _USE_SIMULINK
-
- #ifdef _USE_SIMULINK
- #define _SIMULIN_FREQUENCE 1000000
- #define _SIMULIN_SVPWM_CALCULATE_FREQUENCE 10000
- #define _SIMULIN_DIVIDE_COUNTER_THREHOLD (_SIMULIN_FREQUENCE / _SIMULIN_SVPWM_CALCULATE_FREQUENCE)
- #endif
-
- #define PI 3.1415926
-
- extern float PWM_Table[6];
- void SVPWM_generator(float TargetPhaseAngle, float TargetPhaseMoldRate);
-
- #endif
在 SVPWM_generator(float TargetPhaseAngle, float TargetPhaseMoldRate) 中,TargetPhaseAngle为目标向量的相对于A相坐标轴的角度,单位为°, TargetPhaseMoldRate为目标向量的幅值与直流母线的电压的比值,根据SVPWM可知,当TargetPhaseMoldRate <
时,即目标向量的轨迹圆内切于六个基本向量所组成的正六边形,合成矢量的调制为线性调制。
利用Simulink下的S-Function可以实现对以C语言实现的算法进行仿真分析,仿真框图如下图所示:
逆变桥与负载、测量
SVPWM、PWM信号生成
在由SVPWM信号生成PWM信号过程中,需要注意:三项逆变桥的六个PWM波必须是中心对称的。
如何验证算法的正确?SVPWM的目标是生成一个在空间中匀速旋转的矢量,我们可将SVPWM信号进行ABC坐标系到Alpha-Beta坐标系的转换,并用x-y示波器显示出来,检查目标向量轨迹是否为圆。同理,我们也可以将逆变桥的输出电压进行上述变换,检查其输出向量的轨迹。
当TargetPhaseMoldRate =
时,仿真图形如下:
1、SVPWM输出的马鞍波:
2、SVPWM的输出经过坐标变换得到的圆:
3、逆变桥的输出电压波形
4、逆变桥的输出的电压经过坐标变换得到的目标向量轨迹:
此内容由EEWORLD论坛网友瓜弟原创,如需转载或用于商业用途需征得作者同意并注明出处
author:nblianyan@qq.com