• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Matlab S-function封装学习

武飞扬头像
想要帅哥的码农
帮助1

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

最近学习S-function封装,以下为学习过程中的总结。


一、代码封装

代码模板

学新通

选择User-Defined Functions --> S-Function Examples -->C-files -->sfuntmpl_basic.c

查阅函数的作用以及使用方法可通过官网查询,如下

配置 C/C S-Function 功能 - MATLAB & Simulink - MathWorks 中国

配置 C/C S-Function 功能- MATLAB & Simulink- MathWorks 中国

  1. 设置函数名称
  1.  
    #define S_FUNCTION_NAME  sfuntmpl_basic //这里修改函数名称
  2.  
     
  3.  
    #define S_FUNCTION_LEVEL 2

 2. 配置输入、输出、参数

  1.  
    static void mdlInitializeSizes(SimStruct *S)
  2.  
    {
  3.  
     
  4.  
     
  5.  
    //(1)参数配置
  6.  
     
  7.  
    ssSetNumSFcnParams(S, 0); //设置参数个数  /* Number of expected parameters */
  8.  
     
  9.  
        if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
  10.  
     
  11.  
            /* Return if number of expected != number of actual parameters */
  12.  
     
  13.  
            return;
  14.  
     
  15.  
        }
  16.  
     
  17.  
     
  18.  
     
  19.  
        ssSetNumContStates(S, 0); //指定 块具有的连续状态数
  20.  
     
  21.  
        ssSetNumDiscStates(S, 0); //指定 块具有的离散状态数
  22.  
     
  23.  
    //(2)输入端口配置
  24.  
     
  25.  
    if (!ssSetNumInputPorts(S, 1)) return;//配置输出端口个数
  26.  
     
  27.  
        ssSetInputPortWidth(S, 0, 1);//指定输入端口宽度
  28.  
     
  29.  
        ssSetInputPortRequiredContiguous(S, 0, true); /*direct input signal access*/
  30.  
     
  31.  
        /*
  32.  
     
  33.  
         * Set direct feedthrough flag (1=yes, 0=no).
  34.  
     
  35.  
         * A port has direct feedthrough if the input is used in either
  36.  
     
  37.  
         * the mdlOutputs or mdlGetTimeOfNextVarHit functions.
  38.  
     
  39.  
         */
  40.  
     
  41.  
        ssSetInputPortDirectFeedThrough(S, 0, 1);
  42.  
     
  43.  
     
  44.  
     
  45.  
    //(3)输出端口配置
  46.  
     
  47.  
    if (!ssSetNumOutputPorts(S, 1)) return;//配置输入端口个数
  48.  
     
  49.  
    ssSetOutputPortWidth(S, 0, 1);//指定输出端口宽度
  50.  
    ssSetNumSampleTimes(S, 1);
  51.  
    ssSetNumRWork(S, 0);
  52.  
    ssSetNumIWork(S, 0);
  53.  
    ssSetNumPWork(S, 0);
  54.  
    ssSetNumModes(S, 0);
  55.  
    ssSetNumNonsampledZCs(S, 0);
  56.  
     
  57.  
    /* Specify the sim state compliance to be same as a built-in block */
  58.  
    ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE);
  59.  
     
  60.  
    ssSetOptions(S, 0);
  61.  
     
  62.  
    }
学新通

3.指定此 C MEX S 函数运行的采样率

static void mdlInitializeSampleTimes(SimStruct *S)

4.初始化 此 C MEX S 函数的状态向量

static void mdlStart(SimStruct *S)

5.计算输出模块的输出信号

  1.  
    static void mdlOutputs(SimStruct *S, int_T tid)
  2.  
    {
  3.  
     
  4.  
    //获取输入端口的指针/地址
  5.  
    const void *ssGetInputPortSignal(SimStruct *S, int_T inputPortIdx)
  6.  
     
  7.  
     
  8.  
     
  9.  
    const real_T *u0 = (const real_T*) ssGetInputPortSignal(S,0);
  10.  
     
  11.  
     
  12.  
     
  13.  
    //获取输出端口的指针/地址
  14.  
    void *ssGetOutputPortSignal(SimStruct *S, int_T port)
  15.  
     
  16.  
    real_T       *y = ssGetOutputPortSignal(S,0);
  17.  
     
  18.  
     
  19.  
     
  20.  
    //获取参数指针/地址
  21.  
    const mxArray *ssGetSFcnParam(SimStruct *S, int_T index)
  22.  
     
  23.  
        //获取参数1,double类型
  24.  
     
  25.  
        const real_T  *param1  = (const real_T *)mxGetData(ssGetSFcnParam(S, 0));
  26.  
     
  27.  
        double a = (double) *param1;
  28.  
     
  29.  
        //获取参数2,string类型
  30.  
     
  31.  
        const unsigned char  *param2  = (const unsigned char *)mxArrayToString(ssGetSFcnParam(S, 1));
  32.  
     
  33.  
        const int_T   p_width  = mxGetNumberOfElements(ssGetSFcnParam(S, 1));
  34.  
     
  35.  
        unsigned char *str = (unsigned char *)mxCalloc(p_width, sizeof(unsigned char));
  36.  
     
  37.  
        memcpy(str, param1, p_width);
  38.  
    }
学新通

6.更新块的状态

static void mdlUpdate(SimStruct *S, int_T tid)

7.计算 C MEX S 函数的导数

static void mdlDerivatives(SimStruct *S)

8.执行仿真终止时所需的任何操作

static void mdlTerminate(SimStruct *S)
  • 代码编译
  1. 环境准备

查看matlab是否安装编译器MinGW-w64

mex -setup

环境安装步骤

将TDM-GCC-64.zip 解压在C盘,注意路径不能有空格

配置环境变量

学新通

2.编译指令

mex filename -I./

链接其他库的时候

mex filename -I./ -L./

编译成功后会生成64位Windows版本的动态链接库

学新通

学新通

  • 关联模型
  1. 编写m文件

修改slblocks.m文件

  1.  
    function blkStruct = slblocks
  2.  
     
  3.  
    blkStruct.Name = ['add'];
  4.  
     
  5.  
    blkStruct.OpenFcn = 'add;
  6.  
     
  7.  
    blkStruct.MaskDisplay = '';
  8.  
     
  9.  
     
  10.  
     
  11.  
    Browser(1).Library = 'add';
  12.  
     
  13.  
    Browser(1).Name = 'add';
  14.  
     
  15.  
    Browser(1).IsFlat = 0;
  16.  
     
  17.  
     
  18.  
     
  19.  
    blkStruct.Browser = Browser;
学新通
  1. 打开Simulink,新建Model

添加S-Function 模型

学新通

如图 双击S-Function 模型 后,弹出 Block Parameter窗口 ,点击 Edit 后选择Browser 关联代码封装的 .c文件。

学新通

S-Function name 填入S-function的函数名称,这样就建立了S-function模块与M文件形式的S-function之间的对应关系;

S-Function parameters  填入S-function需要输入的外部参数的名称,如果有对各变量,则变量中间用逗号隔开,如a,b,c;

S-Function modules  仅当S-function是用C语言编写并用MEX工具编译的C-MEX文件时,才需要填写该参数;

 学新通

  • Mask封装

右键点击S-Function 模块,选中 Mask选项 --> Create Mask Editor 创建模板界面

学新通

 学新通

lcon &Ports 页面填写模块界面输出

  1.  
    %参数显示
  2.  
     
  3.  
    showInfo = sprintf('a: %s\nb: %s\nc: %s\n',get_param(gcb,'a'),get_param(gcb,'b'),get_param(gcb,'c'));
  4.  
     
  5.  
    disp(showInfo);
  6.  
     
  7.  
     
  8.  
     
  9.  
    %输入端口名称显示
  10.  
     
  11.  
    port_label('input',1,'DataInput1');
  12.  
     
  13.  
     
  14.  
     
  15.  
    %输出端口名称显示
  16.  
     
  17.  
    port_label('output',1,'DataOutput1');
学新通

Parameters & Dialog 界面

设置和绑定参数控件

Initialization页面

可以添加参数初始化命令

Documentation 页面

可以添加模型说明

最后将模块的名称 S-Function更改;

效果如下:

学新通

  • 将S-Function添加到simulink库中

将 模型复制和保存为Library 文件

学新通

设置路径

学新通

打开Simulink Library Browser库文件

右键选中 Refresh Library Browser 刷新界面然后就可以出来封装的模型。

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgcacee
系列文章
更多 icon
同类精品
更多 icon
继续加载