Tool/software:
Dear experts,
My customers use single-phase inverter, one bridge is 50Hz, the other is 20kHz. They want to realize the level reverse adding dead band when detecting the AC(50Hz) zero point. Their current approach is to switch off the upper and lower device a PWM cycle (50us) when the AC reaches zero point and then switch. However, the AC waveform will cause jitter at zero point, they would like to ask if there is a solution, can automatically add dead band when switching between upper and lower device? As the frequency is 50Hz, the TBPRD register will be overflow, so they use AQCSFRC to realize PWM. I attach the codes and waveform here.
#define EPWM_FREQ_VALUE (100000000) //100MHz
#define INV_EPWMP_FREQ (20e3) //Unit : Khz
#define INV_EPWM_PRID_VALUE (uint16_t)(EPWM_FREQ_VALUE / (INV_EPWMP_FREQ * 2))
//Init EPWM1 module Function config
void Init_EPWM1_Handle(void)
{
EPwm1Regs.TBPRD = INV_EPWM_PRID_VALUE; // PWM frequency
EPwm1Regs.CMPA.bit.CMPA = INV_EPWM_PRID_VALUE - 20; // set duty 200ns initially
EPwm1Regs.CMPA.bit.CMPAHR = 0x0000; //0x7F00; // initialize HRPWM extension
EPwm1Regs.CMPB.bit.CMPB = 20; // 200ns initially
EPwm1Regs.CMPB.bit.CMPBHR = 0x0000; //0x7F00; // initialize HRPWM extension
EPwm1Regs.TBCTR = 0;
EPwm1Regs.TBPHS.bit.TBPHS = 0;
EPwm1Regs.TBCTL.all = 0;
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm1Regs.TBCTL.bit.FREE_SOFT = mPWM_DEBUG_STOP;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
EPwm1Regs.TBCTL.bit.SWFSYNC = 1;
EPwm1Regs.TBCTL.bit.PHSDIR = TB_UP;
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm1Regs.CMPCTL.all = 0;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;
EPwm1Regs.AQCSFRC.bit.CSFA = 1;
EPwm1Regs.AQCSFRC.bit.CSFB = 1;
EPwm1Regs.DBCTL.bit.IN_MODE = 1;
EPwm1Regs.DBCTL.bit.DEDB_MODE = 0;
EPwm1Regs.DBCTL.bit.POLSEL = 0;
EPwm1Regs.DBCTL.bit.OUT_MODE =0;
EPwm1Regs.DBRED.bit.DBRED = 0;
EPwm1Regs.DBFED.bit.DBFED = 0;
EPwm1Regs.DBCTL.bit.OUTSWAP =0;
//Init Isr()
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;
EPwm1Regs.ETCLR.bit.INT = 1;
EPwm1Regs.ETSEL.bit.INTEN = 0;
}
//Init EPWM2 module Function config
void Init_EPWM2_Handle(void)
{
EPwm2Regs.TBPRD = INV_EPWM_PRID_VALUE; // PWM frequency
EPwm2Regs.CMPA.bit.CMPA = INV_EPWM_PRID_VALUE - 20; // set 200ns initially
EPwm2Regs.CMPA.bit.CMPAHR = 0x0000; //0x7F00; // initialize HRPWM extension
EPwm2Regs.CMPB.bit.CMPB = 20; // set 200ns initially
EPwm2Regs.CMPB.bit.CMPBHR = 0x0000; //0x7F00; // initialize HRPWM extension
EPwm2Regs.TBCTR = 0;
EPwm2Regs.TBPHS.bit.TBPHS = 0;
EPwm2Regs.TBCTL.all = 0;
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW; // set Immediate load
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm2Regs.TBCTL.bit.FREE_SOFT = mPWM_DEBUG_STOP; //continu conu
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; //TB_SYNC_DISABLE;
EPwm2Regs.TBCTL.bit.SWFSYNC = 1; //software trigger one time syncon
EPwm2Regs.TBCTL.bit.PHSDIR = TB_UP; //con up after sync
EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm2Regs.CMPCTL.all = 0;
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR;
EPwm2Regs.AQCTLB.bit.CBD = AQ_SET;
EPwm2Regs.AQCSFRC.bit.CSFA = 1;
EPwm2Regs.AQCSFRC.bit.CSFB = 1;
EPwm2Regs.DBCTL.bit.IN_MODE = 1;
EPwm2Regs.DBCTL.bit.DEDB_MODE = 0;
EPwm2Regs.DBCTL.bit.POLSEL = 0;
EPwm2Regs.DBCTL.bit.OUT_MODE =0;
EPwm2Regs.DBRED.bit.DBRED = 0;
EPwm2Regs.DBFED.bit.DBFED = 0;
EPwm2Regs.DBCTL.bit.OUTSWAP =0;
}
void INV_SPWM_Handle(void)
{
switch(DCACControl_FOC.PFC_Phase_Sin)
{
case 0x10 : //Vac_Phase_Count = 0 ZeroCross
{
EPwm2Regs.CMPA.bit.CMPA = DCACControl_FOC.PFC_Period - DCACControl_FOC.PFC_Duty;
EPwm2Regs.CMPB.bit.CMPB = DCACControl_FOC.PFC_Period - DCACControl_FOC.PFC_Duty - DCACControl_FOC.PFC_Duty_DT;
EPwm1Regs.AQCSFRC.bit.CSFA = eForceLow; //ePWM1_A low
EPwm1Regs.AQCSFRC.bit.CSFB = eForceLow; //ePWM1_B low
EPwm2Regs.AQCSFRC.bit.CSFA = eNoForce; //ePWM2 release
EPwm2Regs.AQCSFRC.bit.CSFB = eNoForce; //ePWM2 release
break;
}
case 0x11 : //Vac_Phase_Count = 0 ~ 200
{
EPwm2Regs.CMPA.bit.CMPA = DCACControl_FOC.PFC_Period - DCACControl_FOC.PFC_Duty;
EPwm2Regs.CMPB.bit.CMPB = DCACControl_FOC.PFC_Period - DCACControl_FOC.PFC_Duty - DCACControl_FOC.PFC_Duty_DT;
EPwm1Regs.AQCSFRC.bit.CSFA = eForceLow; //ePWM1_A low
EPwm1Regs.AQCSFRC.bit.CSFB = eForceHigh; //ePWM1_B high
EPwm2Regs.AQCSFRC.bit.CSFA = eNoForce; //ePWM2 release
EPwm2Regs.AQCSFRC.bit.CSFB = eNoForce; //ePWM2 release
break;
}
case 0x20 : //Vac_Phase_Count = 200 ZeroCross
{
EPwm2Regs.CMPA.bit.CMPA = DCACControl_FOC.PFC_Duty + DCACControl_FOC.PFC_Duty_DT;
EPwm2Regs.CMPB.bit.CMPB = DCACControl_FOC.PFC_Duty;
EPwm1Regs.AQCSFRC.bit.CSFA = eForceLow; //ePWM1_A low
EPwm1Regs.AQCSFRC.bit.CSFB = eForceLow; //ePWM1_B low
EPwm2Regs.AQCSFRC.bit.CSFA = eNoForce; //ePWM2 release
EPwm2Regs.AQCSFRC.bit.CSFB = eNoForce; //ePWM2 release
break;
}
case 0x21 : //Vac_Phase_Count = 200 ~ 400
{
EPwm2Regs.CMPA.bit.CMPA = DCACControl_FOC.PFC_Duty + DCACControl_FOC.PFC_Duty_DT;
EPwm2Regs.CMPB.bit.CMPB = DCACControl_FOC.PFC_Duty;
EPwm1Regs.AQCSFRC.bit.CSFA = eForceHigh; //ePWM1_A high
EPwm1Regs.AQCSFRC.bit.CSFB = eForceLow; //ePWM1_B low
EPwm2Regs.AQCSFRC.bit.CSFA = eNoForce; //ePWM2 release
EPwm2Regs.AQCSFRC.bit.CSFB = eNoForce; //ePWM2 release
break;
}
default :
{
EPwm1Regs.AQCSFRC.bit.CSFA = eForceLow; //1
EPwm1Regs.AQCSFRC.bit.CSFB = eForceLow; //1
EPwm2Regs.AQCSFRC.bit.CSFA = eForceLow; //1
EPwm2Regs.AQCSFRC.bit.CSFB = eForceLow; //1
break;
}
}
}