文章目录
- 1、在simulink中打开Library
- 2、设置S-Function模块
- 2.1、设置文件名
- 2.2、添加变量
- 2.3、设置输入输出
- 2.4、构建
- 3、编辑c语言程序
- 3.1、源码分析
- 3.1.1、sfunc.c
- 3.1.2、sfunc_wrapper.c
- 3.2 编译
- 4、结果
- 5、总结
1、在simulink中打开Library
选择S-Function Builder模块,拖拽出来。
2、设置S-Function模块
双击S-Function Builder模块,
属性:
(1)S-Function Name:设置c语言文件名。
(2)Insert Ports:添加输入输出变量。
(3)Ports And Parameters:设置输入以及输出变量名称、类型、数据类型、维度。
(4)Build:构建c语言文件
2.1、设置文件名
在S-Function Name处填写,注意不能有中文,本列设置为sfunc
2.2、添加变量
首先要选中Port And Parameters,点击Insert Ports,选择要添加的输入还是输出变量
2.3、设置输入输出
首先要选中Port And Parameters,然后修改输入输出选项下有关窗口属性:
- Name:输入输出变量(端口)名称,用户自己设置即可;
- Scope:变量类型;
- Data Type: 数据类型
- Dimensions:数据的维度,这里有两种选项,分别是1-D和2-D;如果是1-D则表示输入向量,2-D则表示输入为矩阵;
- Complexity:输入的数据是实数还是复数,这里有real(实数)和complex(复数)这两个选项;
2.4、构建
最后,设置完成后,点击Build按钮即可构建c语言文件,提示S-function ‘sfunc.mexw64’ created successfully后说明构建成功。
3、编辑c语言程序
3.1、源码分析
当Build后,会再matlab当前的目录下生成sfunc.c
和sfunc_wrapper.c
两个c语言文件以及一个.mexw64
文件。
-
.mexw64
:文件是供matlab使用的动态链接库; -
sfunc.c
:可在此文件中修改输入输出; -
sfunc_wrapper.c
:主要修改这个文件,来实现c语言功能,下面具体再分析;
3.1.1、sfunc.c
此文件是自动生成的文件,源码比较多,这里就看看主要的mdlOutputs函数即可:
static void mdlOutputs(SimStruct *S, int_T tid)
{
const real_T *u1 = (real_T *) ssGetInputPortRealSignal(S, 0);
const real_T *u0 = (real_T *) ssGetInputPortRealSignal(S, 1);
real_T *y0 = (real_T *) ssGetOutputPortRealSignal(S, 0);
real_T *y1 = (real_T *) ssGetOutputPortRealSignal(S, 1);
sfunc_Outputs_wrapper(u1, u0, y0, y1);
}
simulink每通过一个采样点就会调用一次函数mdlOutputs,在函数mdlOutputs中首先定义了两个输入两个输出变量,和我们之前在ui界面配置的相同,紧接着就是调用sfunc_Outputs_wrapper函数。
3.1.2、sfunc_wrapper.c
再此文件中,源码页比较长,我们只要看主要的sfunc_Outputs_wrapper函数即可:
void sfunc_Outputs_wrapper(const real_T *u1,
const real_T *u0,
real_T *y0,
real_T *y1)
{
/* %%%-SFUNWIZ_wrapper_Outputs_Changes_BEGIN --- EDIT HERE TO _END */
/* This sample sets the output equal to the input
y0[0] = u0[0];
For complex signals use: y0[0].re = u0[0].re;
y0[0].im = u0[0].im;
y1[0].re = u1[0].re;
y1[0].im = u1[0].im;
*/
/* %%%-SFUNWIZ_wrapper_Outputs_Changes_END --- EDIT HERE TO _BEGIN */
}
这里可以看到函数的参数为我们之前定义的两个输入以及两个输出,都是通过指针的形式传入函数。
由于之前我们定义的是一行一列的一维数组,这里传入的指针就是代表了数组的首地址,我们只需要对指针进行解引用,即可对变量进行操作。
例:
void sfunc_Outputs_wrapper(const real_T *u1,
const real_T *u0,
real_T *y0,
real_T *y1)
{
/* %%%-SFUNWIZ_wrapper_Outputs_Changes_BEGIN --- EDIT HERE TO _END */
/* This sample sets the output equal to the input
y0[0] = u0[0];
For complex signals use: y0[0].re = u0[0].re;
y0[0].im = u0[0].im;
y1[0].re = u1[0].re;
y1[0].im = u1[0].im;
*/
/* %%%-SFUNWIZ_wrapper_Outputs_Changes_END --- EDIT HERE TO _BEGIN */
y0[0] = u0[0];
y1[0] = u1[0];
}
3.2 编译
在matlab终端输入:
mex sfunc.c sfunc_wrapper.c
注:如果没安装编译器则需要先安装编译器编译器安装
4、结果
结果为:
5、总结
本文简单介绍了如何使用simulink中的S-Function模块调用c语言来实现我们想要的功能,有的地方是我自己的理解如果有错误,希望大家海涵并且指正,谢谢大家。