DSP

PMSM控制01-在MATLAB/sinmulink仿真实现-计时器比较法输出SVPWM波形

2019-07-13 16:40发布


由于本人转入新能源汽车电机控制行业,因此日后会陆续更新汽车电机、控制器、控制算法、电路等的文章。当然别的DIY文章也会继续更,工作、兴趣、生活,该有的都得有。
以下正文:
simulink中实现计时器比较法输出SVPWM控制波形:
计时器比较法是控制中常用的算法,在DSP中基本都使用此算法输出SVPWM,因为与硬件原理相适用,这也是为后续在硬件上实现DSP控制做铺垫。


scope2显示的输出波形:

clock模块用于给定系统输入时间,根据系统时间产生正弦余弦波形:



clock输出的即是一个计时累加的信号,最终值等于simulink仿真时间。 双击matlab function,弹出界面进行如下配置,模块输出的是一个复数。带i的为虚部。 输入参数即是一个实部虚部之间相位差pi/2的复数,至于为何三角函数内乘100,因为输入参数u与仿真时间相关,u为0-0.01的递增值,乘100保证相位为0~pi,起码有半个周期的输入,是修正数量级用的参数。

complex to Magnitude-Angle模块分解复数,为幅值和角度: 该模块专用于分解复数,复数的英文即complex。

再下一步,将产生的幅值和角度输入S-function模块: S-function是simulink中供用户调用自定义脚本函数的模块: 自定义的m文件,下面对m文件代码进行分析: 对输入的连续电压矢量进行离散化:
function[sys,x0,str,ts] = SVPW_TimeCounterCompare003(t,x,u,flag) tsam = 0.02/20; switchflag,    case 0         [sys,x0,str,ts] = Initialization(tsam);    case 3         sys = mdlOutputs(t,x,u);    case {1,2,4,9}         sys = [];    otherwise         error(['Unhandled flag=',num2str(flag)]); end function[sys,x0,str,ts] = Initialization(tsam) sizes = simsizes;%simsizes用于设置Sfunction参数状态 sizes.NumContStates = 0; sizes.NumDiscStates = 0; sizes.NumOutputs = 2; sizes.NumInputs = 2; sizes.DirFeedthrough = 1; sizes.NumSampleTimes = 1;%采样时间 sys = simsizes(sizes); x0 = []; str = []; ts = [tsam 0 ]; functionsys = mdlOutputs(t,x,u) sys = [u(1),u(2)];


下一步是进入包含核心计算公式的代码:


第二个matlab dunction模块配置: 直接调用m文件。

左边输入4个信号5个量,第一个是上一步分解的幅度角度两个值组成的一维数组,第二个输入是采样频率第三个是直流电压值,第四个为比较用的三角波: 这些量作为输入量,MATLAB Function模块调用的代码:
  functiony = SVPWM_TimeCounterCompare(u)   Ve = u(1); Ph = u(2); te = u(3); Udc = u(4); du = pi/3; %定义每个矢量开关信号 u0 = [0 0 0]; u1 = [1 0 0]; u2 = [1 1 0]; u3 = [0 1 0]; u4 = [0 1 1]; u5 = [0 0 1]; u6 = [1 0 1]; u7 = [1 1 1]; %判断矢量所处的扇区,选择对应的ua,ub,phe,根据所在扇区选择合成的所需的一组矢量
ifPh>0 && Ph<=du     Phe = Ph;     h = 1;     ua = u1;     ub = u2; elseifPh>du && Ph<=2*du     Phe=2*du-Ph;     h = 2;     ua = u3;     ub = u2; elseifPh>2*du && Ph<=3*du     Phe = Ph-2*du;     h = 3;     ua = u3;     ub = u4; elseifPh>-3*du && Ph<=-2*du     Phe = -Ph-2*du;     h = 4;     ua = u5;     ub = u4; elseifPh>-2*du && Ph<=-du     Phe = Ph+2*du;     h = 5;     ua = u5;     ub = u6; else     Phe = -Ph;     h = 6;     ua = u1;     ub = u6; end %计算ta,tb,t0(ms) A = Udc; ta = 1.5*(cos(Phe)-1/sqrt(3)*sin(Phe))*Ve*te/A; tb = sqrt(3)*Ve*sin(Phe)*te/A; t0 = te-ta-tb; ift0<0     ta = ta/(ta/tb)*te;     tb = te-ta; end %时间折算成电压值 usw1 = Udc*t0/te/2; usw2 = Udc*ta/te+usw1; usw3 = Udc*tb/te+usw2; %判断并输出 %u(5)即为输入的三角波值 ifu(5)>=0 && u(5)     y = u0;%中值电压 elseifu(5)>=usw1 && u(5)     y = ua; elseifu(5)>=usw2 && u(5)     y = ub; elsey = u7;%中值电压 end 代码的具体算法公式等为计时器比较法输出的原理及电压矢量叠加的理论推导公式,不在仿真的范畴,因此在此不做公式推导之类的赘述,有兴趣可以查阅SVPWM波形原理,一般书都会详细叙述上述公式的推导过程,半小时便能理解。

另外说明一下几个模块的配置: 此为三角波发生模块,三角波模块在SVPWM发生中用作比较作用,(与调制信号比较,这个模型的调制信号就是第一个matlab function模块产生的复数信号转换成的相位幅度信号,实际就是正余弦波) 配置如下:
最终在scope2可以看到,模型输出为:
然后,再把SVPWM信号连接到逆变器上,输出正弦波: 整体模型如下: 这一块为模拟逆变器用,switch参数如下: 具体配置原理是,由于SVPWM控制信号发生侧输出的是数字信号,switch的逻辑关系设置为:若输入信号大于0.5,则输出200,小于0.5,则输出-200.由三个switch模块组成三路输出。
这是模拟真实逆变器的仿真图(只作为说明,此模型中不用到):
这是真实逆变器的原理图: 逆变器的原理即是数字控制信号通过控制6个IGBT的关断,控制UVW三相输出状态:正,反,关断,可直接用三个switch开关模拟,效果相同,实际的逆变器还需要考虑到死区时间、导通周期等问题,需要考虑的问题篇幅过大,在此不做赘述,逆变器部分再详解。在此只为验证计时器比较法的SVPWM输出的正确性:
下面为输出观测模块:
傅里叶模块输出的波形: 这里傅里叶模块用于观测幅值,可以看到幅值在起动的短时间内相电压可以达到理论值148.8并保持稳定,接近150V输入。
可观测到,scope6的显示为:
scope6前有4个低通滤波器,过滤谐波用,从上到下低通滤波器的作用分别为:只通过基波、过滤掉3次谐波以上的谐波、过滤5次谐波以上的谐波、过滤7次谐波以上的谐波,滤波器在软硬件设计中都是一门大学问,在此亦暂不做赘述。 低通滤波器配置: 说明一下,下图是保留基波的配置,若要过滤3次谐波以上的谐波,只需修改成314*3即可。5次7次同理。

从逆变器输出波形可以看出: 一、滤波后,基波已经可以输出较标准的正弦波形。 二、3次谐波的含量较高。 三、波形在一个周期后即达到理想状态。(实际中由于EMC、气隙磁场畸变等原因不会这么理想) 可以看出此SVPWM算法是正确可行的。
注: 1.SVPWM只是电机控制中很基础的一环,控制信号、反馈、park、clark变换等等软件处理在实际应用中均有难度,特别是滤波,电磁兼容的问题,足够想到脱发。因此只在matlab上做个仿真,输输波形跑跑电机是非常轻松愉悦的事。 2.实际要在simulink中搭建更接近真实控制电路控制流程的模型还缺几个模块,会在后续补充,这里只说明SVPWM的生成。 3.目前主流的还是FOC和DTC一类的控制算法,以及无传感器控制的均会陆续更新。 4.CSDN的编辑器很不人性化,后续可能直接分享我的印象笔记,排版实在费时。 5.相关模型文件我已经上传到CSDN,可下载。