其实写好一个程序功能框架后,可以很方便地移植到很多芯片,本帖参考我曾经发过的一篇帖子,适合于矢量控制,针对于RT1052移植可以总结为一下几个步骤: 1)替换 浮点运算头文件.h,使用ARM的math库,并添加到工程中 2)按照以下讨论的内容完成SVPWM.H和SVPWM..C的编写 3)在互补PWM程序上,实现6路互补带死区PWM的输出 4)将占空比p->Tcmpa,p->Tcmpb, p->Tcmpc赋给3路PWM,更改占空比,例如PWM2_SM3_DutySet(u8 duty) --------------------------------------------------------------------------------------------------------------------------------------------------------- SVPWM算法其实已经应用的比较广泛了,这里介绍的是两电平拓扑中使用的算法,对于三电平拓扑,需要使用三电平SVPWM,以下帖子中描述的SVPWM算法均是针对两电平的。对于SVPWM基本过程的推导,请搜索《SVPWM的原理及法则推导和控制算法详解第二修改版》,这个是介绍的比较好的文档。
1、 如果使用逆变器是驱动电机的,那么你需要考虑以下问题: 1)电压空间矢量与磁链空间矢量的关系,具体公式参见网上文档,从公式可以看出:当供电电源的压频比保持不变时,磁链幅值也保持不变,且电压空间矢量的方向为磁链圆的切线方向。当磁链矢量旋转一周时,电压矢量也旋转一周,其轨迹与磁链圆重合。对于永磁同步电机来说,我们希望磁链圆尽可能为圆形,这样可以产生恒定的电磁转矩,所以电压空间矢量来近似为圆形,从而使得磁链近似为圆形。 2)SVPWM算法的电压利用率比SPWM提高了15.47% 3)在理解完算法之后,就要把SVPWM看出一个模块,它的输入时Ualpha和Ubeta,输出为驱动三相桥式电路的占空比。 4)五段式SVPWM与七段式SVPWM,七段式SVPWM的谐波含量比五段式小,在驱动电机调速的场合对谐波要求比较高,所以选择七段式SVPWM 2、算法实现过程: 1)计算基本矢量作用时间 2)确定电压矢量所在扇区 3)根据参考电压矢量所在扇区选择基本矢量作用的时间 4)根据扇区,选择三组互补PWM的占空比 3、参考程序 1)编写SVPWM.h #ifndef SVPWM_H #define SVPWM_H #include "浮点运算头文件.h" //----------------------------------------------------------------------------- // 定义SVPWM结构体t //----------------------------------------------------------------------------- typedef struct { float Ualpha; // Input: reference alpha-axis phase voltage float Ubeta; // Input: reference beta-axis phase voltage float Vdc; // Input: DC voltage float T; // Input: PWM Modulation Period float Tcmpa; // Output: reference phase-a switching function float Tcmpb; // Output: reference phase-b switching function float Tcmpc; // Output: reference phase-c switching function void (*calc)(); // Pointer to calculation function } SVPWM_2L; //----------------------------------------------------------------------------- typedef SVPWM_2L *SVPWM_2L_handle; //----------------------------------------------------------------------------- #define SVPWM_2L_DEFAULTS {0,0,0,1.0,\ 1,1,1,\ (void (*)(Uint32))svpwm_2l_calc} //----------------------------------------------------------------------------- void svpwm_2l_calc(SVPWM_2L_handle); #endif 2)编写SVPWM.c
#include "浮点运算.h" #include <math.h> #include "SVPWM.h"
void svpwm_2l_calc(SVPWM_2L *p) { float temp; float X,Y,Z, t1,t2; Uint16 A,B,C,N,Sector; float Ta, Tb, Tc; float K=1.73205081;//sqrt(3)/2 //1、计算基本时间变量 X= K*p->Ubeta/p->Vdc*p->T; Y=(K*p->Ubeta+3*p->Ualpha)/(2*p->Vdc)*p->T; Z=(K*p->Ubeta-3*p->Ualpha)/(2*p->Vdc)*p->T; //2、扇区判别 if(p->Ubeta>0) {A=1;} else {A=0;} if( (K*p->Ualpha - p->Ubeta)>0 ) {B=1;} else {B=0;} if((-K*p->Ualpha - p->Ubeta)>0) {C=1;} else {C=0;} N=A+2*B+4*C; switch(N) { case 1:{Sector=2;break;} case 2:{Sector=6;break;} case 3:{Sector=1;break;} case 4:{Sector=4;break;} case 5:{Sector=3;break;} case 6:{Sector=5;break;} default:{;} } //根据参考电压矢量所在扇区选择基本矢量作用的时间 switch(Sector) { case 1: {t1=-Z; t2= X;break;} case 2: {t1= Z; t2= Y;break;} case 3: {t1= X; t2=-Y;break;} case 4: {t1=-X; t2= Z;break;} case 5: {t1=-Y; t2=-Z;break;} case 6: {t1= Y; t2=-X;break;} default:{;} } if((t1+t2)>p->T)//对过调制情况进行调整 { temp=t1+t2; t1=t1*p->T/temp; t2=t2*p->T/temp; } Ta=(p->T-t1-t2)/4;//作用时间分配 Tb=Ta+t1/2; Tc=Tb+t2/2; //计算占空比 switch(Sector) { case 1: {p->Tcmpa=Ta; p->Tcmpb=Tb; p->Tcmpc=Tc; break;} case 2: {p->Tcmpa=Tb; p->Tcmpb=Ta; p->Tcmpc=Tc; break;} case 3: {p->Tcmpa=Tc; p->Tcmpb=Ta; p->Tcmpc=Tb; break;} case 4: {p->Tcmpa=Tc; p->Tcmpb=Tb; p->Tcmpc=Ta; break;} case 5: {p->Tcmpa=Tb; p->Tcmpb=Tc; p->Tcmpc=Ta; break;} case 6: {p->Tcmpa=Ta; p->Tcmpb=Tc; p->Tcmpc=Tb; break;} default:{;} } } 4、实验波形如下,左图2通道是处理器直接输出的波形,经过RC滤波之后的波形如1通道所示,右图是三相SVPWM波形图,为什么会是这样,是因为引入了三次谐波,所以不是正弦波,而是马鞍波
|