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

📄 regdown.c

📁 Proakis《contemporarycommunication systems using matlab》matlab源代码
💻 C
字号:
/*
 * REGDOWN   A SIMULINK register down block
 *
 * Syntax:  [sys, x0] = regdown(t, x, u, flag, OutputIndex, Increament, trigThreshold, cycl_flag)
 *      This block output a vector with the initial index given in OutputIndex.
 *      the increament of the index is given in Increament. This block has three
 *      input veriables. The first is a vector providing the register signals.
 *      The second is a clock signal trigger the refreshment of the register in
 *      in this block. The third is a trigger signal for the output refreshment.
 *      The block using the raising edge of both second and third input pulse
 *      in trigger the action. At the raising edge of the third signal, a positive
 *      signal at the third inport would cause the output refreshemnt.
 *
 * Wes Wang 8/23, 1994
 *
 * Copyright (c) 1994-96 by The MathWorks, Inc.
 * All Rights Reserved
 * $Revision: 1.1 $  $Date: 1996/04/01 19:03:47 $
 */

#define S_FUNCTION_NAME regdown

#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 OUTPUT_INDEX   ssGetArg(S,0)
#define INCREAMENT     ssGetArg(S,1)
#define TRIG_THRSHLD   ssGetArg(S,2)
#define CYCLIC_FLAG    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;
{
    int num_output_idx, num_increament;
    
    /*
     * Set-up size information.
     */ 

    if (ssGetNumArgs(S) == NUM_ARGS) {
        /* check the dimension for OUTPUT_INDEX and INCREAMNET */
        num_output_idx = mxGetN(OUTPUT_INDEX) * mxGetM(OUTPUT_INDEX);
        num_increament  = mxGetN(INCREAMENT)   * mxGetM(INCREAMENT);
        if (num_output_idx <= 0) {
#ifdef MATLAB_MEX_FILE
            mexErrMsgTxt("OutputIndex cannot be a empty vector.");
#endif        
        }
        if (num_output_idx != num_increament) {
            if (num_increament != 1) {
#ifdef MATLAB_MEX_FILE
                mexErrMsgTxt("The vector size for OutputIndex and Increment must be the same.");
#endif
            }
        }
    
        if ((mxGetN(TRIG_THRSHLD)*mxGetM(TRIG_THRSHLD) != 1)) {
#ifdef MATLAB_MEX_FILE
            mexErrMsgTxt("The threshold must be a scalar.");
#endif
        } 
       
        ssSetNumContStates(    S, 0);
        ssSetNumDiscStates(    S, 0);
        ssSetNumInputs(        S, -1);
        ssSetNumOutputs(       S, 1 + num_output_idx);
        ssSetDirectFeedThrough(S, 1);
        ssSetNumInputArgs(     S, NUM_ARGS);
        ssSetNumSampleTimes(   S, 1);
        ssSetNumRWork(         S, -1);
        /* the buffer size is input_vector + trig_in + trig_out
         * R vector is assigned as buffer, lastTime2, lastTime3
         */
        ssSetNumIWork(         S, 2 + num_output_idx);
        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 num_output_idx   = ssGetNumOutputs(S) - 1;
    double *regi         = ssGetRWork(S);

    int *lastTrig2       = ssGetIWork(S);
    int *lastTrig3       = ssGetIWork(S) + 1;
    int *outputIndex     = ssGetIWork(S) + 2; 

    int *increament      = ssGetIWork(S) + num_output_idx + 2;

    int num_increament   = mxGetN(INCREAMENT) * mxGetM(INCREAMENT);

    int regiSize         = ssGetNumInputs(S) - 2;

    int i;

    /* 
     * Initialize the buffer to all zeros, we could allow this to
     * be an additional paramter.
     */
    
    for (i = 0; i < regiSize; i++)
        *regi++ = 0.;
    /*
     * Initialize the current buffer position, buffer start, and output index
     */
    
    for (i = 0; i < num_output_idx; i++) {
        if (mxGetPr(OUTPUT_INDEX)[i] < 0) {
#ifdef MATLAB_MEX_FILE
             mexErrMsgTxt("Output Index must be positive integers.");
#endif
                }
        *outputIndex++ = mxGetPr(OUTPUT_INDEX)[i];
        if (num_increament == 1) {
            *increament++ = mxGetPr(INCREAMENT)[0];
                } else {
            *increament++ = mxGetPr(INCREAMENT)[i];
        }
    }
    *lastTrig2 = 0;
    *lastTrig3 = 0;
    if (regiSize >= 0) {
        double *lastTime2    = ssGetRWork(S) + regiSize;
        double *lastTime3    = ssGetRWork(S) + regiSize + 1;
        *lastTime2 = -1.0;
        *lastTime3 = -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;
{
    int num_output_idx   = ssGetNumOutputs(S) - 1;
    double *regi         = ssGetRWork(S);
    double  trigThreshold   = mxGetPr(TRIG_THRSHLD)[0];
    
    int *lastTrig2       = ssGetIWork(S);
    int *lastTrig3       = ssGetIWork(S) + 1;
    int *outputIndex     = ssGetIWork(S) + 2; 

    int *increament      = ssGetIWork(S)+ num_output_idx + 2;

    int regiSize         = ssGetNumInputs(S) - 2;

    double *lastTime2    = ssGetRWork(S) + regiSize;
    double *lastTime3    = ssGetRWork(S) + regiSize + 1;
    double currentTime   = ssGetT(S);
    
    int cycl_flag   = (int)mxGetPr(CYCLIC_FLAG)[0];
    
    int i, modulo_idx;
/*    char    err_msg[256];
 */
  
/*    sprintf(err_msg, "regiSize %d, num_output_idx %d, u[regiSize] %f, u[regiSize+1] %f.\n", regiSize, num_output_idx, u[regiSize], u[regiSize+1]);
    mexPrintf(err_msg);
 */

    if ((u[regiSize] >= trigThreshold) & (*lastTrig2 == 0)) {
/*        sprintf(err_msg, "Refresh register at time %f\n", ssGetT(S));
        mexPrintf(err_msg);
 */
        /* refresh the registers */
        for (i = 0; i < regiSize; i++)
            regi[i] = u[i];
        /* refresh output index */
        for (i = 0; i < num_output_idx; i++)
            outputIndex[i] = mxGetPr(OUTPUT_INDEX)[i];
        /* reset trigger flag */
        *lastTrig2 = 1;
        y[num_output_idx] = 1;
        *lastTime2 = currentTime;
/*        sprintf(err_msg, "u[regiSize+1] %f, threshold %f.\n", u[regiSize+1], trigThreshold);
        mexPrintf(err_msg);
 */
    } else {
        if (u[regiSize] >= trigThreshold) {
            if (currentTime > 0) {
                if ((currentTime - *lastTime2) / currentTime < 0.00000001) {
                    /* re-refresh the buffer, use the most recent one */
                    for (i = 0; i < regiSize; i++)
                        regi[i] = u[i];
                    /* verify whether the output needs to refresh */
                    if ((u[regiSize + 1] >= trigThreshold) && ((currentTime - *lastTime3) / currentTime < 0.00000001)) {
                        int backIndex;
                
                        for (i = 0; i < num_output_idx; i++) {
                            backIndex = outputIndex[i] - increament[i];

                            if (cycl_flag > 0) {
                                if (backIndex >= 0)
                                    backIndex %= regiSize;
                                else 
                                    backIndex = (regiSize - ((-backIndex) % regiSize)) % regiSize;
/*           sprintf(err_msg, "backIndex %d, regiSize %d, currentTime %f.\n", backIndex, regiSize, currentTime);
            mexPrintf(err_msg);
 */            
                                y[i] = regi[backIndex];
                            } else {
                                if ((backIndex < regiSize) & (backIndex >= 0))
                                    y[i] = regi[backIndex];
                                else
                                    y[i] = 0.0;
                                               }
                                               }
                                       }
                       }
               }
       } else if (*lastTrig2 == 1) {
           if (u[regiSize] < trigThreshold) {
                  *lastTrig2 = 0;
                y[num_output_idx] = 0.0;
                     }
               }
       }
    if ((u[regiSize + 1] >= trigThreshold) & (*lastTrig3 == 0)) {
/*        mexPrintf("In Trigger 3\n");
 */
        for (i = 0; i < num_output_idx; i++) {
            /* refresh output */
/*          sprintf(err_msg, "OutputIndex %d, Increament %d, y %f, time %f.\n", outputIndex[i], increament[i], regi[outputIndex[i]], ssGetT(S));
            mexPrintf(err_msg);
 */
            if (cycl_flag > 0) {
                modulo_idx = outputIndex[i];
                if (modulo_idx >= 0)
                    modulo_idx %= regiSize;
                else 
                    modulo_idx = (regiSize - ((-modulo_idx) % regiSize)) % regiSize;
                y[i] = regi[modulo_idx];
            } else {
                if ((outputIndex[i] < regiSize) & (outputIndex[i] >= 0))
                    y[i] = regi[outputIndex[i]];
                else
                    y[i] = 0.0;
            }

            /* refresh output index */                
            outputIndex[i] += increament[i];
        }
        *lastTrig3 = 1;
        *lastTime3 = currentTime;
  } else {
            if (*lastTrig3 == 1) {
              if (u[regiSize+1] < trigThreshold)
                  *lastTrig3 = 0;
         }
               if (ssGetT(S) <= 0.0) {
            for (i = 0; i < num_output_idx; i++)
                     y[i] = 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 + -