本文是通过软件编程实现SVPWM算法,并将各扇区有效矢量T1,T2,和T0+T7无效矢量作用时间通过DAC转换输出马鞍波,可以更加深刻理解SVPWM算法的实现过程(基于GD32E508芯片)。
1.实现步骤
SVPWM波基波频率设定f为1Hz,旋转实时角度为23.141*t 时间t的步长为0.001,即每隔1ms更新一次旋转角度,1s为一个周期,一个周期1000个采样点
1、移植arm自带DSP库,使能FPU运算;
2、通过给定旋转坐标系直流电压Vd、Vq通过park逆变换得到正交的两相交流正弦电压Ua、Ub;
3、判断Ua、Ub大小判断扇区1/2/3/4/5/6,计算各扇区有效矢量T1,T2 ,无效矢量T0,T7作用时间。
4、各扇区有效矢量T1,T2,无效矢量T0,T7(实则为三相逆变电路三对mos管各下管导通时间,T1+T2+T0+T7的和为SVPWM三角波载波的周期T)。
5、将T1,T2,T0+T7通过DAC转换输出SVPWM马鞍波形(基波和三次谐波的叠加)。
2.软件C代码
2.1 .h文件
#ifndef MAIN_H
#define MAIN_H
#include "gd32e50x.h"
#include "arm_math.h"
/*--------转子磁通两相旋转坐标系----------*/
typedef struct{
float Vd;
float Vq;
}voltage_two_phase_rotation;
/*--------定子两相静止坐标系----------*/
typedef struct{
float Va1;
float Vb1;
}voltage_two_static_rotation;
/*--------定子三相静止坐标系----------*/
typedef struct{
float Ta;
float Tb;
float Tc;
}svpwm_three_timer;
typedef struct{
float X;
float Y;
float Z;
uint8_t sector_num;
}svpwm_variable;
/*--------定义各扇区有效矢量T1/T2结构体----------*/
typedef struct{
float T1;
float T2;
}svpwm_vector_timer;
#endif /* MAIN_H */
2.2 .c文件
#include "systick.h"
#include "stdio.h"
#include "main.h"
#include "gd32e507z_eval.h"
#define pi 3.142562
svpwm_three_timer v3_three;
uint16_t dac_convert[3]={0};
svpwm_vector_timer v2_timer;
/* park逆变换得到正交的两相交流正弦电压 */
voltage_two_static_rotation voltage_park_inverse(voltage_two_phase_rotation* vi, float angle)
{
voltage_two_static_rotation v1;
v1.Va1 = 0.00;
v1.Vb1 = 0.00;
v1.Va1 = vi->Vq * arm_cos_f32(angle) + vi->Vd * arm_sin_f32(angle);
v1.Vb1 = -vi->Vq * arm_sin_f32(angle) + vi->Vd * arm_cos_f32(angle);
return v1;
}
/* 扇区判断 */
svpwm_variable sector_judge(voltage_two_static_rotation* vi)
{
uint8_t count = 0,a = 0,b = 0,c = 0;
svpwm_variable qt;
qt.X = 0.00;
qt.Y = 0.00;
qt.Z = 0.00;
/* 实际应用中X/Y/Z需要再除以三相逆变器直流侧母线电压值Udc 这里取载波和基波的频率为1:1*/
// qt.X = sqrtf(3.00) * 1 * vi->Vb1;
// qt.Y = sqrtf(3.00) * 1 *(-vi->Vb1 + sqrtf(3.00) * vi->Va1)/2;
// qt.Z = sqrtf(3.00) * 1 * -(vi->Vb1 + sqrtf(3.00)* vi->Va1)/2;
qt.X = vi->Vb1;
qt.Y = (-vi->Vb1 + sqrtf(3.00) * vi->Va1)/2;
qt.Z = -(vi->Vb1 + sqrtf(3.00)* vi->Va1)/2;
if(qt.X > 0.00){
a = 1;
}
if(qt.Y > 0.00){
b = 1;
}
if(qt.Z > 0){
c = 1;
}
count = a + 2 * b + 4 * c;
switch(count){
case 3:
qt.sector_num = 1;
break;
case 1:
qt.sector_num = 2;
break;
case 5:
qt.sector_num = 3;
break;
case 4:
qt.sector_num = 4;
break;
case 6:
qt.sector_num = 5;
break;
case 2:
qt.sector_num = 6;
break;
default:
break;
}
return qt;
}
/*----各扇区矢量作用时间T1,T2计算----*/
svpwm_vector_timer timer_vector_output(svpwm_variable* v1)
{
float T1,T2;
svpwm_vector_timer v2;
switch(v1->sector_num){
case 1:
v2.T1 = v1->Y;
v2.T2 = v1->X;
break;
case 2:
v2.T1 = -v1->Y;
v2.T2 = -v1->Z;
break;
case 3:
v2.T1 = v1->X;
v2.T2 = v1->Z;
break;
case 4:
v2.T1 = -v1->X;
v2.T2 = -v1->Y;
break;
case 5:
v2.T1 = v1->Z;
v2.T2 = v1->Y;
break;
case 6:
v2.T1 = -v1->Z;
v2.T2 = -v1->X;
break;
}
return v2;
}
/*------三相逆变器三对mos管各下管Ta/Tb/Tc作用时间 Ta+Tb+Tc的和为SVPWM三角波载波的周期T------*/
svpwm_three_timer three_phase_timer_output(svpwm_vector_timer* vt,svpwm_variable* vi)
{
svpwm_three_timer v1;
float temp,value1,value2,value3;
temp = vt->T1 + vt->T2;
//设定SVPWM载波频率为1,即调制波与载波的频率比为1:1,在实际应用中载波频率要远大于调制波频率。
value1 = (1 - vt->T1 - vt->T2)/4.0;
value2 = value1 + vt->T1/2.0;
value3 = value2 + vt->T2/2.0;
switch(vi->sector_num){
case 1:
v1.Ta = value1;
v1.Tb = value2;
v1.Tc = value3;
break;
case 2:
v1.Ta = value2;
v1.Tb = value1;
v1.Tc = value3;
break;
case 3:
v1.Ta = value3;
v1.Tb = value1;
v1.Tc = value2;
break;
case 4:
v1.Ta = value3;
v1.Tb = value2;
v1.Tc = value1;
break;
case 5:
v1.Ta = value2;
v1.Tb = value3;
v1.Tc = value1;
break;
case 6:
v1.Ta = value1;
v1.Tb = value3;
v1.Tc = value2;
break;
}
return v1;
}
//dac 初始化配置
void dac_init(void)
{
/* enable the clock of peripherals */
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_DAC0);
rcu_periph_clock_enable(RCU_DAC1);
gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6);//DAC转换通过PA4/PA5/PA6输出
dac_deinit(DAC0);
//dac0 ch0
dac_trigger_source_config(DAC0,DAC_OUT_0, DAC_TRIGGER_SOFTWARE);
dac_trigger_enable(DAC0,DAC_OUT_0);
dac_ddisc_config(DAC0,DAC_OUT_0,DAC_direct_connect_gpio);
dac_output_buffer_enable(DAC0,DAC_OUT_0);
dac_enable(DAC0,DAC_OUT_0);
//dac0 ch1
dac_trigger_source_config(DAC0,DAC_OUT_1, DAC_TRIGGER_SOFTWARE);
dac_trigger_enable(DAC0,DAC_OUT_1);
dac_ddisc_config(DAC0,DAC_OUT_1,DAC_direct_connect_gpio);
dac_output_buffer_enable(DAC0,DAC_OUT_1);
dac_enable(DAC0,DAC_OUT_1);
//dac1 ch0
dac_deinit(DAC1);
dac_trigger_source_config(DAC1,DAC_OUT_0, DAC_TRIGGER_SOFTWARE);
dac_trigger_enable(DAC1,DAC_OUT_0);
dac_ddisc_config(DAC1,DAC_OUT_0,DAC_direct_connect_gpio);
dac_output_buffer_enable(DAC1,DAC_OUT_0);
dac_enable(DAC1,DAC_OUT_0);
}
/*!
\brief main function
\param[in] none
\param[out] none
\retval none
*/
int main(void)
{
uint16_t num = 0;
float angle = 0.00;
float timer = 0.001;
voltage_two_phase_rotation v1_two;
voltage_two_static_rotation v2_two;
svpwm_variable v4_variable;
v1_two.Vd = 0.00;//设定旋转坐标系的d轴分量为0,实际电机控制算法通过闭环使d轴分量为0,以获得最大转矩。
v1_two.Vq = 1.00;//设定旋转坐标系的q轴分量为1
systick_config();
dac_init();
while(1){
if(timer >= 1.00){
timer = 0.001;//1s转一圈,采样1000个点,每隔1ms采样一次
}
angle = 2 * pi * timer;//根据时间得到旋转角度
v2_two = voltage_park_inverse(&v1_two,angle);//park逆变换得到正交的两相交流正弦电压
v4_variable = sector_judge(&v2_two);//算法判断当前所处的扇区数
v2_timer = timer_vector_output(&v4_variable);//计算各扇区有效矢量T1,T2作用时间
v3_three = three_phase_timer_output(&v2_timer,&v4_variable);//不同扇区,三相逆变器三对mos管各下管Ta/Tb/Tc作用时间
//三对mos管各下管Ta/Tb/Tc作用时间通过三路DAC转换输出,调制波和载波频率设成一致的目的也是方便DAC转换输出示波器观察,如果载波频率过大,
//DAC转换输出的值很小,不利于示波器观察。
dac_convert[0] =(uint16_t)(((v3_three.Ta + 0.0) * 4096)/3.30);
dac_convert[1] =(uint16_t)(((v3_three.Tb + 0.0)* 4096)/3.30);
dac_convert[2] =(uint16_t)(((v3_three.Tc + 0.0)* 4096)/3.30);
OUT0_R12DH(DAC0) = dac_convert[0];
OUT1_R12DH(DAC0) = dac_convert[1];
OUT0_R12DH(DAC1) = dac_convert[2];
DAC_SWT(DAC0) |= DAC_SWT_SWTR0;
DAC_SWT(DAC0) |= DAC_SWT_SWTR1;
DAC_SWT(DAC1) |= DAC_SWT_SWTR0;
timer += 0.001;
delay_1ms(1);
}
}
3.实验结果
示波器抓取三路DAC输出马鞍波波形,SVPWM基波为1hz:
示波器抓取三路DAC输出马鞍波波形,SVPWM三次谐波为3hz:
Matlab仿真SVPWM马鞍波输出波形:
Matlab仿真输出面积等效PWM波经电机感性负责滤除高次谐波分量输出三相正弦交流ia,ib,ic:
4.总结
各扇区T1,T2,T0+T7在实际应用编程中是给到timer定时器中心对齐模式输出三路互补PWM波的比较值CH1VAL,CH2VAL,CH3VAL,svpwm即为调制波,timer定时器PWM中心对齐模式的三角波即为载波,输出三路互补pwm波作用于三相逆变电路三对mos管可输出和SVPWM面积等效的PWM波(+Ud,0 ,-Ud),Ud为三相逆变电路直流侧电压,再作用于电机,因为电机是感性负载,等效电感L可将PWM波中的高次谐波分量滤除,只剩基波分量,输出相位差为120度的三相交流正弦电流ia,ib,ic。
实际电机应用中,马鞍波只能通过matlab仿真看到,示波器使能抓取三对mos管的pwm开关波形或者经三相全桥逆变电路输出的含有高次谐波、面积等效三相交流正弦波的pwm波形。