#include "F28x_Project.
h"
#include "math.h"
//-------------------------------------------
//Function Declaration
extern interrupt void cpu_epwm1_isr(void);
void InitEPwm1(void);
void InitEPwm2(void);
void InitEPwm3(void);
void InitDaca(void);
void InitDacb(void);
void Inverter_3Ph(void);
void SolarPV_MPPT(void);
//----------------------------------------------
//Initialization
float Line_freq=50;
float theta=0, Sampling_time = 0.0001;
float L=30e-3,r_L=0.01,C=3600e-6,k=0;
float V_m = 325, Vd=0,Vq=0,Id=0,Iq=0,Pdq=0,Qdq=0;
float v_a=0,v_b=0,v_c=0,i_a=0,i_b=0,i_c=0;
float phi = 51.34;
float PLL_theta=0,PLL_kp =
0.687,PLL_ki=77.47,del_f=0,PLL_theta1=0,PLL_theta1_pre=0,v_q_pre=0,del_f_pre =
0,del_f_er=0,del_f_er_pre=0;
int epwm_prd=5000, epwm_cmpa=2500;
float B0,B1,B2,B3,B4,B5,B6,B7,B8,B9;
float sinevalue,ref_a=0,ref_b=0,ref_c=0;
float
V_dc=0,Vdc_ref=800,V_ao=0,V_bo=0,V_co=0,v_no=0,v_La=0,v_Lb=0,v_Lc=0,v_La_pre=0,v_Lb_p
re=0,v_Lc_pre=0;
float P_ref=0,Q_ref=0,omegaL;
float Error_Vdc=0,Error_Q=0,Error_Id=0,Error_Iq=0,Id_ref=0,Iq_ref=0,Ud=0,Uq=0,Id_pre=0;
float Error_Vdc_pre=0,Error_Q_pre=0,Error_Id_pre=0,Error_Iq_pre=0;
float kp_Vdc=-1819,ki_Vdc=-114233.3,kp_q=-2.08e-3,ki_q=-0.1312,kp_I=199.52,ki_I=62.68;
float md,mq,ma,mb,mc;
Uint16 DAC1 = 0;
Uint16 DAC2 = 0;
//------------------------------------------------------------
float Isc = 5.1035; // Short Circuit Current
float Ir = 800; // Irradiance
float Tc = 298; // Actual panel temperature (ambient}
float Tr = 298; //Actual panel temperature (manufacture decided ambient)
float Iph = 0; //Photo generated current
float alpha = 0.003213; // Temperature coefficient of current
float Ipv_d = 0; //PV diode current
float q=1.6e-19; //charge
float Nsh=1, Nse=7;// Parallel and Series Strings
float Is = 1.6113e-10; //Diode Saturation Current
float Vpv = 417, Ipv=0,Ppv=0,Ipv_pre=0,Vpv_pre=0,Ppv_pre=0,deltaPpv=0,deltaVpv=0; //Initially
Vpv is set to Open circuit voltage
float Rse = 0.37756, Rsh = 546.44; // Series and Shunt Resistance
float Ncell = 96; //Cells per module
float Aq = 1.005; // Diode Ideality factor
float kv = 1.38e-23; //Boltzman Constant
float coefA=0;
float dutyBoost=0,dutyBoost_pre=0.5,deltaD=1e-6;
//Boost
float Lboost=20e-3, r_Lboost = 10e-3, Cpv=100e-6;
float v_Lboost = 0,
i_Lboost=0,v_Lboost_pre=0,i_Cboost=0,i_Cboost_pre=0,i_Dboost=0,i_Cpv=0,i_Cpv_pre=0;
float B10,B11;
int MPPT_EN=0,Irr_change=0;
void main(void)
InitSysCtrl();//Initialization of system resources.
InitGpio(); //Sets all pins to be muxed to GPIO in input mode.
InitDaca();
InitDacb();
EALLOW;
CpuSysRegs.PCLKCR2.bit.EPWM1 = 1; //Module clock is turned ON
CpuSysRegs.PCLKCR2.bit.EPWM2 = 1;
CpuSysRegs.PCLKCR2.bit.EPWM3 = 1;
EDIS;
InitEPwm1Gpio();//Configure GPIO0 as EPWM1A, Configure GPIO1 as EPWM1B
InitEPwm2Gpio();
InitEPwm3Gpio();
EALLOW;
ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 1; // To make EPWM clock = SYSCLK/2
EDIS;
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
EALLOW;
PieVectTable.EPWM1_INT = &cpu_epwm1_isr;
EDIS;
IER |=M_INT3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;//epwm1 interrupt
EINT;
ERTM;
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
InitEPwm1();
InitEPwm2();
InitEPwm3();
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=1;
EDIS;
B0 = (2*PLL_kp+PLL_ki*Sampling_time)/2; // PLL Constants
B1 = (PLL_ki*Sampling_time-2*PLL_kp)/2;
B2 = (2*L+r_L*Sampling_time)/Sampling_time; // Inverter Model Constants
B3 = (r_L*Sampling_time-2*L)/Sampling_time;
B4 = (2*kp_Vdc+ki_Vdc*Sampling_time)/2; // V loop
B5 = (ki_Vdc*Sampling_time-2*kp_Vdc)/2;
B6 = (2*kp_q+ki_q*Sampling_time)/2; // Power Q
B7 = (ki_q*Sampling_time-2*kp_q)/2;
B8 = (2*kp_I+ki_I*Sampling_time)/2; // Current PI
B9 = (ki_I*Sampling_time-2*kp_I)/2;
B10 = (2*Lboost+r_Lboost*Sampling_time)/Sampling_time; //Boost Inductor Model
B11 = (r_Lboost*Sampling_time-2*Lboost)/Sampling_time;
omegaL = 2*M_PI*Line_freq*L;
k = (-3*V_m*Sampling_time)/(4*800*C);//DC link Increase
while(1)
void InitEPwm1()
EPwm1Regs.TBPRD = epwm_prd;
EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;//Phase is 0
EPwm1Regs.TBCTR = 0x0000;//Clear Counter
EPwm1Regs.CMPA.bit.CMPA = epwm_cmpa;
EPwm1Regs.TBCTL.bit.CTRMODE=2;// Count up and down
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TB_DIV1 = 0x0
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // TB_DIV1 = 0x0
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;// Clear PWM1A on event A, up count
EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;// Set PWM1A on event A, down count
EPwm1Regs.AQCTLB.bit.CAU = AQ_SET;// Set PWM1B on event A, up count
EPwm1Regs.AQCTLB.bit.CAD = AQ_CLEAR;// Clear PWM1B on event A, down count
EPwm1Regs.TBCTL.bit.SYNCOSEL=1;// EPWM1 acts as master
EPwm1Regs.ETSEL.bit.INTSELCMP = 0; //enable interrupt event time base counter equal to
CMPA
EPwm1Regs.ETSEL.bit.INTEN=1;//enalbe ePWM1 interrupt generation
EPwm1Regs.ETSEL.bit.INTSEL = 2;//Generate interrupt when TBCTR=TBPRD
EPwm1Regs.ETPS.bit.INTPRD = 1;//Generate interrupt on first event
EPwm1Regs.ETCLR.bit.INT=1;//clear INT flag
//--------------------------------------------------------------------------------------------
void InitEPwm2()
EPwm2Regs.TBPRD = epwm_prd;
EPwm2Regs.TBPHS.bit.TBPHS = 0x0000;//Phase is 0
EPwm2Regs.TBCTR = 0x0000;//Clear Counter
EPwm2Regs.CMPA.bit.CMPA = epwm_cmpa;
EPwm2Regs.TBCTL.bit.CTRMODE=2;// Count up and down
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TB_DIV1 = 0x0
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; // TB_DIV1 = 0x0
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;// Clear PWM1A on event A, up count
EPwm2Regs.AQCTLA.bit.CAD = AQ_SET;// Set PWM1A on event A, down count
EPwm2Regs.AQCTLB.bit.CAU = AQ_SET;// Set PWM1B on event A, up count
EPwm2Regs.AQCTLB.bit.CAD = AQ_CLEAR;// Clear PWM1B on event A, down count
EPwm2Regs.TBCTL.bit.SYNCOSEL=0;// EPWM1 acts as slave
}
//------------------------------------------------------------------------------------------------
void InitEPwm3()
EPwm3Regs.TBPRD = epwm_prd;
EPwm3Regs.TBPHS.bit.TBPHS = 0x0000;//Phase is 0
EPwm3Regs.TBCTR = 0x0000;//Clear Counter
EPwm3Regs.CMPA.bit.CMPA = epwm_cmpa;
EPwm3Regs.TBCTL.bit.CTRMODE=2;// Count up and down
EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TB_DIV1 = 0x0
EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1; // TB_DIV1 = 0x0
EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR;// Clear PWM1A on event A, up count
EPwm3Regs.AQCTLA.bit.CAD = AQ_SET;// Set PWM1A on event A, down count
EPwm3Regs.AQCTLB.bit.CAU = AQ_SET;// Set PWM1B on event A, up count
EPwm3Regs.AQCTLB.bit.CAD = AQ_CLEAR;// Clear PWM1B on event A, down count
EPwm3Regs.TBCTL.bit.SYNCOSEL=0;// EPWM1 acts as slave
interrupt void cpu_epwm1_isr(void)
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
theta = theta + (2*M_PI*Line_freq*Sampling_time);
if(theta>=2*M_PI)
theta=0;
v_a = V_m * __sin(theta);
v_b = V_m * __sin(theta+(-120*M_PI/180));
v_c = V_m * __sin(theta+(-240*M_PI/180));
Inverter_3Ph(); // Inverter Model gives current ia,ib,ic - flowing through filter inductor
Vd = (2.0/3.0)*((__sin(PLL_theta)*v_a)+(__sin(PLL_theta-2*M_PI/3)*v_b)+(__sin(PLL_theta-
4*M_PI/3)*v_c));//dq transformation
Vq = (2.0/3.0)*((__cos(PLL_theta)*v_a)+(__cos(PLL_theta-2*M_PI/3)*v_b)+(__cos(PLL_theta-
4*M_PI/3)*v_c));
del_f = del_f_pre +(B0*Vq)+(B1*v_q_pre); //PLL kp+ki/s
v_q_pre = Vq;
del_f_pre = del_f;
del_f_er = del_f+Line_freq;
PLL_theta1 = (M_PI*Sampling_time)*(del_f_er+del_f_er_pre)+PLL_theta1_pre;//Integrator
1/s
PLL_theta = (PLL_theta1<=(2*M_PI))*PLL_theta1;
PLL_theta1_pre = PLL_theta;
del_f_er_pre = del_f_er;
Id = (2.0/3.0)*((__sin(PLL_theta)*i_a)+(__sin(PLL_theta-2*M_PI/3)*i_b)+(__sin(PLL_theta-
4*M_PI/3)*i_c));
Iq = (2.0/3.0)*((__cos(PLL_theta)*i_a)+(__cos(PLL_theta-2*M_PI/3)*i_b)+(__cos(PLL_theta-
4*M_PI/3)*i_c));
Pdq = 1.5*Vd*Id;
Qdq = -1.5*Vd*Iq;
SolarPV_MPPT();
Error_Vdc = Vdc_ref-V_dc;
P_ref = P_ref+(B4*Error_Vdc)+(B5*Error_Vdc_pre); // PI Controller V loop
Error_Vdc_pre = Error_Vdc;
Id_ref = P_ref*(2/(3*V_m));
Error_Q = Q_ref-Qdq;
Iq_ref = Iq_ref+(B6*Error_Q)+(B7*Error_Q_pre);// PI Controller Q loop
Error_Q_pre = Error_Q;
Error_Id = Id_ref-Id;
Ud = Ud+(B8*Error_Id)+(B9*Error_Id_pre);// PI Controller d current loop
Error_Id_pre = Error_Id;
Error_Iq = Iq_ref-Iq;
Uq = Uq+(B8*Error_Iq)+(B9*Error_Iq_pre);// PI Controller q current loop
Error_Iq_pre = Error_Iq;
md = (((Ud-Iq*omegaL)+Vd)*2)/V_dc;
mq = (((Uq+Id*omegaL)+Vq)*2)/V_dc;
ma = __sin(PLL_theta)*md+__cos(PLL_theta)*mq;
mb = __sin(PLL_theta-2*M_PI/3)*md+__cos(PLL_theta-2*M_PI/3)*mq;
mc = __sin(PLL_theta-4*M_PI/3)*md+__cos(PLL_theta-4*M_PI/3)*mq;
ref_a = (ma+1)/2;
ref_b = (mb+1)/2;
ref_c = (mc+1)/2;
EPwm1Regs.CMPA.bit.CMPA = ref_a*epwm_prd;
EPwm2Regs.CMPA.bit.CMPA = ref_b*epwm_prd;
EPwm3Regs.CMPA.bit.CMPA = ref_c*epwm_prd;
DAC1 = ((V_dc)/(1600))*4095;
DAC2 = ((Pdq)/(3600))*4095;
DacaRegs.DACVALS.bit.DACVALS = DAC1;
DacbRegs.DACVALS.bit.DACVALS = DAC2;
EPwm1Regs.ETCLR.bit.INT=1;
void InitDaca(void)
EALLOW;
DacaRegs.DACCTL.bit.DACREFSEL = 1;//Configure DAC -A control registers VREFHI = 3.3V is
selected
DacaRegs.DACCTL.bit.LOADMODE = 0; // Load on next SYSCLK
DacaRegs.DACOUTEN.bit.DACOUTEN = 1;//Enable DAC -A output
DacaRegs.DACVALS.bit.DACVALS = 100;//Put the value into the DAC Value Shadow Register
DELAY_US(10); // wait for 10us for the DAC to be powered up
EDIS;
void InitDacb(void)
EALLOW;
DacbRegs.DACCTL.bit.DACREFSEL = 1;//Configure DAC -A control registers VREFHI = 3.3V is
selected
DacbRegs.DACCTL.bit.LOADMODE = 0; // Load on next SYSCLK
DacbRegs.DACOUTEN.bit.DACOUTEN = 1;//Enable DAC -A output
DacbRegs.DACVALS.bit.DACVALS = 100;//Put the value into the DAC Value Shadow Register
DELAY_US(10); // wait for 10us for the DAC to be powered up
EDIS;
void Inverter_3Ph(void)
{
//Inverter Pole Voltages
V_ao = V_dc * ref_a;
V_bo = V_dc * ref_b;
V_co = V_dc * ref_c;
//AC neutral to DC negative voltage
v_no = (V_ao+V_bo+V_co)/3;
//Filter Inductor voltages
v_La = V_ao-v_a-v_no;
v_Lb = V_bo-v_b-v_no;
v_Lc = V_co-v_c-v_no;
//Inductor Currents using Bilinear Transformation
i_a = (-B3*i_a+(v_La+v_La_pre))/B2;
i_b = (-B3*i_b+(v_Lb+v_Lb_pre))/B2;
i_c = (-B3*i_c+(v_Lc+v_Lc_pre))/B2;
v_La_pre = v_La;
v_Lb_pre = v_Lb;
v_Lc_pre = v_Lc;
}
void SolarPV_MPPT(void)
if(MPPT_EN==0)
//DC link build up
V_dc = V_dc+k*(Id+Id_pre);
Id_pre=Id;
Vpv=417;
Ipv_pre=0;
Vpv_pre=Vpv;
Iph = (Isc+(alpha*(Tc-Tr)))*Ir/1000;
coefA = q*((Vpv_pre+(Ipv_pre*(Rse*Nse/Nsh)))/(Nse*Ncell*Aq*kv*Tc));
Ipv_d = Nsh*Is*(exp(coefA)-1);
Ipv = Iph-Ipv_d-((Vpv_pre+Ipv_pre*((Rse*Nse)/Nsh))/(Rsh*Nse/Nsh));
Ppv = Vpv*Ipv;
v_Lboost=0;
i_Lboost=0;
i_Cpv=0;
i_Dboost=0;
i_Cboost=0;
i_Cpv_pre=i_Cpv;
i_Cboost_pre=i_Cboost;
v_Lboost_pre=v_Lboost;
}
if(MPPT_EN==1)
// MPPT Enable
if(Irr_change==0)
Ir=800;
if(Irr_change==1)
Ir = Ir+0.05;
if(Ir>=1000)
Ir=1000;
if(Irr_change==2)
Ir=Ir-0.05;
if(Ir<=700)
Ir=700;
// Solar PV
Iph = (Isc+(alpha*(Tc-Tr)))*Ir/1000;
coefA = q*((Vpv_pre+(Ipv_pre*(Rse*Nse/Nsh)))/(Nse*Ncell*Aq*kv*Tc));
Ipv_d = Nsh*Is*(exp(coefA)-1);
Ipv = Iph-Ipv_d-((Vpv_pre+Ipv_pre*((Rse*Nse)/Nsh))/(Rsh*Nse/Nsh));
Ppv = Vpv*Ipv;
deltaPpv = Ppv-Ppv_pre;
deltaVpv = Vpv-Vpv_pre;
if(deltaPpv<0)
if(deltaVpv<0)
dutyBoost = dutyBoost_pre-deltaD;
else
dutyBoost = dutyBoost_pre+deltaD;
else
if(deltaVpv<0)
dutyBoost = dutyBoost_pre+deltaD;
else
dutyBoost = dutyBoost_pre-deltaD;
if(deltaPpv==0)
dutyBoost = dutyBoost_pre;
dutyBoost_pre = dutyBoost;
Vpv_pre = Vpv;
Ipv_pre = Ipv;
Ppv_pre = Ppv;
v_Lboost = Vpv-V_dc*(1-dutyBoost);
i_Lboost = (-B11*i_Lboost+(v_Lboost+v_Lboost_pre))/B10;
i_Cpv = Ipv-i_Lboost;
Vpv = Vpv+(Sampling_time/(2*Cpv)*(i_Cpv+i_Cpv_pre));
i_Dboost = i_Lboost*(1-dutyBoost);
i_Cboost = i_Dboost-(1.5*V_m/800)*Id;
V_dc = V_dc+(Sampling_time/(2*C)*(i_Cboost+i_Cboost_pre));
i_Cpv_pre = i_Cpv;
i_Cboost_pre = i_Cboost;
v_Lboost_pre = v_Lboost;