⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 regshift.c

📁 数字通信第四版原书的例程
💻 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 + -