概述
MATLAB s-function 的功能强大,而且支持多重语言编写。今天,就一个小题目来写一下使用m语言编写 s-funtion 的心得与总结。题目是:使用s-function编写buck-boost的电路模型(连续)
第一步:我们要建立buck-boost的模型。使用状态空间平均法,就可以很简单的建立buck-boost的数学模型,数学模型是:
第二步:编写S函数。
我们首先需要打开s函数模板。在命令行输入:
open('sfuntmpl.m')
模板中主要语句有:
function [sys,x0,str,ts,simStateCompliance] = bc(t,x,u,flag,C,L,R,D)
函数名:bc(自己取个名字)
输入参数:t x u flag C L R D ,其中输入参数的C L R D是我们后添加的。你在函数中需要什么参数,直接添加即可。
switch flag,
case 0,
[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;
case 1,
sys=mdlDerivatives(t,x,u,C,L,R,D); //mdlDerivatives这个函数需要调用C L R D 这些参数,所以我们给它加上。这个函数 是自己编写的,看情况是否要加参数。其实,如果你压根就不用到这个函数,你可以把所有参数都删掉,包括自带的t,x,u,flag因为我们没有使用到他们。这个函数的作用是求微分方程,在连续模式下使用。
case 2,
sys=mdlUpdate(t,x,u); //mdlUpdate这个函数和上面的那个函数是一样的,如果你需要添加什么参数,直接添加就可以,前提是这些参数在最上面的function函数中声明了。这个函数表示更新,在离散模式下使用。
case 3,
sys=mdlOutputs(t,x,u); //s-functiion模块的输出 。
case 4,
sys=mdlGetTimeOfNextVarHit(t,x,u); //这个函数是计算下一个时刻的仿真时间,一般不需要修改。
case 9,
sys=mdlTerminate(t,x,u); //终止函数
otherwise
DAStudio.error(‘Simulink:blocks:unhandledFlag’, num2str(flag));
end
s函数定义的flag就只有0,1,2,3,4,9。每个函数的作用大致也讲了一些。上面的是函数的调用,下面需要写函数的主体。s函数其实输入和输出的关系,参数什么的都是我们自己添加的,需要就用,不用也不所谓。添加参数的目的往往是为了把这个函数当作一个模块,以使各种不同电路参数的buck-boost电路都可以使用。
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes
sizes = simsizes;
sizes.NumContStates = 2; //连续状态变量个数,buck-boost电路时2阶的,变量个数为2
sizes.NumDiscStates = 0; //离散变量个数,连续模式下为0
sizes.NumOutputs = 1; //输出变量的个数
sizes.NumInputs = 1; //输入变量的个数
sizes.DirFeedthrough = 1; //直馈通路,是指输出是否受输入的影响。我的理解是能控性
sizes.NumSampleTimes = 1; //采样时间的个数,这里时1个
sys = simsizes(sizes);
x0 = [14;7.5]; //状态变量的初值。注意:s函数出现的变量一般都是列向量
str = [];
ts = [0 0]; //连续模式下采样时间为0
simStateCompliance = ‘UnknownSimState’;
function sys=mdlDerivatives(t,x,u,C,L,R,D) //这里使用了参数C,L,R,D,需要列写出来
sys = [0 -(1-D)/L;(1-D)/C -1/(R*C)]*x+[D/L;0]*u; //sys其实就是dx dx=Ax+Bu 。注意:返回值是dx 不是x
function sys=mdlUpdate(t,x,u) //连续模式不使用,不管它
sys = [];
function sys=mdlOutputs(t,x,u)
sys = [0 -1]*x; //输出为-x(2) buck-boost输出电压与输入电压方向不同
。。。。。。。。。。。 //后面还有2函数,没有使用,不管它。
下面讲一下,断续是什么样子的:
function [sys,x0,str,ts,simStateCompliance] = bd(t,x,u,flag,C,L,R,D,h) //名字自己取,和上面是一样的
switch flag,
case 0,
[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;
case 1,
sys=mdlDerivatives(t,x,u);
case 2,
sys=mdlUpdate(t,x,u,C,L,R,D,h); //这里是和连续不同的地方。断续是使用Update函数,而不是Derivative函数。
case 3,
sys=mdlOutputs(t,x,u);
case 4,
sys=mdlGetTimeOfNextVarHit(t,x,u);
case 9,
sys=mdlTerminate(t,x,u);
otherwise
DAStudio.error(‘Simulink:blocks:unhandledFlag’, num2str(flag));
end
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes
sizes = simsizes;
sizes.NumContStates = 0;
sizes.NumDiscStates = 2; //断续模式,使用断续变量
sizes.NumOutputs = 1;
sizes.NumInputs = 1;
sizes.DirFeedthrough = 1;
sizes.NumSampleTimes = 1;
sys = simsizes(sizes);
x0 = [0;0]; 这里初值选择为0。原因是simulink断续仿真没有前向欧拉公式,我 电路仿真时一直不稳定,后来发现把初值设置为0就OK了(这里电路仿真啊,就是使用powerlib库搭的模型不稳定,不是写的s函数不稳定,s函数中咱们用的是前向差分,一般步长不太大都是稳定的)
str = [];
ts = [1e-7 0]; %离散采样时间 这里设置的是1e-7 和连续不一样哦
function sys=mdlDerivatives(t,x,u)
sys = [];
function sys=mdlUpdate(t,x,u,C,L,R,D,h)
sys(1)=x(1)+h*((-(1-D)/L)*x(2)+(D/L)u(1));
sys(2)=x(2)+h(((1-D)/C)x(1)-(1/(RC))*x(2));
x(1)=sys(1); //要不要都可以
x(2)=sys(2); //要不要都可以
这里咱们好好说说,其实也很简单,就是一个前向欧拉,但是咱们要说详细了。首先看sys(1)和sys(2) , sys其实就是以2×1的列向量 ,所以,sys(1,1)是第一个元素,sys(1,2)是第二个元素。因为是列向量,可以简写成sys(1) , sys(2) 。x(1)和x(2)道理是一样的。这里的算法很简单,求x(k+1) , 再将x(k+1)赋给x(k) 。这里最后两句是不需要的,因为sys本身返回的就是x的值 ,但是咱们写单片机代码的时候都是需要的,多写写没什么错的呀。
function sys=mdlOutputs(t,x,u)
sys = -x(2); //输出就是一个值
function sys=mdlGetTimeOfNextVarHit(t,x,u)
sampleTime = 1;
sys = t + sampleTime;
function sys=mdlTerminate(t,x,u)
sys = [];
写到这里就结束了,因为我也是小白,第2次使用s函数,但是我发现因为第一次写的时候没有及时总结,第二次的时候感觉就和一次都没写过的没啥区别,我也不经常写文章,所以写的文字都很糙,都是口头语,不正式,大家勿怪。写的不对的地方,敬请斧正。
最后
以上就是兴奋歌曲为你收集整理的MATLAB S-Function 使用心得的全部内容,希望文章能够帮你解决MATLAB S-Function 使用心得所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复