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

📄 homopuls.c

📁 Proakis《contemporarycommunication systems using matlab》matlab源代码
💻 C
字号:
/*
 * HOMOPULS   A SIMULINK homonic pulse generator.
 *
 *           Syntax:  [sys, x0] = homopuls(t,x,u,flag,sample,divider,offset)
 *
 * Wes Wang  8/18/1994 revised 1/24/1996.
 * Copyright (c) 1994-96 by The MathWorks, Inc.
 * All Rights Reserved
 * $Revision: 1.1 $  $Date: 1996/04/01 19:02:56 $
 */

#define S_FUNCTION_NAME homopuls

#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     3
#define SAMPLE_TIME       ssGetArg(S,0)
#define DIVIDER_EACH      ssGetArg(S,1)
#define OFFSET_EACH       ssGetArg(S,2)

/*
 * 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 dividerSize;
        if ((mxGetN(SAMPLE_TIME) * mxGetM(SAMPLE_TIME)) > 1) {
#ifdef MATLAB_MEX_FILE
                mexErrMsgTxt("The sample time is a scalar.");
#endif
         }

       if ((mxGetN(DIVIDER_EACH) != 1) && (mxGetM(DIVIDER_EACH) != 1)) {
#ifdef MATLAB_MEX_FILE
             mexErrMsgTxt("The divider must be a vector");
#endif
         }
               
        if ((mxGetN(OFFSET_EACH) != 1) && (mxGetM(OFFSET_EACH) != 1)) {
#ifdef MATLAB_MEX_FILE
               mexErrMsgTxt("The offset must be a vector");
#endif
          }
               
        if ((mxGetN(OFFSET_EACH) * (mxGetM(OFFSET_EACH))) != ((mxGetN(DIVIDER_EACH) * (mxGetM(DIVIDER_EACH))))) {
#ifdef MATLAB_MEX_FILE
             mexErrMsgTxt("Divider and Offset must have the same length");
#endif
         }

       dividerSize = mxGetN(DIVIDER_EACH) * mxGetM(DIVIDER_EACH);
      ssSetNumContStates(    S, 0);
           ssSetNumDiscStates(    S, 0);
           ssSetNumInputs(        S, 0);
           ssSetNumOutputs(       S, dividerSize);
         ssSetDirectFeedThrough(S, 0);
           ssSetNumInputArgs(     S, NUM_ARGS);
            ssSetNumSampleTimes(   S, dividerSize);
         ssSetNumRWork(         S, 4*dividerSize+2); /* store the timing */
      ssSetNumIWork(         S, dividerSize); /* store the last time access. */
         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;
{

    double sampleTime, offsetTime, tmp;
    int i, dividerSize, adj;
    int *reverse = ssGetIWork(S);    
 
    sampleTime = mxGetPr(SAMPLE_TIME)[0];
    dividerSize = mxGetN(DIVIDER_EACH) * mxGetM(DIVIDER_EACH);

    for (i=0; i < dividerSize; i++) {
        offsetTime = mxGetPr(OFFSET_EACH)[i];
        tmp = sampleTime/2./mxGetPr(DIVIDER_EACH)[i];
        ssSetSampleTimeEvent(S, i, tmp);
        adj = (int)(offsetTime / tmp);
        tmp = offsetTime - ((double)adj) * tmp;
        ssSetOffsetTimeEvent(S, i, tmp);
/*
        if (tmp != offsetTime - ((double)((int)(offsetTime/tmp/2))) * tmp *2) {
            reverse[i] = 1;
        } else {
            reverse[i] = 0;
        }
 */
    }
}

/*
 * mdlInitializeConditions - initializes the states for the S-Function
 */

static void mdlInitializeConditions(x0, S)
        double *x0;
        SimStruct *S;
{

    int dividerSize = mxGetN(DIVIDER_EACH) * mxGetM(DIVIDER_EACH);
    double *hit_base      = ssGetRWork(S);
    double *next_hit      = ssGetRWork(S) + 1;    
    double *last_value    = ssGetRWork(S) + dividerSize + 1;
    double *increment     = ssGetRWork(S) + dividerSize * 2 + 1;
    double *adj_offset    = ssGetRWork(S) + dividerSize * 3 + 1;
    double *tolerance    = ssGetRWork(S) + dividerSize * 4 + 1;
    int    *reverse = ssGetIWork(S);        
    double sampleTime, offsetTime, offsetMin, tmp, tol;
    int i, adj;

    offsetMin = mxGetPr(OFFSET_EACH)[0];
    sampleTime = mxGetPr(SAMPLE_TIME)[0];
    /* 
     * Initialize the last_accs to all zeros.
     */
    tol = sampleTime;
    for (i = 0; i < dividerSize; i++) {
     *last_value++ = 0.;

        offsetTime = mxGetPr(OFFSET_EACH)[i];        
        offsetMin = (offsetMin < offsetTime) ? offsetMin : offsetTime;

        next_hit[i] = offsetTime;

        tmp = sampleTime/2./mxGetPr(DIVIDER_EACH)[i];
        increment[i] = tmp;

        tol = (tol < tmp) ? tol : tmp;
        
        adj = (int)(offsetTime / tmp);
        tmp = offsetTime - ((double)adj) * tmp;
        if (tmp != offsetTime - ((double)((int)(offsetTime/tmp/2))) * tmp *2) {
            reverse[i] = 1;
        } else {
            reverse[i] = 0;
        }
#ifdef MATLAB_MEX_FILE
        if (0) {
           char err_msg[255];
           sprintf(err_msg, "reverse[%d]=%d; ", i, reverse[i]);
           mexPrintf(err_msg);
        }
#endif
        adj_offset[i] = tmp;
        if (tmp > 0)
            tol = (tol < tmp) ? tol : tmp;        
    }
#ifdef MATLAB_MEX_FILE
    if (0) {
       char err_msg[255];
       sprintf(err_msg, "\n");
       mexPrintf(err_msg);
    }
#endif
    *hit_base = offsetMin + sampleTime;
    *hit_base = sampleTime;
    *tolerance = tol / 100;
}

/*
 * 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 dividerSize = mxGetN(DIVIDER_EACH) * mxGetM(DIVIDER_EACH);
    double *hit_base      = ssGetRWork(S);
    double *next_hit      = ssGetRWork(S) + 1;    
    double *last_value    = ssGetRWork(S) + dividerSize + 1;
    double *increment     = ssGetRWork(S) + dividerSize * 2 + 1;
    double *adj_offset    = ssGetRWork(S) + dividerSize * 3 + 1;
    double *tolerance     = ssGetRWork(S) + dividerSize * 4 + 1;
    int    *reverse = ssGetIWork(S);
    
    double time_clock, tol;
    int i;

    tol = *tolerance;
    
    time_clock = ssGetT(S) + tol;
    for (i = 0; i < dividerSize; i++) {
        if (time_clock >= next_hit[i]) {
            int    num;
            double sampleTime;

            sampleTime = mxGetPr(SAMPLE_TIME)[0];        
            num = (int)((time_clock - *hit_base - adj_offset[i] - sampleTime) / increment[i]);
            num = num%2;
            if (num)
               last_value[i] = 1.;
            else
               last_value[i] = 0.;
#ifdef MATLAB_MEX_FILE
        if (0) {
           char err_msg[255];
           sprintf(err_msg, "reverse[%d]=%d; last_value=%d; ", i, reverse[i], (int)last_value[i]);
           mexPrintf(err_msg);
        }
#endif
            if (reverse[i])
               last_value[i] = ((int)last_value[i] + 1) % 2;
#ifdef MATLAB_MEX_FILE
        if (0) {
           char err_msg[255];
           sprintf(err_msg, "new_last_value=%d;\n ", (int)last_value[i]);
           mexPrintf(err_msg);
        }
#endif
            next_hit[i] = next_hit[i] + increment[i];
        }
        y[i] = last_value[i];
    }
    
/*    sprintf(err_msg, "\n ");
    mexPrintf(err_msg);

    for (i = 0; i < dividerSize; i++) {
       sprintf(err_msg, "output_y[%d]= %f, ", i, y[i]);
       mexPrintf(err_msg);
     }
 */
  /* adjust the "current hit" every sample cycle.    */
    if (time_clock > *hit_base){
        double sampleTime;
        sampleTime = mxGetPr(SAMPLE_TIME)[0];        
        for (i = 0; i < dividerSize; i++) {
            if (time_clock > mxGetPr(OFFSET_EACH)[i]) {
          
                if (adj_offset[i] <= 0) {
                    next_hit[i] = *hit_base + increment[i];
                } else {
                    next_hit[i] = *hit_base + adj_offset[i];
                }
            }
        }
        *hit_base = *hit_base + sampleTime;        
    }    
}

/*
 * 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 + -