资源预览内容
第1页 / 共17页
第2页 / 共17页
第3页 / 共17页
第4页 / 共17页
第5页 / 共17页
第6页 / 共17页
第7页 / 共17页
第8页 / 共17页
第9页 / 共17页
第10页 / 共17页
亲,该文档总共17页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
1 Matlab 中基于 C 语言的 S 函数的编写与应用 作者:Zheng Simin 单位:WHU 摘要:摘要:Matlab/Simulink 中提供了 S 函数模块,可以实现和 C 语言和其它语言的程序混编,将 C 语言和 Matlab 的强大的仿真能力及数据可视化能力进行了有机结合,可以极大地方便一些以 C 语言为基础的工程应用的算法仿真和数学实验的进行。 本文将对Matlab中基于C语言的S函数的应用及编写方法行相关介绍。 关键字:关键字:Matlab;S 函数;C 语言 1 Matlab 的 S 函数简介 “S-函数是系统函数(System Function)的简称, 是指采用非图形化的方式(即计算机语言,区别于 Simulink 的系统模块)描述的一个功能块。Simulink 没有单独的语言,但它提供了 S 函数规则。所谓的 S 函数可以是一个 M 文件、FORTRAN程序、C 或 C+语言程序等,通过特殊的语法规则使之能够被 Simulink 模型或模块调用。S 函数使 Simulink 更加充实、完备,具有更强的处理能力。 S-函数作为与其他语言相结合的接口,可以使用这个语言所提供的强大能力。例如,Matlab 语言编写的 S-函数可以充分利用 MATLAB 所提供的丰富资源,方便地调用各种工具箱函数和图形函数;使用 C 语言编写的 S-函数可以实现对操作系统的访问,如实现与其他进程的通信和同步等。 Simulink 已经提供了大量的内置的系统模块,并且允许用户自定义模块,对于大多数动态系统仿真分析语言,使用 Simulink 提供的模块即可实现,而无需使用 S-函数。但是,当需要开发一个新的通用的模块作为一个独立的功能单元时,使用 S-函数实现则是一种相当简便的方法。另外,由于 S-函数可以使用多种语言编写,因此可以将已有的代码结合进来,而不需要在 Simulink 中重新实现算法,从而在某种程度上实现了代码移植。此外,在 S-函数中使用文本方式输入公式、方程,非常适合复杂动态系统的数学描述,并且在仿真过程中可以对仿真进行更精确的控制。” 具体详细的一些介绍在此不再赘述,本文结合自身的项目经历,推荐一种 S函数的用处:Matlab 中嵌入其它代码,例如中嵌入其它代码,例如 C 代码,并参与算法的仿真,然后代码,并参与算法的仿真,然后利用利用 Matlab 丰富的图形生成接口函数来实现数据的可视化丰富的图形生成接口函数来实现数据的可视化。 备注:本文在所涉及的 Matlab 版本:Matlab.R2010b 2 一个 S 函数仿真例子 2 在正式对 S 函数进行介绍前,先看一个例子,这个例子是对网络的随机延时环境进行算法模拟,能够对输入的正常的时钟信号产生 0.2s 到 0.7s 不等的随机延时。本小节采用“从整体到局部,从结果到原因”的方式对此示例进行介绍。 用数字程序建立一个随机延时为 0.3s 到 0.6s 不等的网络随机延时环境, 所涉及的 Simulink 仿真程序结构如图 2-1 所示。 图 2-1 网络随机延时仿真 这是一个比较基本的 S 函数的仿真应用结构图,采样周期设置为 0.1s。整个仿真图的采样周期在解算器里面设置,单个仿真图的采样周期双击本模块,在如图 2-2 的界面中对“Sample time”进行设置即可。 图 2-2 设置模块采样周期 在图 2-1 所示的网络随机延时仿真程序中,输入一个时钟模块,然后经过一个单位的延时(单位延时的大小等于采样周期),然后再经过网络随机延时的 S函数模块(程序代码见附录),然后再对 S 函数模块输入输出的两路信号合并在同一坐标系下输出。输出的模块有两种,“Scope”数字示波器模块和“ToWorkspace”数据导出模块。 “Scope”可以直接将数据在坐标系下进行可视化显示,可以实现坐标轴不同级别的缩放,如图 2-3 所示;“ToWorkspace”则将数据以指定的变量名称存放在工作区间中, 然后在工作区间中可以编写相应的程序直接对此数据进行引用。 z1Unit DelaysimoutTo WorkspaceScopeRandomTimeDelayS-Fun-TimeDelayClock3 图 2-3 “Scope”整体图(左)和局部放大图(右) 因为“Scope 模块”默认的输出是黑底背景色,这些图片数据放置到论文中采用黑白打印时,完全是漆黑一片,为此可以采用一些处理方式:在 Matlab 的命令输入区域输入命令: “set(0,ShowHiddenHandles,On); set(gcf,menubar,figure)” 然后“Scope 图”就变成“Figure 图”了,并配备了相应的修改菜单,通过修改“【Edit】【Axes Properties】”然后就可以调出修改菜单,对坐标系统进行显示参数修改。在对“背景色、标尺颜色、曲线显示样式、坐标轴标记”进行修改后,图 2-3 就变成如图 2-4 的效果了(直接输出的是矢量图)。 图 2-4 “Scope”虚拟示波器图形变换 如果需要对输出数据进行程序引用,则可以使用“To Workspace”模块将数据引出到工作区间中,在仿真程序 2-1 运行结束后,在工作区间中会生成一个全局变量,如图 2-5 所示。 Times(s)Delay(s)4 图 2-5 导出仿真数据到 Workspace 中 当数据导出到 Workspace 工作空间中后, 就可以利用 Matlab 提供的一些函数接口来进行任意的程序设计并完成对数据的操作和引用了。例如,可以通过如表2-1 所示的 M 代码对导出的数据 simout(输出的两组数据)和 tout(仿真的时间标记)进行作图。 表 2-1 引用数据绘制曲线图的 M 程序 figure1 = figure; axes1 = axes(Parent,figure1,FontName,Consolas,FontSize,11); hold(axes1,all); x=linspace(0, 10, 101); p=plot(x,simout(:,1), c-, x, simout(:,2), r:); %grid; set(p,LineWidth,2,Parent,axes1); xlabel(Time(s),FontName,Consolas,FontSize,12); ylabel(Y-Value,FontName,Consolas,FontSize,12); title(The RandomDelay,FontSize,12,FontName,Consolas); legend(Clock,RandomDelay Colck); 运行表 2-1 所示的 M 文件后,就可以完成对工作区间的数据进行曲线绘制,绘制的结果如图 2-6 所示,当然如果对图形不满意,还可以通过菜单对显示图的坐标、背景色、线条样式、标记等等进行修改。 数据导出到工作区间后, 其意义并不仅仅局限于调用更强大的 plot 绘图函数来完成对数据的可视化, 更重要意义在于这样做可以将本程序的实验数据实现通用性。 这些数据从 Simulink 导出到 Worksapce 后, 一方面它可以被任意的 Matlab函数和其它的 Simulink 仿真程序所引用,另外一方面这些数据可以提供可以数据修改的可视化界面,可以复制到例如 Excel 等数据处理系统中,然后再供其它5 程序进行引用。总之,“数据导出模块 To Workspace”(及相应的“数据导入模块 From Workspace”)为 Simulink 和外界数据交流提供了接口,实现了数据的共享。 图 2-6 导出数据的 Plot 曲线图 3 S 函数模块 在上一节上对一个S函数的应用仿真程序例子的整体结构及功能进行了介绍,下面将对 S 函数的结构和编写方式(本文主要是基于 C 语言来实现)进行详细介绍。 3.1 S 函数的结构 关于 S 函数的学习资料,最齐全的就在 Matlab 自带的 Help 帮助文档中。在安装 Malab 之后,安装程序也顺便安装好了相关的学习文档。在【Simulink】-【Users Guide】-【Developing S-Functions】分支里面就有详细的关于 S 函数的说明,如图 3-1 所示。 在帮助文档里面有关于 S 函数的工作原理, 运行流程及如何完成 S 函数的代码编写,在此不再赘述。本文只是简单的对自己除了这些文档外的一些学习经历进行一下总结。 02468100246810Time(s)Y-ValueThe RandomDelayClock RandomDelay Colck6 图 3-1 S 函数的相关学习文档 3.2 S 函数的代码编写 用 C 或 C+语言编写实现的 S 函数被称为“MEX S-Functions”,MEX S 函数由一系列的回调方法组成。用户只需要按照一定的结构对代码进行编写即可,具体的代码结构,在 Matlab 中会提供一个模板“sfuntmpl_doc.c”,这个文件存在于“D:Program FilesMATLABR2010bsimulinksrc”中,用户只需要先复制一份此模板,然后再修改相应的名字,就可以往里面写好的回调函数的函数体中写入自己想实现的 C 代码即可。这里面主要包括:输入何输出端口设置、参数的提取、输出端口的设置等等。具体的编写方法也请参照帮助文档。 3.3 S 函数的编译 在编写好 S 函数的实现代码*.c 文件后,还需要在 Matlab 的命令输出窗口中进行命令行输入,完成对源代码的编译,这样才能被 S 函数模块所调用。在命令窗口中输入命令: “mex -g RandomTimeDelay.c” M 文件 S-函数在 MATLAB 环境下可以通过解释器直接执行, 而 C 文件或其它语言编写的 C-函数,则需要先编译成可以在 MATLAB 内运行的二进制代码:动态连接库或静态连接库,然后才可以使用,这些经过编译的二进制文件就称作7 MEX 文件。用 MEX 命令来对*.c 文件进行编译,然后会在相应的目录下生成对应的*.mexw32 文件。然后就可以在 simulink 模块中引用这个 s 函数了。 图 3-2 S 函数的 C 代码编译 3.4 S 函数的调用 在 Simulink 模块中拖入 S 函数模块,然后双击模块,将模块和当前目录下的S 函数的*.mexw32 文件相对应起来,然后就可以实现函数的调用了。例如在第 2节中对 RandomTimeDelay 函数调用时,双击 S 函数模块,在如图 3-3 所示的设置对话框中设置 S 函数的名称(在 C 代码中指定的)和输入参数1,2,8(分别代表:输入信号宽度、最小随机时延、最大随机时延)。具体的还有些涉及到函数的传值,及 S 函数中一些参数的解析等等,都参考帮助文档。 图 3-3 S 函数模块参数设置 3.5 S 函数的调试 8 程序规模比较小的时候, 使用printf来将中间变量打印到Matlab的Workspace窗口中,然后看运行情况。程序规模比较大时,使用专门的 C 语言开发集成环境,例如 VC6.0 或者 Eclipse CDT 等等来开发,调试成功后,再将代码直接复制到 MEX-S 函数的模板中,然后再在 Matlab 中使用 MEX 命令编译一次,就可以在 Simulink 中进行调用了。 在Matlab的帮助文档中提供了一些使用VC+或者VS来调试C代码的方法,根据但要,好像可以一边使用 Matlab 仿真,一边在 VS 中进行断点调试,还可以查看中间变量值,但是自己一直都没有试成功,今后有时间有需求后再仔细研究下是什么问题吧。 附上 Matlab 帮助文档中提供的 “Matlab 和外部工具现场联调” 方法
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号