📄 bldc_1_sinusoidal.c
字号:
/* 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 bldc_1_sinusoidal
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"
#include "math.h"
#define R_IDX 0 //motor phase resister
#define R_PARAM(S) ssGetSFcnParam(S,R_IDX)
#define L_IDX 1 //motor phase self inductance
#define L_PARAM(S) ssGetSFcnParam(S,L_IDX)
#define M_IDX 2 //motor phase mutual inductance
#define M_PARAM(S) ssGetSFcnParam(S,M_IDX)
#define Ke_IDX 3 //motor back_EMF coefficient
#define Ke_PARAM(S) ssGetSFcnParam(S,Ke_IDX)
#define X0_IDX 4 //initial value of the system states,4-dimensional vector
#define X0_PARAM(S) ssGetSFcnParam(S,X0_IDX)
#define P_IDX 5 //number of poles
#define P_PARAM(S) ssGetSFcnParam(S,P_IDX)
#define J_IDX 6 //drive inertia
#define J_PARAM(S) ssGetSFcnParam(S,J_IDX)
#define NPARAMS 7
#define NSTATES 5 //iab,iac,ibc,electrical ratating speed in rad/s,electrical angle of the rotor
const real_T delta=0.0001;
const real_T pai=3.14159;
real_T flag = 0;
unsigned char commu_flag = 1;
real_T VAB;
real_T VAC;
real_T VBC;
real_T Vsg; //motor Y neutral point
real_T Vag;
real_T Vbg;
real_T Vcg;
/*====================*
* S-function methods *
*====================*/
#define MDL_CHECK_PARAMETERS
#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE)
/* Function: mdlCheckParameters =============================================
* Abstract:
* Validate our parameters to verify they are okay.
*/
static void mdlCheckParameters(SimStruct *S)
{
if(mxGetM(X0_PARAM(S))!=NSTATES)
{
ssSetErrorStatus(S,"the initial value of the states has been false dimensioned");
return;
}
}
#endif
/* 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);
if (!ssSetNumInputPorts(S, 9)) return;//6 switching signals,Vs,TL, pwm signal and flux density
/*The inverter DC Link voltage,Vs*/
ssSetInputPortWidth(S, 0, 1);
/*The switching signals for S1 to S6 respectivly,named according to the convention*/
ssSetInputPortWidth(S, 1, 1);
ssSetInputPortWidth(S, 2, 1);
ssSetInputPortWidth(S, 3, 1);
ssSetInputPortWidth(S, 4, 1);
ssSetInputPortWidth(S, 5, 1);
ssSetInputPortWidth(S, 6, 1);
/*Load torque on the motor shaft*/
ssSetInputPortWidth(S, 7, 1);
/*pwm signal*/
ssSetInputPortWidth(S, 8, 1);
/*set direct feedthru appearing in the system output*/
ssSetInputPortDirectFeedThrough(S, 0, 0);
ssSetInputPortDirectFeedThrough(S, 1, 1);
ssSetInputPortDirectFeedThrough(S, 2, 1);
ssSetInputPortDirectFeedThrough(S, 3, 1);
ssSetInputPortDirectFeedThrough(S, 4, 1);
ssSetInputPortDirectFeedThrough(S, 5, 1);
ssSetInputPortDirectFeedThrough(S, 6, 1);
ssSetInputPortDirectFeedThrough(S, 7, 0);
ssSetInputPortDirectFeedThrough(S, 8, 1);
/*model output are phase currents and magnetoelectrical torque*/
if (!ssSetNumOutputPorts(S, 12)) return;
/*Magnetoelectrical torque*/
ssSetOutputPortWidth(S, 0, 1);
/*motor stator phase currents*/
ssSetOutputPortWidth(S, 1, 1);
ssSetOutputPortWidth(S, 2, 1);
ssSetOutputPortWidth(S, 3, 1);
/*motor electrical speed*/
ssSetOutputPortWidth(S, 4, 1);
/*motor 3 phase BEMF*/
ssSetOutputPortWidth(S, 5, 1);
ssSetOutputPortWidth(S, 6, 1);
ssSetOutputPortWidth(S, 7, 1);
/*observe the DC link current*/
ssSetOutputPortWidth(S, 8, 1);
/*observe the motor terminal voltage*/
ssSetOutputPortWidth(S, 9, 1);
ssSetOutputPortWidth(S, 10, 1);
ssSetOutputPortWidth(S, 11, 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);//get from simulink the number of continours states of the model
if (mxGetM(X0_PARAM(S)) != 0) //this parameter is not an empty matrix
{
const real_T *pr = mxGetPr(X0_PARAM(S));
for (i = 0; i < nStates; i++)
{
*x0++ = *pr++;
}
}
else //this parameter is an empty matrix
{
for(i = 0; i < nStates; i++)
{
*x0++ = 0.0;
}
}
}
/* Function: mdlOutputs =======================================================
* Abstract:
*
*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
real_T *y0 = ssGetOutputPortRealSignal(S,0);
real_T *y1 = ssGetOutputPortRealSignal(S,1);
real_T *y2 = ssGetOutputPortRealSignal(S,2);
real_T *y3 = ssGetOutputPortRealSignal(S,3);
real_T *y4 = ssGetOutputPortRealSignal(S,4);
real_T *y5 = ssGetOutputPortRealSignal(S,5);
real_T *y6 = ssGetOutputPortRealSignal(S,6);
real_T *y7 = ssGetOutputPortRealSignal(S,7);
real_T *y8 = ssGetOutputPortRealSignal(S,8);
real_T *y9 = ssGetOutputPortRealSignal(S,9);
real_T *y10 = ssGetOutputPortRealSignal(S,10);
real_T *y11 = ssGetOutputPortRealSignal(S,11);
real_T *x = ssGetContStates(S);
InputRealPtrsType uPtrs1 = ssGetInputPortRealSignalPtrs(S,1);//S1
InputRealPtrsType uPtrs2 = ssGetInputPortRealSignalPtrs(S,2);//S2
InputRealPtrsType uPtrs3 = ssGetInputPortRealSignalPtrs(S,3);//S3
InputRealPtrsType uPtrs4 = ssGetInputPortRealSignalPtrs(S,4);//S4
InputRealPtrsType uPtrs5 = ssGetInputPortRealSignalPtrs(S,5);//S5
InputRealPtrsType uPtrs6 = ssGetInputPortRealSignalPtrs(S,6);//S6
InputRealPtrsType uPtrs8 = ssGetInputPortRealSignalPtrs(S,8);//pwm signal
real_T S1 = *uPtrs1[0];
real_T S2 = *uPtrs2[0];
real_T S3 = *uPtrs3[0];
real_T S4 = *uPtrs4[0];
real_T S5 = *uPtrs5[0];
real_T S6 = *uPtrs6[0];
real_T pwm = *uPtrs8[0];
const real_T *Ke = mxGetPr(Ke_PARAM(S));//back_EMF coefficient
const real_T *P = mxGetPr(P_PARAM(S));//number of poles
const real_T *R = mxGetPr(R_PARAM(S));//motor stator phase resistor
const real_T *L = mxGetPr(L_PARAM(S));//motor stator phase self inductance
const real_T *M = mxGetPr(M_PARAM(S));//motor stator mutual inductance
real_T B1 = sin(x[4])+(1/7.9)*sin(3*x[4]);
real_T B2 = sin(x[4]-2*pai/3)+(1/7.9)*sin(3*(x[4]-2*pai/3));
real_T B3 = sin(x[4]+2*pai/3)+(1/7.9)*sin(3*(x[4]+2*pai/3));
real_T ia = (x[0]+x[1])/3;//phase a current
real_T ib = (x[2]-x[0])/3;//phase b current
real_T ic = (-1)*(x[1]+x[2])/3;//phase c current
real_T iah=0;//current flowing thru the high side switch and free-wheeling diode of phase a
real_T ibh=0;//current flowing thru the high side switch and free-wheeling diode of phase b
real_T ich=0;//current flowing thru the high side switch and free-wheeling diode of phase c
if(S1==1) iah=ia;
else if(S4==1&&pwm==1) iah=0;
else if(S4==1&&pwm==0) iah=ia;
else if(ia>0) iah=0;
if(S3==1) ibh=ib;
else if(S6==1&&pwm==1) ibh=0;
else if(S6==1&&pwm==0) ibh=ib;
else if(ib>0) ibh=0;
if(S5==1) ich=ic;
else if(S2==1&&pwm==1) ich=0;
else if(S2==1&&pwm==0) ich=ic;
else if(ic>0) ich=0;
/*calculating stator phase currents*/
y1[0] = ia; //stator phase A current
y2[0] = ib; //stator phase B current
y3[0] = ic; //stator phase C current
/*calculating motor electrical speed*/
y4[0] = x[3];
/*calculating electrical torque*/
y0[0] = P[0]*Ke[0]*((x[0]+x[1])*B1+(x[2]-x[0])*B2-(x[1]+x[2])*B3)/3;
/*observe 3 phase BEMF*/
y5[0] = Ke[0]*x[3]*B1/P[0];//phase a BEMF
y6[0] = Ke[0]*x[3]*B2/P[0];//phase b BEMF
y7[0] = Ke[0]*x[3]*B3/P[0];//phase c BEMF
/*simulate the saturation function of the shunt current sense circuit*/
if((iah+ibh+ich)<=0) y8[0]=0;
else y8[0] = iah+ibh+ich;
y9[0] = VAB;
y10[0]= VAC;
y11[0]= flag;
}
#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 *y0 = ssGetOutputPortRealSignal(S,0);
InputRealPtrsType uPtrs0 = ssGetInputPortRealSignalPtrs(S,0);//inverter DC-link voltage
InputRealPtrsType uPtrs1 = ssGetInputPortRealSignalPtrs(S,1);//S1
InputRealPtrsType uPtrs2 = ssGetInputPortRealSignalPtrs(S,2);//S2
InputRealPtrsType uPtrs3 = ssGetInputPortRealSignalPtrs(S,3);//S3
InputRealPtrsType uPtrs4 = ssGetInputPortRealSignalPtrs(S,4);//S4
InputRealPtrsType uPtrs5 = ssGetInputPortRealSignalPtrs(S,5);//S5
InputRealPtrsType uPtrs6 = ssGetInputPortRealSignalPtrs(S,6);//S6
InputRealPtrsType uPtrs7 = ssGetInputPortRealSignalPtrs(S,7);//load torque on the motor shaft
InputRealPtrsType uPtrs8 = ssGetInputPortRealSignalPtrs(S,8);//pwm signal
const real_T *R = mxGetPr(R_PARAM(S));//motor stator phase resistor
const real_T *L = mxGetPr(L_PARAM(S));//motor stator phase self inductance
const real_T *M = mxGetPr(M_PARAM(S));//motor stator mutual inductance
const real_T *Ke = mxGetPr(Ke_PARAM(S));//back_EMF coefficient
const real_T *J = mxGetPr(J_PARAM(S));//drive inertia
const real_T *P = mxGetPr(P_PARAM(S));//number of poles
real_T Vs = *uPtrs0[0];
real_T Tl = *uPtrs7[0];
real_T S1 = *uPtrs1[0];
real_T S2 = *uPtrs2[0];
real_T S3 = *uPtrs3[0];
real_T S4 = *uPtrs4[0];
real_T S5 = *uPtrs5[0];
real_T S6 = *uPtrs6[0];
real_T pwm = *uPtrs8[0];
real_T ia = (x[0]+x[1])/3;//phase a current
real_T ib = (x[2]-x[0])/3;//phase b current
real_T ic = (-1)*(x[1]+x[2])/3;//phase c current
real_T ea = Ke[0]*x[3]*(sin(x[4])+(1/7.9)*sin(3*x[4]))/P[0];//phase a BEMF
real_T eb = Ke[0]*x[3]*(sin(x[4]-2*pai/3)+(1/7.9)*sin(3*(x[4]-2*pai/3)))/P[0];//phase b BEMF
real_T ec = Ke[0]*x[3]*(sin(x[4]+2*pai/3)+(1/7.9)*sin(3*(x[4]+2*pai/3)))/P[0];//phase c BEMF
real_T Vab;
real_T Vac;
real_T Vbc;
/*line to line voltage determination*/
/*stator voltage vector 1*/
if((S5==1)&&(S6==1))
{ commu_flag = 1;
if(pwm==1)//pwm on mode
{
if((-1)*ia>=delta&&(Vsg+ea)<Vs) //commutation freewheeling
{
Vab = Vs;
Vac = 0;
Vag = Vs;
Vbg = 0;
Vcg = Vs;
Vsg = (2*Vs-ea-eb-ec)/3;
}
else //commutation freewheeling over
{
Vab = 0.5*(Vs+2*ea-eb-ec);
Vac = 0.5*(2*ea-Vs-eb-ec);
Vsg = (Vs-ec-eb)/2;
Vag = Vsg+ea;
Vbg = 0;
Vcg = Vs;
}
Vbc = (-1)*Vs;
}
else //pwm off mode
{
if((-1)*ia>=delta&&(Vsg+ea)<Vs) //commutation freewheeling
{
if((-1)*ib>=delta)//pwm freewheeling
{
Vac = Vbc = Vab = 0;
Vag = Vbg = Vcg = Vs;
Vsg = (3*Vs-ea-eb-ec)/3;
}
else //pwm freewheeling over
{
Vab = (-0.5)*(2*eb-ea-ec);
Vac = 0;
Vbc = (-1)*Vab;
Vag = Vcg = Vs;
Vsg = Vs-(ea+ec)/2;
Vbg = Vsg+eb;
}
}
else //commutation freewheeling over
{
if(ic>=delta) //pwm freewheeling
{
Vab = Vac = 0.5*(2*ea-eb-ec);
Vbc = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -