MATLAB S-Function 使用心得

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函数,但是我发现因为第一次写的时候没有及时总结,第二次的时候感觉就和一次都没写过的没啥区别,我也不经常写文章,所以写的文字都很糙,都是口头语,不正式,大家勿怪。写的不对的地方,敬请斧正。

  • 9
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值