我是靠谱客的博主 拉长鼠标,最近开发中收集的这篇文章主要介绍[Matlab]Simulink串口接收详解2用S-Function解析数据包1.概述2. 效果3. S-Function源码4. 文件说明及下载,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

原创文章,欢迎转载。转载请注明:转载自 祥的博客

原文链接:https://blog.csdn.net/humanking7/article/details/80856505


  • 1.概述
    • 1.1. S-Function模块设置
    • 1.2. Data Type Conversion模块设置
  • 2. 效果
  • 3. S-Function源码
    • 3.1. S-Function源码 - unPackData_Q.c
    • 3.2. 需要的头文件 - DataType.h
  • 4. 文件说明及下载
    • 4.1 文件说明
    • 4.2 文件下载


1.概述

在上一个博文 [Matlab] Simulink 串口接收详解1 中,讲了一下Serial Precive模块的简单用法,但是有时候我们接收的数据是具有复杂定义的数据包。这个时候就需要自己对得到数据进行2次解析。

IMG20180629005148

1.1. S-Function模块设置

在这里我用Matlab中的S-Function写解析函数,如下图中的unPackData模块,是 S-Function 模块。S-Function 函数( unPackData_Q.c )将在后面讲解。

IMG20180629112354.png

1.2. Data Type Conversion模块设置

还是一次接收一个16字节的uint8数组,实际代表了2个double的数据。之所以加一个数据转换模块,是因为S-Function的输入是double类型的。

IMG20180629113207.png

如果不经过转换模块,则会报错:

  • Data type mismatch. Input port 1 of ‘recCom_Union/unPackData’ expects a signal of data type ‘double’. However, it is driven by a signal of data type ‘uint8’.
  • Data type mismatch. Output port 1 of ‘recCom_Union/Serial Receive’ is a signal of data type ‘uint8’. However, it is driving a signal of data type ‘double’.

IMG20180629114325

2. 效果

Qt写的发送程序,每隔100ms发送两个double数据,这两个数据按照正弦信号输出:

  • number1 = A1*sin( w1 * time + d1)
  • number2 = A2*sin( w2 * time + d2)

接收效果如下图所示:

IMG20180629000000

3. S-Function源码

3.1. S-Function源码 - unPackData_Q.c

#define S_FUNCTION_NAME  unPackData_Q
#define S_FUNCTION_LEVEL 2


#include "simstruc.h"
#include "DataType.h"//收发数据类型



static void mdlInitializeSizes(SimStruct *S)
{
    /* See sfuntmpl_doc.c for more details on the macros below */

    ssSetNumSFcnParams(S, 0);  /* Number of expected parameters */
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
        /* Return if number of expected != number of actual parameters */
        return;
    }

    ssSetNumContStates(S, 0);
    ssSetNumDiscStates(S, 0);

    if (!ssSetNumInputPorts(S, 1)) return;//1个输入口
    ssSetInputPortWidth(S, 0, 16);//16维
    ssSetInputPortRequiredContiguous(S, 0, true); /*direct input signal access*/
    /*
     * Set direct feedthrough flag (1=yes, 0=no).
     * A port has direct feedthrough if the input is used in either
     * the mdlOutputs or mdlGetTimeOfNextVarHit functions.
     * See matlabroot/simulink/src/sfuntmpl_directfeed.txt.
     */
    ssSetInputPortDirectFeedThrough(S, 0, 1);

    if (!ssSetNumOutputPorts(S, 1)) return;//1个输出口
    ssSetOutputPortWidth(S, 0, 2);//宽度为2


    ssSetNumSampleTimes(S, 1);
    ssSetNumRWork(S, 0);
    ssSetNumIWork(S, 0);
    ssSetNumPWork(S, 0);
    ssSetNumModes(S, 0);
    ssSetNumNonsampledZCs(S, 0);

    /* Specify the sim state compliance to be same as a built-in block */
    ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE);

    ssSetOptions(S, 0);
}



/* Function: mdlInitializeSampleTimes =========================================
 * Abstract:
 *    This function is used to specify the sample time(s) for your
 *    S-function. You must register the same number of sample times as
 *    specified in ssSetNumSampleTimes.
 */
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)
  /* Function: mdlInitializeConditions ========================================
   * Abstract:
   *    In this function, you should initialize the continuous and discrete
   *    states for your S-function block.  The initial states are placed
   *    in the state vector, ssGetContStates(S) or ssGetRealDiscStates(S).
   *    You can also perform any other initialization activities that your
   *    S-function may require. Note, this routine will be called at the
   *    start of simulation and if it is present in an enabled subsystem
   *    configured to reset states, it will be call when the enabled subsystem
   *    restarts execution to reset the states.
   */
  static void mdlInitializeConditions(SimStruct *S)
  {
  }
#endif /* MDL_INITIALIZE_CONDITIONS */



#define MDL_START  /* Change to #undef to remove function */
#if defined(MDL_START) 
  /* Function: mdlStart =======================================================
   * Abstract:
   *    This function is called once at start of model execution. If you
   *    have states that should be initialized once, this is the place
   *    to do it.
   */
  static void mdlStart(SimStruct *S)
  {
  }
#endif /*  MDL_START */



/* Function: mdlOutputs =======================================================
 * Abstract:
 *    In this function, you compute the outputs of your S-function
 *    block.
 */
static void mdlOutputs(SimStruct *S, int_T tid)
{//解析核心代码
    int i;
    Un_sendData revData;
    const real_T *u = (const real_T*) ssGetInputPortSignal(S,0);
    real_T       *y = ssGetOutputPortSignal(S,0);

    //Step1.赋值解析[用char的数组buf进行赋值]
    for(i=0;i<16;i++)
    {
        revData.buf[i] = (uint8)(u[i]);
    }

    //Step2.输出[用double数组数据number进行解析]
    y[0] = revData.number[0];
    y[1] = revData.number[1];
}



#define MDL_UPDATE  /* Change to #undef to remove function */
#if defined(MDL_UPDATE)
  /* Function: mdlUpdate ======================================================
   * Abstract:
   *    This function is called once for every major integration time step.
   *    Discrete states are typically updated here, but this function is useful
   *    for performing any tasks that should only take place once per
   *    integration step.
   */
  static void mdlUpdate(SimStruct *S, int_T tid)
  {
  }
#endif /* MDL_UPDATE */



#define MDL_DERIVATIVES  /* Change to #undef to remove function */
#if defined(MDL_DERIVATIVES)
  /* Function: mdlDerivatives =================================================
   * Abstract:
   *    In this function, you compute the S-function block's derivatives.
   *    The derivatives are placed in the derivative vector, ssGetdX(S).
   */
  static void mdlDerivatives(SimStruct *S)
  {
  }
#endif /* MDL_DERIVATIVES */



/* Function: mdlTerminate =====================================================
 * Abstract:
 *    In this function, you should perform any actions that are necessary
 *    at the termination of a simulation.  For example, if memory was
 *    allocated in mdlStart, this is the place to free it.
 */
static void mdlTerminate(SimStruct *S)
{
}


/*======================================================*
 * See sfuntmpl_doc.c for the optional S-function methods *
 *======================================================*/

/*=============================*
 * Required S-function trailer *
 *=============================*/

#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 */
#endif


 
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183

3.2. 需要的头文件 - DataType.h

#ifndef _Q_DATA_TYPE_H_
#define _Q_DATA_TYPE_H_

//signed
typedef signed char        int8;
typedef short              int16;
typedef int                int32;
typedef long long          int64;
//unsigned
typedef unsigned char      uint8;
typedef unsigned short     uint16;
typedef unsigned int       uint32;
typedef unsigned long long uint64;



typedef union //
{
    char           buf[16];//用于接收
    double         number[2];//用于处理
}Un_sendData;

#endif
 
 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

4. 文件说明及下载

4.1 文件说明

  • QtSerialSend 文件夹: Qt写的串口发送程序;
  • recCom.mdl:Matlab串口接收程序;
  • recCom_Union.mdl:Matlab串口接收程序,用S-Function进行解析;
  • DataType.h : 定义发送和接收的数据类型,被unPackData_Q.c调用;
  • unPackData_Q.c:用C语言写的S-Function函数,编译后变成unPackData_Q.mexw64,被recCom_Union.mdl调用;
  • unPackData_Q.mexw64:由unPackData_Q.c编译而成,被recCom_Union.mdl调用。

IMG20180629142123

4.2 文件下载

稍后我会上传这些资料到下载区:

  • Matlab接收程序下载:https://download.csdn.net/download/humanking7/10510716
  • Qt发送程序下载:https://download.csdn.net/download/humanking7/10510720

最后

以上就是拉长鼠标为你收集整理的[Matlab]Simulink串口接收详解2用S-Function解析数据包1.概述2. 效果3. S-Function源码4. 文件说明及下载的全部内容,希望文章能够帮你解决[Matlab]Simulink串口接收详解2用S-Function解析数据包1.概述2. 效果3. S-Function源码4. 文件说明及下载所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(72)

评论列表共有 0 条评论

立即
投稿
返回
顶部