dcm_h.c

来自「用C语言编写的在Simulink环境下对转速可调永磁直流电机进行数值仿真的S函数」· C语言 代码 · 共 285 行

C
285
字号
/*  File    : stspace.c
 *  Abstract:
 *
 *      Example mex file S-function for state-space system.
 *
 *      Implements a set of state-space equations.
 *      You can turn this into a new block by using the
 *      S-function block and Mask facility.
 *
 *      This example MEX-file performs the same function
 *      as the built-in State-space block. This is an
 *      example of a MEX-file where the number of inputs,
 *      outputs, and states is dependent on the parameters
 *      passed in from the workspace.
 *
 *      Syntax  [sys, x0] = stspace(t,x,u,flag,A,B,C,D,X0)
 *
 *      For more details about S-functions, see simulink/src/sfuntmpl_doc.c
 *
 *  Copyright 1990-2002 The MathWorks, Inc.
 *  $Revision: 1.12 $
 */

#define S_FUNCTION_NAME DCM_H
#define S_FUNCTION_LEVEL 2

#include "simstruc.h"
#include "math.h"

#define R_IDX 0  //DC motor armature esister
#define R_PARAM(S) ssGetSFcnParam(S,R_IDX)
 
#define L_IDX 1  //DC motor armature inductance
#define L_PARAM(S) ssGetSFcnParam(S,L_IDX)

#define Ce_IDX 2  //DC motor armature inductance
#define Ce_PARAM(S) ssGetSFcnParam(S,Ce_IDX)

#define GD_IDX 3  //DC motor armature inductance
#define GD_PARAM(S) ssGetSFcnParam(S,GD_IDX)

#define Vs_IDX 4  //DC link voltage
#define Vs_PARAM(S) ssGetSFcnParam(S,Vs_IDX)

#define FreeWheelingMode_IDX 5  //H_bridge free wheeling mode
#define FreeWheelingMode_PARAM(S) ssGetSFcnParam(S,FreeWheelingMode_IDX)
 
#define X0_IDX 6  //initial value of the system states,namely,the armature current,the shaft speed and the shaft position
#define X0_PARAM(S) ssGetSFcnParam(S,X0_IDX)

#define NPARAMS 7
/*3 continous states,namely motor armature current,motor shaft speed*/
#define NSTATES 2

const real_T  pai = 3.14159;
/*criterium for freewheeling state*/
const real_T  delta = 0.01;
/*====================*
 * S-function methods *
 *====================*/

/* 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, NPARAMS);  /* Number of expected parameters */
#if defined(MATLAB_MEX_FILE)
    if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) {
        
        if (ssGetErrorStatus(S) != NULL) {
            return;
        }
    } else {
        return; /* Parameter mismatch will be reported by Simulink */
    }
#endif

    ssSetNumContStates(S, NSTATES);
    ssSetNumDiscStates(S, 0);

    /*block contains 2 input ports,with PWM control signal as one and DIR control signal as the other*/
    if (!ssSetNumInputPorts(S, 3)) return;
    /*PWM control bit*/
    ssSetInputPortWidth(S, 0, 1);
    /*DIR,namely rotation direction control bit*/
    ssSetInputPortWidth(S, 1, 1);
    /*Load torque on the shaft*/
    ssSetInputPortWidth(S, 2, 1);
    /*system contains no direct fedthru states*/
    ssSetInputPortDirectFeedThrough(S, 0, 0);
    ssSetInputPortDirectFeedThrough(S, 1, 0);
    ssSetInputPortDirectFeedThrough(S, 2, 0);

    /*block contains 3 output ports, namely the motor output electromagnetical torque,motor shaft speed,and motor shaft 
     *position*/
    if (!ssSetNumOutputPorts(S, 3)) return;
    ssSetOutputPortWidth(S, 0, 1);
    ssSetOutputPortWidth(S, 1, 1);
    ssSetOutputPortWidth(S, 2, 1);

    ssSetNumSampleTimes(S, 1);
    /*
    ssSetNumRWork(S, 0);
    ssSetNumIWork(S, 0);
    ssSetNumPWork(S, 0);
    ssSetNumModes(S, 0);
    ssSetNumNonsampledZCs(S, 0);
           */
    /* Take care when specifying exception free code - see sfuntmpl_doc.c */
    ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
}



/* Function: mdlInitializeSampleTimes =========================================
 * Abstract:
 *    S-function is comprised of only continuous sample time elements
 */
static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
    ssSetOffsetTime(S, 0, 0.0);
}



#define MDL_INITIALIZE_CONDITIONS
/* Function: mdlInitializeConditions ========================================
 * Abstract:
 *    If the initial condition parameter (X0) is not an empty matrix,
 *    then use it to set up the initial conditions, otherwise,
 *    set the intial conditions to all 0.0
 */
static void mdlInitializeConditions(SimStruct *S)
{
    real_T *x0 = ssGetContStates(S);
    int_T i,nStates;
    nStates = ssGetNumContStates(S);
    
    if(mxGetM(X0_PARAM(S)) != 0)//initial states not an empty matrix
    {
    	const real_T *pr = mxGetPr(X0_PARAM(S));
    	for(i=0;i<nStates;i++)
    	{
    		*x0++ = *pr++;
    	}
    }
    else //initial state empty matrix
    {
    	for(i=0;i<nStates;i++)
    	{
    		*x0++ = 0.0;
    	}
    }   
}



/* Function: mdlOutputs =======================================================
 * Abstract:
 *      y = Cx + Du
 */
static void mdlOutputs(SimStruct *S, int_T tid)
{
    /*get the 3 dimensional system output*/
    real_T            *y       = ssGetOutputPortRealSignal(S,0);
    /*get the 3 dimensional system state*/
    /*x=[i,n,theta]*/
    real_T            *x       = ssGetContStates(S);
    /*obtain motor parameters*/
    const real_T  *Ce = mxGetPr(Ce_PARAM(S));//back_EMF coefficient
    
    /*calculate the motor output elecromagnetical torque*/
    y[0] = 9.55*Ce[0]*x[0];
    /*calculate the motor shaft speed*/
    y[1] = x[1];
    /*calculate the motor armature current*/
    y[2] = x[0];
    
}



#define MDL_DERIVATIVES
/* Function: mdlDerivatives =================================================
 * Abstract:
 *      xdot = Ax + Bu
 */
static void mdlDerivatives(SimStruct *S)
{
    real_T            *dx     = ssGetdX(S);
    real_T            *x      = ssGetContStates(S);
    real_T            Us;
    
    /*obtain PWM control signal*/
    InputRealPtrsType uPtrs0  = ssGetInputPortRealSignalPtrs(S,0);
    /*obtain DIR control signal*/
    InputRealPtrsType uPtrs1  = ssGetInputPortRealSignalPtrs(S,1);
    /*obtain the Load torque on the shaft*/
    InputRealPtrsType uPtrs2  = ssGetInputPortRealSignalPtrs(S,2);
    
    real_T PWM = *uPtrs0[0];
    real_T DIR = *uPtrs1[0];
    
    /*obtain motor parameters*/
    const real_T  *Ce = mxGetPr(Ce_PARAM(S));//back_EMF coefficient
    const real_T  *R  = mxGetPr(R_PARAM(S));//motor armature resistance
    const real_T  *L  = mxGetPr(L_PARAM(S));//motor armature inductance
    const real_T  *FreeWheelingMode = mxGetPr(FreeWheelingMode_PARAM(S));//H_bridge freewheeling mode 
    const real_T  *Vs = mxGetPr(Vs_PARAM(S));
    const real_T  *GD = mxGetPr(GD_PARAM(S));
    
    /*determine the DC link voltage according to the PWM and the DIR signals*/
    if(DIR == 1)//speed is positive,defined as cw
    {
    	if(PWM == 1)
    	Us = Vs[0];
    	else//freewheeling
    	{
    		if(FreeWheelingMode[0]==1)//freewheeling thru two anti-parrallel diodes
    		{
    			if(x[0]>=delta)
    			Us = (-1)*Vs[0];
    			else Us = Ce[0]*x[1];//freewheeling over
    		}
    		
    		else//freewheeling thru one diode and one MOSFET
    		{
    			if(x[0]>=delta)
    			Us = 0;
    		        else Us = Ce[0]*x[1];//freewheeling over
    		}
    		
    	}
    }
    else//speed is negative,defined as ccw
    {
    	if(PWM == 1)
    	Us = (-1)*Vs[0];
    	else//freewheeling
    	{
    		if(FreeWheelingMode[0]==1)//freewheeling thru two anti-parrallel diodes
    		{
    			if(x[0]>=delta)
    			Us = (-1)*Vs[0];
    			else Us = Ce[0]*x[1];//freewheeling over
    		}
    		
    		else//freewheeling thru one diode and one MOSFET
    		{
    			if(x[0]>=delta)
    			Us = 0;
    		        else Us = Ce[0]*x[1];//freewheeling over
    		}
    	}
    }
     	
    /*calculate the derivative of the armature current*/
    dx[0] = Us/L[0]-R[0]*x[0]/L[0]-Ce[0]*x[1]/L[0];
    /*calculate the derivative of the shaft speed*/
    dx[1] = (9.55*Ce[0]*x[0]-*uPtrs2[0])*375/GD[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

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?