📄 regshift.c
字号:
/*
* REGSHIFT A SIMULINK trigged register_buff shift
*
* Syntax: [sys, x0] = regshift(t,x,u,flag,outDelay,tirgThreshold)
* This function has two inputs and number of outputs. The first input is
* the signal to be stored and output. The second signal is the clock pulse.
* The function refresh its register_buff and output only at the raising edge of
* the clock pulse. The function assign maximum delay number in outDelay as its
* register numebr. When the function finish refreshing all register, it is
* call a cycle.
*
* outDelay is a scalar or vector which contains integers of desired delay
* steps from the input. The size of the vector determines the
* size of the output.
* trigThreshold is the threshold in detecting the raising edge of the clock
* pulse.
* the size of the output of this function is the size of outDelay pulse one.
* Each output element outputs the delay step as indicated in the corrsponding
* value in outDelay. The last output is zero. It is one only at the time when
* the register_buff and output are triggered in a complete cycle (a cycle of
* complete a refresh cycle). The pulse keeps the same length as the input
* trigger pulse.
*
* Wes Wang August 22, 1994
* Copyright (c) 1994-96 by The MathWorks, Inc.
* All Rights Reserved
* $Revision: 1.1 $ $Date: 1996/04/01 19:03:56 $
*/
#define S_FUNCTION_NAME regshift
#include <stdio.h> /* needed for declaration of sprintf */
#ifdef MATLAB_MEX_FILE
#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 2
#define REGISTER_DELAY ssGetArg(S,0)
#define TRIG_THRESHOLD ssGetArg(S,1)
/*
* 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, regDelay, numOutput, maxDelay;
/* char err_msg[256];
*/
numOutput = mxGetN(REGISTER_DELAY) * mxGetM(REGISTER_DELAY);
if (numOutput < 1) {
#ifdef MATLAB_MEX_FILE
char err_msg[256];
sprintf(err_msg, "Output buffer is empty");
mexErrMsgTxt(err_msg);
#endif
}
maxDelay = 1;
for(i=0; i<numOutput; i++) {
regDelay = (int)(mxGetPr(REGISTER_DELAY)[i]);
maxDelay = (maxDelay > regDelay) ? maxDelay : regDelay;
}
/* sprintf(err_msg, "From initialization maxDelay %d, numOutput %d.\n", maxDelay, numOutput);
mexPrintf(err_msg);
*/
ssSetNumContStates( S, 0);
ssSetNumDiscStates( S, 0);
ssSetNumInputs( S, 2);
ssSetNumOutputs( S, 1 + numOutput);
ssSetDirectFeedThrough(S, 1);
ssSetNumInputArgs( S, NUM_ARGS);
ssSetNumSampleTimes( S, 1);
ssSetNumRWork( S, maxDelay+1);
ssSetNumIWork( S, 2);
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;
{
double *register_buff = ssGetRWork(S);
int *regIndex = ssGetIWork(S);
int *lastTrig = ssGetIWork(S) + 1;
int numOutput = ssGetNumOutputs(S);
int maxDelay = ssGetNumRWork(S) - 1;
double *lastTime = ssGetRWork(S) + maxDelay;
int i;
/*
* Initialize the register_buff to all zeros.
*/
for (i = 0; i < maxDelay; i++)
*register_buff++ = 0.0;
/*
* Initialize the current buffer position and buffer start
*/
*regIndex = 0;
*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 *register_buff = ssGetRWork(S);
double trigThreshold = mxGetPr(TRIG_THRESHOLD)[0];
int *regIndex = ssGetIWork(S);
int *lastTrig = ssGetIWork(S) + 1;
int numOutput = ssGetNumOutputs(S) - 1;
int maxDelay = ssGetNumRWork(S) - 1;
double *lastTime = ssGetRWork(S) + maxDelay;
int i, outnum;
double currentTime = ssGetT(S);
/* 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 ((u[1] >= trigThreshold) & (*lastTrig == 0)) {
for (i = 0; i < numOutput; i++) {
outnum = mxGetPr(REGISTER_DELAY)[i];
if (outnum == 0)
y[i] = *u;
else
y[i] = register_buff[(maxDelay + *regIndex - outnum) % maxDelay];
}
if (*regIndex == 0)
y[numOutput] = 1.0;
else
y[numOutput] = 0.0;
register_buff[(*regIndex)++] = *u;
*regIndex %= maxDelay;
*lastTrig = 1;
*lastTime = currentTime;
} else {
if (currentTime <= 0.0) {
for (i = 0; i < numOutput; i++)
y[i] = 0.0;
} else if ((currentTime - *lastTime) / currentTime < 0.00000001) {
/* keep the most recent change in the buffer */
/* this is backup the case when there are tow calls at the same time.
* the two values of the same time are different.
* This is assume the time variable is always increasing
*/
if (u[1] >= trigThreshold) {
int backIndex;
/* char err_msg[256];
*/
backIndex = *regIndex - 1;
if (backIndex < 0)
backIndex = maxDelay - 1;
/* sprintf(err_msg, "backIndex %d, regIndex %d, maxDelay %d\n", backIndex, *regIndex, maxDelay);
mexPrintf(err_msg);
*/
/* sprintf(err_msg, "currentTime %f, lastTime %f, current u %f, last u %f\n", currentTime, *lastTime, *u, register_buff[backIndex]);
mexPrintf(err_msg);
*/
for (i = 0; i < numOutput; i++) {
outnum = mxGetPr(REGISTER_DELAY)[i];
/* sprintf(err_msg, "outnum %d, modulo(outnum)%d\n", outnum, (maxDelay + backIndex - outnum) % maxDelay);
mexPrintf(err_msg);
*/
if (outnum == 0)
y[i] = *u;
/* else
y[i] = register_buff[(maxDelay + backIndex - outnum) % maxDelay];
*/
}
if (backIndex == 0)
y[numOutput] = 1.0;
else
y[numOutput] = 0.0;
register_buff[backIndex] = *u;
}
}
if (*lastTrig == 1) {
if (u[1] < trigThreshold) {
*lastTrig = 0;
y[numOutput] = 0.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 + -