Hello everyone,
I am trying to implement unipolar sinusoidal PWM to my Inverter. The modulation scheme is given below. I am obtaining the desired PWM signals at the output of the DSP. However; I am drawing current from DC Bus with high frequency noise and it results with high reactive power on the board. It is not a hardware problem. Because hardware is working with another PWM scheme. The PWM setup and update code in each ISR is given below. What could be the reason of this problem?
void setupInverterPWM(uint16_t inv_pwm_no, uint16_t pwm_period_ticks, uint16_t pwm_dbred_ticks, uint16_t pwm_dbfed_ticks)
{
EALLOW;
// PWM clock on F2837x is divided by 2
// ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV=1
// Deadband needs to be 0.5us => 10ns*50=500ns
// Time Base SubModule Registers
(*ePWM[inv_pwm_no]).TBCTL.bit.PRDLD = TB_SHADOW;
(*ePWM[inv_pwm_no]).TBPRD = pwm_period_ticks >>1 ; // PWM frequency = 1 / period
(*ePWM[inv_pwm_no]).TBPHS.bit.TBPHS = 0;
(*ePWM[inv_pwm_no]).TBCTR = 0;
(*ePWM[inv_pwm_no]).TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
(*ePWM[inv_pwm_no]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
(*ePWM[inv_pwm_no]).TBCTL.bit.CLKDIV = TB_DIV1;
(*ePWM[inv_pwm_no+1]).TBCTL.bit.PRDLD = TB_SHADOW;
(*ePWM[inv_pwm_no+1]).TBPRD = pwm_period_ticks >>1 ; // PWM frequency = 1 / period
(*ePWM[inv_pwm_no+1]).TBPHS.bit.TBPHS = 0;
(*ePWM[inv_pwm_no+1]).TBCTR = 0;
(*ePWM[inv_pwm_no+1]).TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
(*ePWM[inv_pwm_no+1]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
(*ePWM[inv_pwm_no+1]).TBCTL.bit.CLKDIV = TB_DIV1;
// Counter Compare Submodule Registers
(*ePWM[inv_pwm_no]).CMPA.bit.CMPA = 0; // set duty 0% initially
(*ePWM[inv_pwm_no]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
(*ePWM[inv_pwm_no]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
(*ePWM[inv_pwm_no+1]).CMPA.bit.CMPA = 0; // set duty 0% initially
(*ePWM[inv_pwm_no+1]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
(*ePWM[inv_pwm_no+1]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
// Action Qualifier SubModule Registers
// assuming positive half cycle comes first i.e. dhl>0
(*ePWM[inv_pwm_no]).AQCTLA.bit.CAU = AQ_SET; // CTR = CMPA@UP , set to 1
(*ePWM[inv_pwm_no]).AQCTLA.bit.CAD = AQ_CLEAR; // CTR = CMPA@Down , toggle
(*ePWM[inv_pwm_no]).AQCTLA.bit.ZRO = AQ_NO_ACTION; // CTR=0, clear to 0
// to start don't configure the PWM to do anything
(*ePWM[inv_pwm_no]).AQCTLA.all=0;
//(*ePWM[inv_pwm_no+1]).AQCTLA.all = 0; // set to take no action
(*ePWM[inv_pwm_no+1]).AQCTLA.bit.CAU = AQ_SET; // CTR = CMPA@Down , clear
(*ePWM[inv_pwm_no+1]).AQCTLA.bit.CAD = AQ_CLEAR; // CTR = CMPA@Down , toggle
(*ePWM[inv_pwm_no+1]).AQCTLA.bit.ZRO = AQ_NO_ACTION; // CTR=0, clear to 0
// Active high complementary PWMs - Set up the deadband
(*ePWM[inv_pwm_no]).DBCTL.bit.IN_MODE = DBA_ALL;
(*ePWM[inv_pwm_no]).DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
(*ePWM[inv_pwm_no]).DBCTL.bit.POLSEL = DB_ACTV_HIC;
(*ePWM[inv_pwm_no]).DBRED = pwm_dbred_ticks;
(*ePWM[inv_pwm_no]).DBFED = pwm_dbred_ticks;
(*ePWM[inv_pwm_no+1]).DBCTL.bit.IN_MODE = DBA_ALL;
(*ePWM[inv_pwm_no+1]).DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
(*ePWM[inv_pwm_no+1]).DBCTL.bit.POLSEL = DB_ACTV_HIC;
(*ePWM[inv_pwm_no+1]).DBRED = pwm_dbred_ticks;
(*ePWM[inv_pwm_no+1]).DBFED = pwm_dbred_ticks;
(*ePWM[inv_pwm_no]).TBCTL.bit.PHSEN = TB_DISABLE;
(*ePWM[inv_pwm_no]).TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // sync "down-stream"
// configure PWM 2 as slaves and let it pass the sync in pulse from PWM1
ePWM[inv_pwm_no+1]->TBCTL.bit.SYNCOSEL=TB_SYNC_IN;
ePWM[inv_pwm_no+1]->TBCTL.bit.PHSEN=TB_ENABLE;
ePWM[inv_pwm_no+1]->TBPHS.bit.TBPHS=2;
ePWM[inv_pwm_no+1]->TBCTL.bit.PHSDIR=TB_UP;
EDIS;
}
inline void updateInverterPWM(uint16_t inv_pwm_no)
{
half_period=(*ePWM[inv_pwm_no]).TBPRD>>1;
invDuty= _IQ24mpy(half_period,_IQ24mpy(invDutyPU,_IQ24(-1.0)))+half_period; //_IQ24mpy((*ePWM[inv_pwm_no]).TBPRD,(1-_IQ24abs(invDutyPU))) originally
invDuty2=_IQ24mpy(half_period,invDutyPU)+half_period;
(*ePWM[inv_pwm_no]).CMPA.bit.CMPA= invDuty; //(*ePWM[inv_pwm_no]).CMPA.bit.CMPA= invDuty;
(*ePWM[inv_pwm_no+1]).CMPA.bit.CMPA = invDuty2; // (*ePWM[inv_pwm_no]).TBPRD
// wait for the PWM to start counting down
if(EPwm1Regs.TBSTS.bit.CTRDIR==0) // make sure the PWM is counting down originally 0
{
toggleLED();
(*ePWM[inv_pwm_no]).AQCTLA.bit.CAU = AQ_SET; // CTR = CMPA@UP , set to 1
(*ePWM[inv_pwm_no]).AQCTLA.bit.CAD = AQ_CLEAR; // CTR = CMPA@Down , toggle
(*ePWM[inv_pwm_no]).AQCTLA.bit.ZRO = AQ_NO_ACTION; // CTR=0, clear to 0
(*ePWM[inv_pwm_no+1]).AQCTLA.bit.CAU = AQ_SET; // CTR = CMPA@Down , clear
(*ePWM[inv_pwm_no+1]).AQCTLA.bit.CAD = AQ_CLEAR; //addition by me
(*ePWM[inv_pwm_no+1]).AQCTLA.bit.ZRO = AQ_NO_ACTION; //addition by me
}
}