📄 stdmamux.c
字号:
/*
* SIMULINK TDMA MUX/DEMUX block.
*
* Syntax: [sys, x0] = stdmamux(t, x, u, flag, switch_box, keeping_value, ini_value)
* This function takes multi-input and it may be multi-output
* depending on the variable switch_box, keeping_value and ini_value
* assignement. This block takes N+1 input. The first N input is the
* signal. The last signal of the block input triggers the
* switch. The block sending initial value before trigger signal is received
*
* switch_box: The colum number is the block output number. The row
* number decides how many switching options. The element
* value of the block are in the range [0, N], where N
* is the vector length of the signal input of this block.
* This block switch the output at the raising edge of the
* trigger signal. When the content of the output is 0,
* this block output the specified initial value, or 0,
* or the last value of the output depending -1, 0, 1 of
* the keeping_value.
* keeping_value: The keeping value should be a vector with its length
* same as the column number of the variable switch_box.
* ini_value: The initial value of the block output. The vector size
* is the same as the column number of the switch_box.
* The vector size of this block is the same as the column number of
* the variable switch_box, as well as the vector size of
* keeping_value and ini_value.
*
* Wes Wang March 6, 1995
* Copyright (c) 1995-96 by The MathWorks, Inc.
* All Rights Reserved
* $Revision: 1.1 $ $Date: 1996/04/01 19:05:46 $
*/
#define S_FUNCTION_NAME stdmamux
#ifdef MATLAB_MEX_FILE
#include <stdio.h> /* needed for declaration of sprintf */
#include "mex.h" /* needed for declaration of mexErrMsgTxt */
#endif
/*
* need to include simstruc.h for the definition of the SimStruct and
* its associated macro definitions.
*/
#include "simstruc.h"
/*
* Defines for easy access of the input parameters
*/
#define NUM_ARGS 4
#define SWITCH_BOX ssGetArg(S,0)
#define KEEP_VALUE ssGetArg(S,1)
#define INI__VALUE ssGetArg(S,2)
#define TTHRESHOLD ssGetArg(S,3)
/*
* mdlInitializeSizes - called to initialize the sizes array stored in
* the SimStruct. The sizes array defines the
* characteristics (number of inputs, outputs,
* states, etc.) of the S-Function.
*/
static void mdlInitializeSizes(S)
SimStruct *S;
{
/*
* Set-up size information.
*/
if (ssGetNumArgs(S) == NUM_ARGS) {
int i, numoutput;
/* char err_msg[256];
*/
numoutput = mxGetN(INI__VALUE) * mxGetM(INI__VALUE);
if (numoutput < 1) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Empty initial variable assignment.");
mexErrMsgTxt(err_msg);
#endif
}
if (mxGetN(KEEP_VALUE) * mxGetM(KEEP_VALUE) != numoutput) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Keep_Value should have the same vector size as Ini_Value.");
mexErrMsgTxt(err_msg);
#endif
}
if (mxGetN(TTHRESHOLD) * mxGetM(TTHRESHOLD) != 1) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Threshold must be a scalar.");
mexErrMsgTxt(err_msg);
#endif
}
if (mxGetN(SWITCH_BOX) != numoutput) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "The column number of Switch_Box must match the vector size of Ini_Value.");
mexErrMsgTxt(err_msg);
#endif
}
ssSetNumContStates( S, 0);
ssSetNumDiscStates( S, 0);
ssSetNumInputs( S, -1);
ssSetNumOutputs( S, numoutput);
ssSetDirectFeedThrough(S, 1);
ssSetNumInputArgs( S, NUM_ARGS);
ssSetNumSampleTimes( S, 1);
ssSetNumRWork( S, 1);
ssSetNumIWork( S, 2 + numoutput);
ssSetNumPWork( S, 0);
} else {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Wrong number of input arguments passed to S-function MEX-file.\n"
"%d input arguments were passed in when expecting %d input arguments.\n", ssGetNumArgs(S) + 4, NUM_ARGS + 4);
mexErrMsgTxt(err_msg);
#endif
}
}
/*
* mdlInitializeSampleTimes - initializes the array of sample times stored in
* the SimStruct associated with this S-Function.
*/
static void mdlInitializeSampleTimes(S)
SimStruct *S;
{
/*
* Note, blocks that are continuous in nature should have a single
* sample time of 0.0.
*/
ssSetSampleTimeEvent(S, 0, 0.0);
ssSetOffsetTimeEvent(S, 0, 0.0);
}
/*
* mdlInitializeConditions - initializes the states for the S-Function
*/
static void mdlInitializeConditions(x0, S)
double *x0;
SimStruct *S;
{
int *regIndex = ssGetIWork(S);
int *lastTrig = ssGetIWork(S) + 1;
double *lastTime = ssGetRWork(S);
/*
* Initialize the current buffer position and buffer start
*/
*regIndex = -1;
*lastTrig = 0;
*lastTime = -1.0;
}
/*
* mdlOutputs - computes the outputs of the S-Function
*/
static void mdlOutputs(y, x, u, S, tid)
double *y, *x, *u;
SimStruct *S;
int tid;
{
double trigThreshold = mxGetPr(TTHRESHOLD)[0];
int *regIndex = ssGetIWork(S);
int *lastTrig = ssGetIWork(S) + 1;
int numoutput = ssGetNumOutputs(S);
int numinput = ssGetNumInputs(S);
double *lastTime = ssGetRWork(S);
int Index;
int i, outnum, m_switch_box;
double currentTime = ssGetT(S);
/* char err_msg[256]; */
/* char err_msg[256];
sprintf(err_msg, "**MAXDELAY %d, u[1] %f, *lastTrig %d, thrshold %f, time %f.\n", maxDelay, u[1], *lastTrig, trigThreshold, currentTime);
mexPrintf(err_msg);
*/
/*
* acquire the buffer data
*/
if (currentTime <= 0.0) {
for (i=0; i<numoutput; i++)
y[i] = mxGetPr(INI__VALUE)[i];
}
m_switch_box = mxGetM(SWITCH_BOX);
/* sprintf(err_msg, "m_switch_box %d, *regIndex %d, time %f., lastTrig %d, u[numinput-1], %f, threshold %f\n", m_switch_box, *regIndex, currentTime, *lastTrig, u[numinput-1], trigThreshold);
mexPrintf(err_msg);
*/
if ((u[numinput-1] >= trigThreshold) & (*lastTrig == 0)) {
/* time for switch to the next line of the switch_box */
/* char err_msg[256];
sprintf(err_msg, "m_switch_box %d, *regIndex %d, time %f.\n", m_switch_box, *regIndex, currentTime);
mexPrintf(err_msg);
*/
/* sprintf(err_msg, "maxDelay %d\n", maxDelay);
mexPrintf(err_msg);
*/
*regIndex += 1;
if (*regIndex >= m_switch_box)
*regIndex = 0;
for (i = 0; i < numoutput; i++) {
/* Index = (int)mxGetPr(SWITCH_BOX)[*regIndex * m_switch_box +i];*/
Index = (int)mxGetPr(SWITCH_BOX)[*regIndex + m_switch_box * i];
/* sprintf(err_msg, "outnum %d, modulo(outnum)%d\n", outnum, (maxDelay + *regIndex - outnum) % maxDelay);
mexPrintf(err_msg);
*/
if (Index <= 0) {
if (mxGetPr(KEEP_VALUE)[i] < 0)
y[i] = mxGetPr(INI__VALUE)[i];
else if (mxGetPr(KEEP_VALUE)[i] == 0)
y[i] = 0.0;
} else if (Index > numinput - 1) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "The index number in Switch_Box variable is larger than the signal input vector.");
mexErrMsgTxt(err_msg);
#endif
} else {
y[i] = u[Index-1];
}
}
*lastTrig = 1;
*lastTime = currentTime;
} else {
if (*regIndex >= 0) {
for (i = 0; i < numoutput; i++) {
/* Index = (int)mxGetPr(SWITCH_BOX)[*regIndex * m_switch_box + i];
*/
Index = (int)mxGetPr(SWITCH_BOX)[*regIndex + m_switch_box * i];
if (Index > 0)
y[i] = u[Index - 1];
}
}
if (u[numinput-1] < trigThreshold)
*lastTrig = 0;
}
}
/*
* mdlUpdate - computes the discrete states of the S-Function
*/
static void mdlUpdate(x, u, S, tid)
double *x, *u;
SimStruct *S;
int tid;
{
}
/*
* mdlDerivatives - computes the derivatives of the S-Function
*/
static void mdlDerivatives(dx, x, u, S, tid)
double *dx, *x, *u;
SimStruct *S;
int tid;
{
}
/*
* mdlTerminate - called at termination of model execution.
*/
static void mdlTerminate(S)
SimStruct *S;
{
}
#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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -