#define S_FUNCTION_NAME svpwm
#define S_FUNCTION_LEVEL 2
/*
* Need to include simstruc.h for the definition of the SimStruct and
* its associated macro definitions.
*/
#include "simstruc.h"
#include <math.h>
/*====================*
* 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)
{
/* See sfuntmpl_doc.c for more details on the macros below */
ssSetNumSFcnParams(S, 0); /* Number of expected parameters */
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
/* Return if number of expected != number of actual parameters */
return;
}
ssSetNumContStates(S, 0);
ssSetNumDiscStates(S, 0);
if (!ssSetNumInputPorts(S, 1)) return;
ssSetInputPortWidth(S, 0, 4);
ssSetInputPortRequiredContiguous(S, 0, true); /*direct input signal access*/
/*
* Set direct feedthrough flag (1=yes, 0=no).
* A port has direct feedthrough if the input is used in either
* the mdlOutputs or mdlGetTimeOfNextVarHit functions.
* See matlabroot/simulink/src/sfuntmpl_directfeed.txt.
*/
ssSetInputPortDirectFeedThrough(S, 0, 1);
if (!ssSetNumOutputPorts(S, 1)) return;
ssSetOutputPortWidth(S, 0, 11);
ssSetNumSampleTimes(S, 1);
ssSetNumRWork(S, 0);
ssSetNumIWork(S, 0);
ssSetNumPWork(S, 0);
ssSetNumModes(S, 0);
ssSetNumNonsampledZCs(S, 0);
ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
}
/* Function: mdlInitializeSampleTimes =========================================
* Abstract:
* This function is used to specify the sample time(s) for your
* S-function. You must register the same number of sample times as
* specified in ssSetNumSampleTimes.
*/
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
}
#define MDL_INITIALIZE_CONDITIONS /* Change to #undef to remove function */
#if defined(MDL_INITIALIZE_CONDITIONS)
/* Function: mdlInitializeConditions ========================================
* Abstract:
* In this function, you should initialize the continuous and discrete
* states for your S-function block. The initial states are placed
* in the state vector, ssGetContStates(S) or ssGetRealDiscStates(S).
* You can also perform any other initialization activities that your
* S-function may require. Note, this routine will be called at the
* start of simulation and if it is present in an enabled subsystem
* configured to reset states, it will be call when the enabled subsystem
* restarts execution to reset the states.
*/
static void mdlInitializeConditions(SimStruct *S)
{
}
#endif /* MDL_INITIALIZE_CONDITIONS */
#define MDL_START /* Change to #undef to remove function */
#if defined(MDL_START)
/* Function: mdlStart =======================================================
* Abstract:
* This function is called once at start of model execution. If you
* have states that should be initialized once, this is the place
* to do it.
*/
static void mdlStart(SimStruct *S)
{
}
#endif /* MDL_START */
/* Function: mdlOutputs =======================================================
* Abstract:
* In this function, you compute the outputs of your S-function
* block. Generally outputs are placed in the output vector, ssGetY(S).
* The input information
* u[0]=Vdc is the dc_link voltage
* u[1]=Tpwm is the pwm period
* u[2]=vsa_ref is the d axis reference
* u[3]=vsb_ref is the q axis reference
* The output information:PWM ON-OFF state
* y[0] is the
* y[1] is the
* y[2] is the
* y[3] is the
* y[4] is the
* y[5] is the
* y[6]....sector timer------y[7]
* The middle information
* t is the system time
* timer is the result of the (system time/Tpwm)'s remainder.
So it can act as the timer in an PWM perion Tpwm.
* T1,T2,T3,T4,T5,T6
* is the six timers
* valhpa_ref is the alpha component of the reference voltage
* vbeta_ref is the beta component of the reference voltage
* sw1,sw2,sw3,sw4
* is the pulse signal
*
*/
static void mdlOutputs(SimStruct *S, int tid)
{
/*输入、输出及中间变量定义*/
const double *u = ( const double*) ssGetInputPortSignal(S,0);
double *y = ssGetOutputPortSignal(S,0);
static int sw1[6]={0,1,1,0,0,1};
static int sw2[6]={0,1,1,0,0,1};
static int sw3[6]={0,1,1,0,0,1};
static int sw4[6]={0,1,1,0,0,1};
static double v1an=0,v1bn=0,v1cn=0;
static double v2an=0,v2bn=0,v2cn=0;
static double v3an=0,v3bn=0,v3cn=0;
static double v4an=0,v4bn=0,v4cn=0;
double t = (double) ssGetT(S);
double timer= fmod(t,u[1]);
double Vdc=u[0];
double Tpwm=u[1];
double Vsalpha_ref=u[2];
double Vsbeta_ref=u[3];
double Vdcinvt;
double X,Y,Z;
double Va,Vb,Vc;
int A,B,C;
double t1,t2;
static double T1_on=0,T2_on=0,T3_on=0,T4_on=0,T5_on=0,T6_on=0;
double taon,tbon,tcon;
static int sector=0;
if (timer<=0.000001) /*中断周期开始,进行扇区矢量时间计算 */
{
if (Vdc<=0)
{ Vdc=1;}
Vdcinvt=Tpwm/(2*Vdc);
X=sqrt(3)*Vdcinvt*Vsbeta_ref;
Y=(sqrt(3)*Vdcinvt*Vsbeta_ref+3*Vdcinvt*Vsalpha_ref)/2;
Z=(sqrt(3)*Vdcinvt*Vsbeta_ref-3*Vdcinvt*Vsalpha_ref)/2;
/* X Y Z 为实际矢量作用时间的一半 */
Va=Vsbeta_ref;
Vb=(sqrt(3)*Vsalpha_ref-Vsbeta_ref)/2;
Vc=(-sqrt(3)*Vsalpha_ref-Vsbeta_ref)/2;
A=B=C=0;
if (Va>0)
A=1;
if (Vb>0)
B=1;
if (Vc>0)
C=1;
sector=A+2*B+4*C;
if (sector==1)
{t1=Z,t2=Y;}
else if (sector==2)
{t1=Y,t2=-X;}
else if (sector==3)
{t1=-Z,t2=X;}
else if (sector==4)
{t1=-X,t2=Z;}
else if (sector==5)
{t1=X,t2=-Y;}
else if (sector==6)
{t1=-Y,t2=-Z;}
if (t1<=0)
t1=0;
if (t2<=0)
t2=0;
if ((t1+t2)>=Tpwm)
{ t1=t1*Tpwm/(t1+t2),t2=t2*Tpwm/(t1+t2);
}
taon=(Tpwm-2*t1-2*t2)/4;
tbon=taon+t1;
tcon=tbon+t2;
T1_on=(Tpwm-2*t1-2*t2)/4; /* 零矢量时间(Tpwm-2*t1-2*t2) */
T2_on=T1_on+t1;
T3_on=T2_on+t2;
T4_on=T3_on+2*T1_on;
T5_on=T4_on+t2;
T6_on=T5_on+t1;
if (sector==1)
{sw1[0]=0,sw1[1]=1,sw1[2]=0,sw1[3]=1,sw1[4]=0,sw1[5]=1;
v1an=0,v1bn=0,v1cn=0;
sw2[0]=0,sw2[1]=1,sw2[2]=1,sw2[3]=0,sw2[4]=0,sw2[5]=1;
v2an=-Vdc/3,v2bn=2*Vdc/3,v2cn=-Vdc/3;
sw3[0]=1,sw3[1]=0,sw3[2]=1,sw3[3]=0,sw3[4]=0,sw3[5]=1;
v3an=Vdc/3,v3bn=Vdc/3,v3cn=-2*Vdc/3;
sw4[0]=1,sw4[1]=0,sw4[2]=1,sw4[3]=0,sw4[4]=1,sw4[5]=0;
v4an=0,v4bn=0,v4cn=0;
}
else if (sector==2)
{sw1[0]=0,sw1[1]=1,sw1[2]=0,sw1[3]=1,sw1[4]=0,sw1[5]=1;
v1an=0,v1bn=0,v1cn=0;
sw2[0]=1,sw2[1]=0,sw2[2]=0,sw2[3]=1,sw2[4]=0,sw2[5]=1;
v2an=2*Vdc/3,v2bn=-Vdc/3,v2cn=-Vdc/3;
sw3[0]=1,sw3[1]=0,sw3[2]=0,sw3[3]=1,sw3[4]=1,sw3[5]=0;
v3an=Vdc/3,v3bn=-2*Vdc/3,v3cn=Vdc/3;
sw4[0]=1,sw4[1]=0,sw4[2]=1,sw4[3]=0,sw4[4]=1,sw4[5]=0;
v4an=0,v4bn=0,v4cn=0;
}
else if (sector==3)
{sw1[0]=0,sw1[1]=1,sw1[2]=0,sw1[3]=1,sw1[4]=0,sw1[5]=1;
v1an=0,v1bn=0,v1cn=0;
sw2[0]=1,sw2[1]=0,sw2[2]=0,sw2[3]=1,sw2[4]=0,sw2[5]=1;
v2an=2*Vdc/3,v2bn=-Vdc/3,v2cn=-Vdc/3;
sw3[0]=1,sw3[1]=0,sw3[2]=1,sw3[3]=0,sw3[4]=0,sw3[5]=1;
v3an=Vdc/3,v3bn=Vdc/3,v3cn=-2*Vdc/3;
sw4[0]=1,sw4[1]=0,sw4[2]=1,sw4[3]=0,sw4[
评论0