本帖最后由 hyowinner 于 2015-1-13 11:52 编辑

很多用户会抱怨说SImulink里没有提供直接读取Excel文件的模块,我们不妨自己定制一个。使用S-function模块结合Level 1 M S-function文件实现一个能够选择excel文件,并将其中数据按照采样时间顺序输出。而在模块的对话框中,我们将数据通过表格展示,或者直接将其图像绘制出来。Simulink自带的模块Mask功能没有提供坐标轴控件,所以使用GUIDE来实现这个模块的对话框。

首先设计一个GUI界面,能够实现通过按钮打开Window对话框选择xls文件,读取其内容中的数据,显示到table中,并绘制图像,基于这样的需求,再结合Simulink模块的对话框风格,设计的GUI(sfun_xlsread_gui.fig)界面如下图:

57038da54a6f44c7ea770079aebbfa9d.png

01.png (30.23 KB, 下载次数: 19)

2014-9-13 07:07 上传

图1 xls文件读取与显示用figOpen这个按钮的回调函数中实现选择xls文件,显示路径,读取数据显示到uitable和并在坐标轴中绘制图像的功能。GUIDE的按钮可以随意控制显示位置和大小,这一点是Simulink的Mask功能所无法比拟的。

对于这个模块的S函数,需要一个参数来保存文件路径信息,命名为g_file_path,内容是字符串,所以在S函数中封装为edit类型以传递此种类型数据。这个参数通过用户对对话框操作之后得到,并应用于S函数内部为模块的仿真功能服务。注意不勾选Evaluate属性,这个属性的意思是将参数内容作为参数调用eval()函数。因为这个参数的内容是一个字符串,不希望作为变量使用,所以不需要再进行一次eval()。

a7f714e13ab4331ddf3179d46fec807f.png

02.png (32.05 KB, 下载次数: 25)

2014-9-13 07:07 上传

图2 封装edit类型参数g_file_path封装之后,右键S函数模块的模块参数列表,填入即将编写的S函数名和参数变量名。

9beb59bdbcc04f38c49c69924b6d724b.png

03.png (17.36 KB, 下载次数: 19)

2014-9-13 07:07 上传

图3 S函数与参数表为了使用刚刚创建的fig替代Simulink默认的对话框,可以将fig作为该S函数模块的打开回调函数(OpenFcn)来运行。这样当双击这个S函数模块的时候,就会启动sfun_xlsread模块作为对话框。

dcd56d40ad7dfba399b8b28454bfe20d.png

04.png (38.56 KB, 下载次数: 19)

2014-9-13 07:07 上传

图4 S函数的OpenFcn有了回调函数的挂接,又有了g_file_path这个参数作为数据传递媒介,用户所选择的文件就能够传递到S函数中去了。上述Fig的button按下所执行的代码如下:

b81c33c91d2f97124e4a6f9ebbd509a9.png

05.png (19.74 KB, 下载次数: 28)

2014-9-13 07:07 上传

图5 button回调函数代码对于S函数的仿真功能,在每个采样时刻将对话框上所选择的xls文件中的数据依次输出,如果仿真时间比较长,采样数大于数据数那么最后一个数据点的数据持续输出。实现这个仿真功能的S函数采用Level 1 M S函数来编写:

function [sys,x0,str,ts,simStateCompliance] =

sfun_xlsread(t,x,u,flag,g_file_path)

switch flag,

case 0,

[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes(g_file_path);

case 1,

sys=mdlDerivatives(t,x,u);

case 2,

sys=mdlUpdate(t,x,u);

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(g_file_path)

global data

len cnt

[data, str] = xlsread(g_file_path);

len = length(data);

sizes = simsizes;

sizes.NumContStates = 0;

sizes.NumDiscStates = 0;

sizes.NumOutputs = 1;

sizes.NumInputs = 0;

sizes.DirFeedthrough = 0;

sizes.NumSampleTimes = 1;

sys = simsizes(sizes);

x0 = [];

str = [];

ts = [0,0];

cnt = 0;

simStateCompliance = 'UnknownSimState';

function sys=mdlDerivatives(t,x,u)

sys = [];

function sys=mdlUpdate(t,x,u)

sys = [];

function sys=mdlOutputs(t,x,u)

global data

len cnt

cnt = cnt + 1;

if cnt<= len

sys = data(cnt);

else

sys = data(end);

end

function sys=mdlGetTimeOfNextVarHit(t,x,u)

sampleTime = 1;

sys = t + sampleTime;

function sys=mdlTerminate(t,x,u)

sys = [];

[align=left]复制代码

这个S函数可以通过前面章节讲述的S函数自动生成工具生成之后稍加修改即可,此模块无输入,无状态变量,一个输出用来输出xls文件内部数据。通过g_file_path读取的数据data作为全局变量,在初始化子方法和输出子方法之间传递。另外需要一个全局变量cnt来进行采样点数的计数,在输出子方法中将对应当前采样点的数据输出。

2bf7ff301a35007a403ef9c9b62813d5.png

06.png (56.63 KB, 下载次数: 25)

2014-9-13 07:07 上传

图6 数据预览及仿真通过这个实例,用户可以扩展Simulink自定义对话框使用控件的范围,借助GUIDE来设计更加丰富多姿的参数对话框。

更多推荐