matlab中的sfunction的用法(C语言)-转_第1页
matlab中的sfunction的用法(C语言)-转_第2页
matlab中的sfunction的用法(C语言)-转_第3页
matlab中的sfunction的用法(C语言)-转_第4页
matlab中的sfunction的用法(C语言)-转_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

matlab中的sfunction的用法(C语言)matlab中的sfunction的用法(C语言)创建一个有1输入(2维),2输出(1维),3个参数,还有全局变量的s-function。1.新建sfunction的C语言文件打开simulink,点击User-Defined

Functions里面的S-Function

Examples。这个里面有多个语言版本的模板,有C,C++,Ada,Fortran和M语言的版本,其实都大同小异,只要了解几个函数就很容易使用了。

选择C语言的版本:从S-function模块中选择C-file

S-functions里面的Basic

C-MEX

template。打开后,另存为自己的模块名字,如test.c。

下面我们来分析代码:#define

S_FUNCTION_NAME

test//这里把文件名sfuntmpl_basic修改为test

#define

S_FUNCTION_LEVEL

2#include

"simstruc.h"//程序里面要用到的头文件在这里引用,如“math.h”等。float

global_var;

//定义全局变量static

void

mdlInitializeSizes(SimStruct

*S){//这个函数用来设置输入、输出和参数的。ssSetNumSFcnParams(S,

3);

/*设置参数个数,这里为3

*/if

(ssGetNumSFcnParams(S)

!=

ssGetSFcnParamsCount(S))

{return;}ssSetNumContStates(S,

0);//设置连续状态的个数,缺省为0;

ssSetNumDiscStates(S,

0);//设置离散状态的个数,缺省为0;if

(!ssSetNumInputPorts(S,

1))

return;//设置输入变量的个数,这里为1ssSetInputPortWidth(S,

0,

2);

//设置输入变量0的维数为2ssSetInputPortRequiredContiguous(S,

0,

true);

//设置input0的访问方式,true就是临近访问,这样指针的增量后就可以直接访问下个input端口了。

ssSetInputPortDirectFeedThrough(S,

0,

1);//

设置输入端口的信号是否mdlOutputs函数中使用,这儿设置为true。if

(!ssSetNumOutputPorts(S,

2))

return;//设置输出变量的个数

ssSetOutputPortWidth(S,

0,

1);//设置输出变量0的维数为1维ssSetOutputPortWidth(S,

1,

1);//设置输出变量1的维数为1维

ssSetNumSampleTimes(S,

1);

//设置采样时间,此处为1s。ssSetNumRWork(S,

0);//不管ssSetNumIWork(S,

0);ssSetNumPWork(S,

0);ssSetNumModes(S,

0);ssSetNumNonsampledZCs(S,

0);ssSetOptions(S,

0);//下面可以写全局变量的初始化程序global_var=1;}static

void

mdlInitializeSampleTimes(SimStruct

*S)//暂时不管

{ssSetSampleTime(S,

0,

CONTINUOUS_SAMPLE_TIME);ssSetOffsetTime(S,

0,

0.0);}#define

MDL_INITIALIZE_CONDITIONS

/*

Change

to

#undef

to

remove

function

*/#if

defined(MDL_INITIALIZE_CONDITIONS)static

void

mdlInitializeConditions(SimStruct

*S)//暂时不管

{}#endif

/*

MDL_INITIALIZE_CONDITIONS

*/#define

MDL_START

/*

Change

to

#undef

to

remove

function

*/

#if

defined(MDL_START)static

void

mdlStart(SimStruct

*S)//暂时不管{}#endif

/*

MDL_START

*/static

void

mdlOutputs(SimStruct

*S,

int_T

tid)//这里填入相关的运算、算法等{real_T

*para1

=

mxGetPr(ssGetSFcnParam(S,0));real_T

*para2

=

mxGetPr(ssGetSFcnParam(S,1));real_T

*para3

=

mxGetPr(ssGetSFcnParam(S,2));const

real_T

*u

=

(const

real_T*)

ssGetInputPortSignal(S,0);

real_T

*y1

=

ssGetOutputPortSignal(S,0);real_T

*y2

=

ssGetOutputPortSignal(S,1);y1[0]=u[0]*para1[0]+u[1]*para2[0];y2[0]=u[1]*para3[0]+u[0]*para1[0];}#define

MDL_UPDATE

/*

Change

to

#undef

to

remove

function

*/

#if

defined(MDL_UPDATE)static

void

mdlUpdate(SimStruct

*S,

int_T

tid){}#endif

/*

MDL_UPDATE

*/#define

MDL_DERIVATIVES

/*

Change

to

#undef

to

remove

function

*/

#if

defined(MDL_DERIVATIVES)static

void

mdlDerivatives(SimStruct

*S){}#endif

/*

MDL_DERIVATIVES

*/static

void

mdlTerminate(SimStruct

*S)//这里需要把global变量全部初始化,否则下次运行程序时,全局变量还是之前的值。{}#ifdef

MATLAB_MEX_FILE

/*

Is

this

file

being

compiled

as

a

MEX-file?

*/#include

"simulink.c"

/*

MEX-file

interface

mechanism

*/

#else#include

"cg_sfun.h"

/*

Code

generation

registration

function

*/#endif2.编译在matlab的command

window

里面输入“mex

test.c”,即可将test.c编译为mex文件。3.调用sfunction在simulink空间里面拉入sfunction,在s-function

name里面填入test,参数里面填入要设定的参数,然后仿真即可。

在User-Defined

Function里面还有matlab

function模块,这个模块支持matlab函数和自定义的函数,缺点就是input,output都是一个端口,模块上不能显示输入输出的label。还有fcn模块,它支持简易的函数表达式。S-FunctionS-Function,在library里面有很多模板,有C,C++,M,Ada,Fortran的版本,其实都大同小异,只要了解几个函数就很容易使用了,当然初学者也可以用S-Function

Builder来构建。当然了解了代码后,那个Builder生成的代码就更容易懂了。下面咱们以一个例子开始把任务:构建一个C的S-Function。2个input,2个output,2个parameterinput都为3*1向量,output也是3*1向量。从S-function模块中选择C-file

examples里面的Basic

C-MEX

template。打开它,另存为我们的模块名字就ok了。我们存为test.c把下面我们来分析代码:1.#define

S_FUNCTION_NAME

sfuntmpl_basic#define

S_FUNCTION_LEVEL

2#define

INPUT_NUM

2#define

OUTPUT_NUM

2这儿我们需要修改下文件名了。把sfuntmpl_basic

改为

test2.#include

"simstruc.h"此处引用头文件,当我们需要其他头文件,例如math.h,stdio.h等,看你需要啥函数了。3.static

void

mdlInitializeSizes(SimStruct

*S)这个函数我们用来设置输入,输入,和参数的。参数就是,我们点击模块时候,那个对话框里面需要设置的。参数之间空格隔开4.ssSetNumSFcnParams(S,

PARA_NUM);

/*

Number

of

expected

parameters

*/if

(ssGetNumSFcnParams(S)

!=

ssGetSFcnParamsCount(S))

{/*

Return

if

number

of

expected

!=

number

of

actual

parameters

*/return;}PARA_NUM

就是你自己需要设置的参数个数5.ssSetNumContStates(S,

0);ssSetNumDiscStates(S,

0);设置连续状态和离散状态个数。缺省都为06.if

(!ssSetNumInputPorts(S,

INPUT_NUM))

return;ssSetInputPortWidth(S,

0,3);

//设置端口的维数,现在为3*1ssSetInputPortRequiredContiguous(S,

0,

true);

/*direct

input

signal

access*/ssSetInputPortWidth(S,

1,3);

//设置端口的维数,现在为3*1ssSetInputPortRequiredContiguous(S,

1,

true);

/*direct

input

signal

access*/ssSetInputPortDirectFeedThrough(S,

0,

1);ssSetInputPortDirectFeedThrough(S,

1,

1);INPUT_NUM就是输入端口的个数,分别设置每个端口的维数,注意端口号从0开始的。ssSetInputPortRequiredContiguous是设置input的访问方式,true就是临近访问,这样指针的增量后

就可以直接访问下个input端口了。ssSetInputPortDirectFeedThrough设置输入端口的信号是否mdlOutputs函数中使用,这儿设置为true。7.if

(!ssSetNumOutputPorts(S,

OUTPUT_NUM))

return;ssSetOutputPortWidth(S,

0,

3);ssSetOutputPortWidth(S,

1,

3);同样设置2个输出端口,以及维数8.ssSetNumSampleTimes(S,

1);ssSetNumRWork(S,

0);ssSetNumIWork(S,

0);ssSetNumPWork(S,

0);ssSetNumModes(S,

0);ssSetNumNonsampledZCs(S,

0);设置采样时间,此处为1s。ssSetNumRWork,设置浮点向量的大小,0表示继承信号大小,DYNAMICALLY_SIZED表示可用

mdlSetWorkWidths来自己设置。下面的函数依次是设置整型,指针,模式向量的大小。模式向量是专用模块的编写的。ssSetNumNonsampledZCs设置采样点之间的zero

crossing的模块的状态个数9.mdlInitializeSizes函数搞定。其他mdlInitializeSampleTimesmdlInitializeConditionsmdlStart我们暂时不管了,一些初始化的东西,大家可以放在这里。我们直接奔mdlOutputs函数把。10.在这个函数里面,我们执行我们的复杂逻辑关系,和我们的代码了。首先,我们得到我们参数,输入,输出的指针把。这样我们才能操作。real_T

*para1

=

mxGetPr(ssGetSFcnParam(S,0));real_T

*para2

=

mxGetPr(ssGetSFcnParam(S,1));const

real_T

*u1

=

(const

real_T*)

ssGetInputPortSignal(S,0);const

real_T

*u2

=

(const

real_T*)

ssGetInputPortSignal(S,1);real_T

*y1

=

ssGetOutputPortSignal(S,0);real_T

*y2

=

ssGetOutputPortSignal(S,1);下面我们简单把输入乘上参数1或参数2,然后赋值给输出。y1[0]

=

para1[0]*u1[0];y1[1]

=

para1[0]*u1[1];y1[2

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论