WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

s-function für PWM-unit

 

DrStrange
Forum-Newbie

Forum-Newbie


Beiträge: 2
Anmeldedatum: 29.10.20
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 11.11.2020, 17:30     Titel: s-function für PWM-unit
  Antworten mit Zitat      
Hallo zusammen,

ich habe versucht, ein PWM-unit von einem µController (NXP S12Z) mittels s-function nachzubilden.

Es funktioniert gut, wenn im Model nur eine Instanz von s-function gibt. Also für eine PWM-phase.

Nun habe ich eine zweite Instanz hinzugefügt, dann bekomme ich runtime-error.

Unten ist meine C-mex s-function
Code:

/*  File    : sfunc_pmf.c
 *  Abstract: 16bit S12Z PMF
 *
 *
 *  Copyright 1990-2013 The MathWorks, Inc.
 */

#define S_FUNCTION_NAME     sfunc_pmf
#define S_FUNCTION_LEVEL    2

#include "simstruc.h"

// Units
#define NANO                            (1e-9)
#define MICRO                           (1e-6)
#define KILO                            (1e3)
#define MEGA                            (1e6)

// no. of outputs
#define OUTPUT_NUM                      (2)

// Inputs
#define Inp_Modulus                     (*uPtrs[0])
#define Inp_PwmVal                      (*uPtrs[1])

// Discrete states
#define DiskState_Modulus               (x[0])
#define DiskState_PwmVal                (x[1])

// Parameters
#define Par_GetClockFreq()              ((*mxGetPr(ssGetSFcnParam(S, 0))) * MEGA)
#define PMF_CLK_RES                     (1.0/Par_GetClockFreq())

#define MAX_HIT_TIMES                   (3)
#define HS_INDEX                        (0)
#define LS_INDEX                        (1)
#define SEQ_HS_OFF_LS_OFF               {0, 0} // {HS_INDEX, LS_INDEX}
#define SEQ_HS_ON_LS_OFF                {1, 0}
#define SEQ_HS_OFF_LS_ON                {0, 1}
#define SET_SEQ(seq_index, HSLS_Seq)    (memcpy(sw_seqs[seq_index], (boolean_T[])HSLS_Seq, sizeof((boolean_T[])HSLS_Seq)))

real_T    TimeHit_arr[MAX_HIT_TIMES];
int_T     TimeHit_index = 0;
int_T     TimeHitIndexMax = MAX_HIT_TIMES;
boolean_T sw_seqs[MAX_HIT_TIMES][2];
real_T    NextHitTime;

#define MDL_CHECK_PARAMETERS
/* Function: mdlCheckParameters =============================================
* Abstract:
*    Validate our parameters to verify they are okay.
*/
static void mdlCheckParameters(SimStruct *S)
{
}
 
/* Function: mdlInitializeSizes ===============================================
 * Abstract:
 *    The sizes information is used by Simulink to determine the S-function
 *    block's characteristics (number of inputs, outputs, states, etc.).
 */
static void mdlInitializeSizes(SimStruct *S)
{
    ssSetNumSFcnParams(S, 1);  /* Number of expected parameters */
    if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) {
      mdlCheckParameters(S);
      if(ssGetErrorStatus(S) != NULL) return;
    } else {    
      return; // Parameter mismatch will be reported by Simulink
    }

    // set all 1 parameter(s) as not tunable
    ssSetSFcnParamTunable(S, 0 ,0 ); //  
   
    ssSetNumContStates(S, 0);
   
    // 2 Disc States
    ssSetNumDiscStates(S, 2);

    if (!ssSetNumInputPorts(S, 1)) return;
    ssSetInputPortWidth(S, 0, 2);

    if (!ssSetNumOutputPorts(S, OUTPUT_NUM)) return;
    {
        int_T i = 0;              
        for(i=0; i < OUTPUT_NUM; i++){
            ssSetOutputPortWidth(S, i, 1);
        }
    }

    ssSetNumSampleTimes(S, 1);
   
    ssSetNumRWork(S, 0);
    ssSetNumIWork(S, 0);
    ssSetNumPWork(S, 0);
    ssSetNumModes(S, 0);
    ssSetNumNonsampledZCs(S, 0);
    ssSetOperatingPointCompliance(S, USE_DEFAULT_OPERATING_POINT);

    if (ssGetSimMode(S) == SS_SIMMODE_RTWGEN && !ssIsVariableStepSolver(S)) {
        ssSetErrorStatus(S, "S-function vsfunc.c cannot be used with Simulink Coder "
                         "and Fixed-Step Solvers because it contains variable"
                         " sample time");
    }

    ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
}

/* Function: mdlInitializeSampleTimes =========================================
 * Abstract:
 *    Variable-Step S-function
 */
static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, VARIABLE_SAMPLE_TIME);
    ssSetOffsetTime(S, 0, 0.0);
    ssSetModelReferenceSampleTimeDefaultInheritance(S);
}

#define MDL_INITIALIZE_CONDITIONS
/* Function: mdlInitializeConditions ========================================
 * Abstract:
 *    Initialize discrete state.
 */
static void mdlInitializeConditions(SimStruct *S)
{
    real_T *x = ssGetRealDiscStates(S);
           
    DiskState_Modulus = 1000;
    DiskState_PwmVal = (uint16_T)0;
   
    TimeHit_index = 0;            
    NextHitTime = 0.0;
}



#define MDL_GET_TIME_OF_NEXT_VAR_HIT
static void mdlGetTimeOfNextVarHit(SimStruct *S)
{
    real_T *x = ssGetRealDiscStates(S);
   
    if (TimeHit_index == 0) {        // new PWM-periode begins                
        if (DiskState_PwmVal <= 0) { // Duty cycle <= 0%
            TimeHitIndexMax = 1;
            TimeHit_arr[0] = ssGetT(S) + (real_T)(DiskState_Modulus * 2.0) * PMF_CLK_RES;
            SET_SEQ(0, SEQ_HS_OFF_LS_ON);
        } else {                    // Duty cycle >= 100%            
            if (DiskState_PwmVal >= DiskState_Modulus) {
                TimeHitIndexMax = 1;
                TimeHit_arr[0] = ssGetT(S) + (real_T)(DiskState_Modulus * 2.0) * PMF_CLK_RES;
                SET_SEQ(0, SEQ_HS_ON_LS_OFF);
            } else {                // 0% < Duty cycle < 100%                                
                TimeHitIndexMax = 3;
                TimeHit_arr[0] = ssGetT(S) + (real_T)DiskState_PwmVal * PMF_CLK_RES;
                TimeHit_arr[1] = ssGetT(S) + (real_T)(DiskState_Modulus * 2.0 - DiskState_PwmVal) * PMF_CLK_RES;
                TimeHit_arr[2] = ssGetT(S) + (real_T)(DiskState_Modulus * 2.0) * PMF_CLK_RES;

                SET_SEQ(0, SEQ_HS_ON_LS_OFF);
                SET_SEQ(1, SEQ_HS_OFF_LS_ON);
                SET_SEQ(2, SEQ_HS_ON_LS_OFF);
            }
        }
    }
   
    NextHitTime = TimeHit_arr[TimeHit_index];

    /* Make sure input will increase time */
    if (NextHitTime <= ssGetT(S)) {
        /* If not, abort simulation */
        ssSetErrorStatus(S,"sfunc_pmf.c/mdlGetTimeOfNextVarHit(): Variable step control\n"
                           "Check NextHitTime!");
        ssPrintf("Error in sfunc_pmf.c/mdlGetTimeOfNextVarHit():\nTimeHit_index = %d\nNextHitTime[s] = %.f\nssGetT(S) = %.f\n",
                  TimeHit_index, NextHitTime, ssGetT(S));
        return;
    }
   
    ssSetTNext(S, NextHitTime);
   
}


/* Function: mdlOutputs =======================================================
 * Abstract:
 *      
 */
static void mdlOutputs(SimStruct *S, int_T tid)
{
    real_T *y = ssGetOutputPortRealSignal(S,0);
           
    y[0] = sw_seqs[TimeHit_index][HS_INDEX];
    y[1] = sw_seqs[TimeHit_index][LS_INDEX];
           
}



#define MDL_UPDATE
/* Function: mdlUpdate ========================================================
 * Abstract:
 *    This function is called once for every major integration time step.
 *    Discrete states are typically updated here, but this function is useful
 *    for performing any tasks that should only take place once per integration
 *    step.
 */
static void mdlUpdate(SimStruct *S, int_T tid)
{
    real_T            *x    = ssGetRealDiscStates(S);
    InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);
       

    // time to latch new duty and modulus
    if(TimeHit_index == 0){
        DiskState_Modulus = (real_T)((uint16_T)Inp_Modulus);
        DiskState_PwmVal  = (real_T)((uint16_T)Inp_PwmVal);
        if((Inp_PwmVal < 0) || (Inp_Modulus < 0)){
            ssSetErrorStatus(S,"sfunc_pmf.c/mdlUpdate(): Input(s) Reload and CmpVal must be > 0!\n");
        }
    }
       
    TimeHit_index++;
    if(TimeHit_index >= TimeHitIndexMax){
        TimeHit_index = 0;            
    }

}

/* Function: mdlTerminate =====================================================
 * Abstract:
 *    No termination needed, but we are required to have this routine.
 */
static void mdlTerminate(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

 


Bitte seht Euch im Anhang.

Könnt ihr bitte mir helfen?

Vielen Dank im Voraus!
Tony

pmf.slx
 Beschreibung:
PWM-model

Download
 Dateiname:  pmf.slx
 Dateigröße:  27.32 KB
 Heruntergeladen:  216 mal
sfunc_pmf.c
 Beschreibung:
C-mex s-function

Download
 Dateiname:  sfunc_pmf.c
 Dateigröße:  7.51 KB
 Heruntergeladen:  222 mal
zwei Instanze_error.PNG
 Beschreibung:

Download
 Dateiname:  zwei Instanze_error.PNG
 Dateigröße:  64.48 KB
 Heruntergeladen:  195 mal
eine Instanz_OK.PNG
 Beschreibung:

Download
 Dateiname:  eine Instanz_OK.PNG
 Dateigröße:  58.95 KB
 Heruntergeladen:  198 mal
nxp_pwm.PNG
 Beschreibung:
PWM-Unit

Download
 Dateiname:  nxp_pwm.PNG
 Dateigröße:  39.96 KB
 Heruntergeladen:  191 mal
Private Nachricht senden Benutzer-Profile anzeigen


DrStrange
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 2
Anmeldedatum: 29.10.20
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 19.11.2020, 14:32     Titel:
  Antworten mit Zitat      
für newbee wie ich:

Man muss die global-variable mit Work-vektor realisieren.
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.