This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F280041: PWM deadband of 50Hz frequency

Part Number: TMS320F280041

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;
}
}
}

  • Hello,

    I will take a look at and reply within few days.

  • Hi Angela,

    1. Could you help us understand which oscilloscope channel is representing which signal?
    2. Which is the jitter in the waveform that we want to get rid off?
    3. Also can you share the zoomed in PWM waveforms at zero crossing and the expected waveform which we would like to achieve

    Best regards, Pawan

  • Hi Pawan,

    In the first figure, the green and blue waveform are the PWM1A and PWM1B. In the second figure, the orange and blue waveform are the PWM1A and PWM1B. You can see the dead band is 50us(ISR is 20kHz) in figure 1. They want to reduce it to 20us.

  • Hello Angela,

    Did customer consider using PLL (Phase-Locked Loop) to generate 50Hz AC sine wave?  You can use a SPLL library to synchronize the switching of the upper and lower devices with the AC waveform. The PLL can generate a signal that is phase-locked to the AC waveform, and this signal can be used to control the switching of the upper and lower devices.

    Then, you can use a ZCD method to detect the zero point of the AC waveform and add the desired dead band.