转】svpwm 的 MATLAB 仿真实现为了能让大家在已经泛滥的知识上少走弯路,本人把自己在 SVPWM 上的认识与看到此贴的读者们一起分享,废话少说,切入正题:在看下面内容之前,您应该至少对 SVPWM 的原理有大致的了解,如果不了解也没关系,你只要按照我交给你的步骤来做,也可以轻而易举的跨过 SVPWM 这道坎,在仿真之前您必须安装 MATLAB7.0 或以上版本,必须确保simpowersysm 工具箱已被安装,如果以上要求已经达到,那么就可以执行以下步骤了:步骤 1:打开 matlab 主界面,然后在 command window 界面中的“>>”旁边输入simulink,打开 simulink 开发环境后新建一个 mdl 文件,在 simulink 下拉菜单中的ports&subsystems 中找到 subsystem 模块,用其建立一个如图 1 的总的模块,这个模块有两个输入口,一个输出口(实际上包含六路 PWM 信号),接来的东西都将在这个模块中添加,输入输出模块的名称可以在双击模块后自己更改,其中 Vahar,Vbetar 是需要输出的电压在两相静止坐标系下的两个分量,输出是控制逆变器六个 IGBT 的 pwm 脉冲信号。
图 1也许有人会问,输入参数不是还包括直流电压和功率开关频率吗?别急,下面接着让您看到上述模块的内部情况步骤 2:根据图 2,添加 subsystem 的内核模块,里面用到的模块有以下几种:in,out,mux,demux,repeating sequence,rational operator,logical operator 和里面的主角 S-Function builder 模块图 2可以看到输入有四个参数 Vapha,Vbeta,Tz,Vdc,输出为六路 PWM 信号,这个仿真模块没考虑死区的问题;取 Tz 为 1/(1e+4)这就是说开个频率是 10kHz,Vdc 为 500,这两个参数要根据实际情况自己设置,这里是我任意设的,repeating sequence 的设置如图 3 所示,这样设的目的是想产生一个周期为 Tz,峰值为 Tz/2 的等腰直角三角形调制波,接下来设置两个比较模块和取反模块,比较模块是大于等于关系,各模块的其他参数,我没说的就当默认设置,细心的读者会在图 4 中的第一幅图中看到仿真时间设为 Ts,这是我设的系统仿真步长,这里就用默认值-1,此外比较模块和取反模块的信号属性 signal atrributes 均应设为Boolean 格式。
图 3图 4步骤 3:设置 s-builder 模块,这个设置也很简单,但是看起来有点多,图 2 中的 svpwm模块就是用 simulink 中的 s-function builder 建立的,只是名字改成 svpwm 罢了,有图2 可以看出 svpwm 产生的三个时间比较值与 repeating sequence 产生的等腰三角波进行比较,从而产生想要的六路 PWM 波,svpwm 的核心算法是使用 C 语言编写的,下面详细介绍该模块的设置,s-fanction builder 的界面如下图:图 5在 s-function name 中输入 svpwm,如果你把我下面说的设置完后,再按一下 s-function name 旁边的 build,接着就会在 matlab 的显示路径文件夹中(如“我的文档/matlab”)产生几个格式各异的以 svpwm 开头的文件,如 svpwm.c,svpwm.tlc 等,不过这是后话,先说说设置,在 initialization 中的各参数均设为 0,sample mode 设为 inherited,如图 5 所示,这些都是默认值,也是说可以不用管它就可以了,在 data properties 中设:图 6port name 为 u (默认是 u0),行数 row 为 4(因为有四个输入参数),其他选用默认值,如图 6 所示,设 output ports 的输出 port name 为 y(原来为 y0),行数 rows 为3(因为有三个输出),其他参数默认,剩下的两个 parameters 和 data type attributes均采用默认值;在 libraries 中全部使用默认值;接下来要改的就是 outputs 中的内容,也是实现 SVPWM 的核心算法,必须注意要必须勾选 inputs are needed in the output function(direct feedthrough),这句话的意思是:输出结果直接用到了输入数据,比如y=u+1,将下面给出的 C 语言程序复制到空白处,如图 7 所示:图 7/*u[4]={vaphar,vbetar,Tz,Vdc}*/int A,B,C,N;double X,Y,Z,Tx,Ty,T0,Tl,Tm,Th;if (u[1]>0) A = 1;else A=0;if ((1.732051*u[0]-u[1])>0) B = 1;else B=0;if ((-1.732051*u[0]-u[1])>0) C = 1;else C=0;N=A+2*B+4*C;X=1.732051*u[1]*u[2]/u[3];Y=(0.8660*u[1]+1.5*u[0])*u[2]/u[3];Z=(-0.8660*u[1]+1.5*u[0])*u[2]/u[3];switch (N){case 1: Tx= Y;Ty=-Z;break;case 2: Tx=-X;Ty= Y;break;case 3: Tx= Z;Ty= X;break;case 4: Tx=-Z;Ty=-X;break;case 5: Tx= X;Ty=-Y;break;default: Tx=-Y;Ty= Z;}if ((Tx+Ty)>u[2]){Tx=Tx*u[2]/(Tx+Ty);Ty=Ty*u[2]/(Tx+Ty);}T0=(u[2]-(Tx+Ty))/4;Tl=(u[2]+Tx-Ty)/4;/*Tl=T0/4+Tx/2*/Tm=(u[2]-Tx+Ty)/4;/*Tm=T0/4+Ty/2*/Th=(u[2]+Tx+Ty)/4;/*Th=T0/4+Ty/2+Ty/2*/switch (N){case 1 :y[0]=Tm;y[1]=T0;y[2]=Th;break;case 2 :y[0]=T0;y[1]=Th;y[2]=Tm;break;case 3 :y[0]=T0;y[1]=Tl;y[2]=Th;break;case 4 :y[0]=Th;y[1]=Tm;y[2]=T0;break;case 5 :y[0]=Th;y[1]=T0;y[2]=Tl;break;default :y[0]=Tl;y[1]=Th;y[2]=T0;}接下来的两个 continuous derivatives 和 discrete update 都不用改,使用默认值,这两个只有在有导数时才会用到,最后一个在 build info 中勾选 show comlile steps(在build 时会显示编译过程)、create a debugged mex-file 和 generate wrapper tlc(这个我也不知道干什么用的)。
这下所有的细节设置都结束了,步骤 4:设置仿真参数,回到 mdl 主界面,选择菜单栏中的 simulation/configurate parameters,里面的仿真时间可以根据实际情况自己定,在 sover options 中,type 建议选 fixed-step,fixed step size 应本人设为 5e-6,这个参数是仿真时最小的步长,这个参数必须比开关周期 Tz 小,否则无法仿真,其他参数都不用管它,要想知道这些参数是什么意思,就多看看 matlab 中的 help,里面都有详细说明步骤 5 是安装 lcc,在 matlab 的 command window 中输入 mex -setup,然后按照提示将 LCC 安装上,安装完毕的提示是 done接下来你就可以做跟你有用有关的事了,把 SVPWM 当做一个模块了使用步骤 6:打开 s-function builder,单击一下里面的 build,接着您就可以看到编译过程,如果看到 success,那就说明您已经成功了编译完后关闭 s-function builder,接下来做你的系统仿真吧,只要您的 svpwm 模块和编译出来的 svpwm.c 放在一个文件夹中,以后仿真就不用再点 build 了。
很简单吧,其实 SVPWM 的仿真没什么难的!需要提醒同志们的是,在仿真之前必须build 一下 s-function builder,不然无法运行模块,采用 s-builder 的原因是建成的模块很简洁,而且运行速度要比其他方法快的多,接下来同志们该去自己试一下了!。