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.

transient dead band behavior

In my motor control code I have implemented dead band using ePWMs module built into dead band functionality.  It works great except, half the time, and only during first or first two commutation transitions, it gets turned off for a brief period before I force the whole module to low state.

In my code throughout commutations I always alternate pwm module between pwm and forced low.  When it comes to turn one of these modules from pwm to low I execute following code...

EPwm3Regs.AQCSFRC.bit.CSFA = 1; // Low

EPwm3Regs.AQCSFRC.bit.CSFB = 1; // Low

EPwm3Regs.DBCTL.bit.OUT_MODE = BP_DISABLE;

In those occasions when I have shoot through current I almost see the opposite (see attachment for scope shots and code). It looks like dead band goes off first then few cycles later pwm module is forced low.

The odd thing is, after first cycle of commutation I never see it again, and on top of that I don't see it on every turn on of the motor. I realize that it is probably related to initialization/timing somehow, but I don't even know where to start.  I tried putting some delay between force low and dead band disable, that didn't help.  I tried putting the whole statement into TB clock disable/re-enable block, that didn't either.

Any additional ideas are welcome.8585.Dead band problem.doc

thanks,

Vlad

 

  • Vlad,

    What is the value of BP_DISABLE?

    Also, are you using immediate or shadow mode?  I believe that If you use shadow mode for your compare registers, the CSFA does not take affect until after the next Shadow load event, which is probably on a CTR=ZERO.

     

    I don't think it applies to this issue, but as a suggestion, when you first configure your PWM channels during init, use the following order:

    1) Set TBCLKSYNC = 0 (keeps PWM module clocks from running)
    2) Enable PWM clocks
    3) Configure PWM modules
    4) Set TBCLKSYNC = 1 (starts all PWM modules at once after being configured)

    Regards,
    Daniel 

  • To be sure that shoot-through never happens, don't bypass the dead-band module.  You can configure the AQ and DB so it is not necessary to change the DB output mode.

    1) Configure AQ so that output xA and xB are generated the same (Set and Clear Actions are the same)

    2) Configure DB Input Mode so that xA is Rising edge delay source and xB is Falling edge delay source

    3) Configure DB Polarity Select to be Active Hi Complementary (xB is inverted)

    4) Configure DB Output Mode so that xA is Rising Edge Delayed (RED) and xB is Falling Edge Delayed (FED)

    Then when you want to disable the outputs use the AQ Software Force function: Force xA Clear Low and xB Set High.  The DB will invert xB to be low so that both FET gates are off.  And the dead band requirements of the FET motor phase driver will always be met :)

  • Works as advertised.

    Thanks Greg!

  • the active high complementary seems to be take effect immediately, when before you set the AQCSFRC to turn off PWM,  there is one of the the PWM A&B output high, is there any method to turn off PWM A&B output(low) at initial time. thanks

  • I'm not sure what your problem is, but is seems that you are changing the DB configuration on the fly. To be sure that the DB is always applied, never change its configuration. You should be able to change commutation phases only using the AQ registers.

  • Greg, below is my pwm initial code,

    before execute the red line code  (*ePWM[x]).DBCTL.bit.POLSEL = DB_ACTV_HIC;  pwm A&B all output low,

    after the red line code executed the pwm B output high,  then the red line code SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; executed, the pwm A&B output low,

    my purpose is at the initialize code, pwm A&B output stay low, only after I turn on the output accord the AQCSFRC regs, so is there any method?

    InitEPwm1Gpio();
    InitEPwm2Gpio();
    InitEPwm3Gpio();
    InitEPwm4Gpio();

    EALLOW; // enable protected register write

    //-----------------------------------------------------------------------------
    //Init PWM1 for primary
    //-----------------------------------------------------------------------------
    // Time Base SubModule Registers
    (*ePWM[1]).TBCTL.bit.PRDLD = TB_SHADOW; // set Immediate load
    (*ePWM[1]).TBPRD = MIN_PERIOD; // PWM frequency = (60M/200K), start with max frequence
    //(*ePWM[1]).TBPHS.half.TBPHS = 2;
    (*ePWM[1]).TBCTR = 0;
    (*ePWM[1]).TBCTL.bit.CTRMODE = TB_COUNT_UP;
    (*ePWM[1]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
    (*ePWM[1]).TBCTL.bit.CLKDIV = TB_DIV1;

    (*ePWM[1]).TBCTL.bit.PHSEN = TB_DISABLE;
    (*ePWM[1]).TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // sync "down-stream"
    (*ePWM[1]).TBCTL.bit.PHSDIR = TB_UP; // after sync event, the count direction change to count up,
    // for up down pwm mode, sync happen in counter=0, so it must set count up

    // Counter Compare Submodule Registers
    (*ePWM[1]).CMPA.half.CMPA = 30; // set duty 0% initially
    (*ePWM[1]).CMPB = 151; // set duty 0% initially
    (*ePWM[1]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    (*ePWM[1]).CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    (*ePWM[1]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    (*ePWM[1]).CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    // Action Qualifier SubModule Registers
    (*ePWM[1]).AQCTLA.bit.CAU = AQ_SET;
    (*ePWM[1]).AQCTLA.bit.CBU = AQ_CLEAR;
    (*ePWM[1]).AQCTLB.bit.CAU = AQ_SET;
    (*ePWM[1]).AQCTLB.bit.CBU = AQ_CLEAR;

    // Active high complementary PWMs - Set up the deadband
    (*ePWM[1]).DBCTL.bit.IN_MODE = DBA_RED_DBB_FED;
    (*ePWM[1]).DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    (*ePWM[1]).DBCTL.bit.POLSEL = DB_ACTV_HIC;
    (*ePWM[1]).DBRED = 10;
    (*ePWM[1]).DBFED = 10;

    //-----------------------------------------------------------------------------
    //Init PWM2 for sync
    //-----------------------------------------------------------------------------
    // Time Base SubModule Registers
    (*ePWM[2]).TBCTL.bit.PRDLD = TB_SHADOW; // set Immediate load
    (*ePWM[2]).TBPRD = MIN_PERIOD; // PWM frequency = (60M/200K/2)
    //(*ePWM[2]).TBPHS.half.TBPHS = 12;
    (*ePWM[2]).TBCTR = 0;
    (*ePWM[2]).TBCTL.bit.CTRMODE = TB_COUNT_UP;
    (*ePWM[2]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
    (*ePWM[2]).TBCTL.bit.CLKDIV = TB_DIV1;

    (*ePWM[2]).TBCTL.bit.PHSEN = TB_ENABLE;
    (*ePWM[2]).TBCTL.bit.PHSDIR = TB_UP;
    (*ePWM[2]).TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync "down-stream"
    (*ePWM[2]).TBPHS.half.TBPHS = 2; //(Note: Phase+2 value used to compensate for logic delay)

    // Counter Compare Submodule Registers
    (*ePWM[2]).CMPA.half.CMPA = 24; // set duty 0% initially
    (*ePWM[2]).CMPB = 145; // set duty 0% initially
    (*ePWM[2]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    (*ePWM[2]).CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    (*ePWM[2]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    (*ePWM[2]).CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    // Action Qualifier SubModule Registers
    (*ePWM[2]).AQCTLA.bit.CAU = AQ_SET;
    (*ePWM[2]).AQCTLA.bit.CBU = AQ_CLEAR;
    (*ePWM[2]).AQCTLB.bit.CAU = AQ_SET;
    (*ePWM[2]).AQCTLB.bit.CBU = AQ_CLEAR;

    // Active high complementary PWMs - Set up the deadband
    (*ePWM[2]).DBCTL.bit.IN_MODE = DBA_RED_DBB_FED;
    (*ePWM[2]).DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    (*ePWM[2]).DBCTL.bit.POLSEL = DB_ACTV_HIC;
    (*ePWM[2]).DBRED = 10;
    (*ePWM[2]).DBFED = 10;

    //-----------------------------------------------------------------------------
    //Init PWM3 for another phase LLC primary
    //-----------------------------------------------------------------------------
    // Time Base SubModule Registers
    (*ePWM[3]).TBCTL.bit.PRDLD = TB_SHADOW; // set Immediate load
    (*ePWM[3]).TBPRD = MIN_PERIOD; // PWM frequency = (60M/200K) - 1, TB_COUNT_UP
    //(*ePWM[3]).TBPHS.half.TBPHS = MIN_PERIOD/2; //90 degrees
    (*ePWM[3]).TBCTR = 0;
    (*ePWM[3]).TBCTL.bit.CTRMODE = TB_COUNT_UP;
    (*ePWM[3]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
    (*ePWM[3]).TBCTL.bit.CLKDIV = TB_DIV1;

    (*ePWM[3]).TBCTL.bit.PHSEN = TB_ENABLE;
    (*ePWM[3]).TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync "down-stream"
    (*ePWM[3]).TBCTL.bit.PHSDIR = TB_UP;
    (*ePWM[3]).TBPHS.half.TBPHS = 2; // phase shift for 90 degrees(Note: Phase+2 value used to compensate for logic delay)

    // Counter Compare Submodule Registers
    (*ePWM[3]).CMPA.half.CMPA = 90; // set duty 0% initially
    (*ePWM[3]).CMPB = 211; // set duty 0% initially
    (*ePWM[3]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    (*ePWM[3]).CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    (*ePWM[3]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    (*ePWM[3]).CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    // Action Qualifier SubModule Registers
    (*ePWM[3]).AQCTLA.bit.CAU = AQ_SET;
    (*ePWM[3]).AQCTLA.bit.CBU = AQ_CLEAR;
    (*ePWM[3]).AQCTLB.bit.CAU = AQ_SET;
    (*ePWM[3]).AQCTLB.bit.CBU = AQ_CLEAR;

    // Active high complementary PWMs - Set up the deadband
    (*ePWM[3]).DBCTL.bit.IN_MODE = DBA_RED_DBB_FED;
    (*ePWM[3]).DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    (*ePWM[3]).DBCTL.bit.POLSEL = DB_ACTV_HIC;
    (*ePWM[3]).DBRED = 10;
    (*ePWM[3]).DBFED = 10;

    //-----------------------------------------------------------------------------
    //Init PWM4 for another phase LLC sync
    //-----------------------------------------------------------------------------
    // Time Base SubModule Registers
    (*ePWM[4]).TBCTL.bit.PRDLD = TB_SHADOW; // set Immediate load
    (*ePWM[4]).TBPRD = MIN_PERIOD; // PWM frequency = (60M/200K/2)
    //(*ePWM[4]).TBPHS.half.TBPHS = 0;
    (*ePWM[4]).TBCTR = 0;
    (*ePWM[4]).TBCTL.bit.CTRMODE = TB_COUNT_UP;
    (*ePWM[4]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
    (*ePWM[4]).TBCTL.bit.CLKDIV = TB_DIV1;

    (*ePWM[4]).TBCTL.bit.PHSEN = TB_ENABLE;
    (*ePWM[4]).TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync "down-stream"
    (*ePWM[4]).TBCTL.bit.PHSDIR = TB_UP;
    (*ePWM[4]).TBPHS.half.TBPHS = 2; //(Note: Phase+2 value used to compensate for logic delay)

    // Counter Compare Submodule Registers
    (*ePWM[4]).CMPA.half.CMPA = 84; // set duty 0% initially
    (*ePWM[4]).CMPB = 205; // set duty 0% initially
    (*ePWM[4]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    (*ePWM[4]).CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    (*ePWM[4]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    (*ePWM[4]).CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    // Action Qualifier SubModule Registers
    (*ePWM[4]).AQCTLA.bit.CAU = AQ_SET;
    (*ePWM[4]).AQCTLA.bit.CBU = AQ_CLEAR;
    (*ePWM[4]).AQCTLB.bit.CAU = AQ_SET;
    (*ePWM[4]).AQCTLB.bit.CBU = AQ_CLEAR;

    // Active high complementary PWMs - Set up the deadband
    (*ePWM[4]).DBCTL.bit.IN_MODE = DBA_RED_DBB_FED;
    (*ePWM[4]).DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    (*ePWM[4]).DBCTL.bit.POLSEL = DB_ACTV_HIC;
    (*ePWM[4]).DBRED = 10;
    (*ePWM[4]).DBFED = 10;
    EDIS;

    // enable pwm peripheral clock for sync
    EALLOW;
    (*ePWM[1]).AQCSFRC.all = 0x09;
    (*ePWM[2]).AQCSFRC.all = 0x09;
    (*ePWM[3]).AQCSFRC.all = 0x09;
    (*ePWM[4]).AQCSFRC.all = 0x09;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;

    // software force synchronize
    (*ePWM[1]).TBCTL.bit.SWFSYNC = 1;

  • It would seem to me that you could leave the GPIO pin configuration to be high impedance inputs (or output LOW) before the PWM configuration.  Then at the end, after the PWM clock enable, switch the GPIO pin mux to select PWM.

  • I assume that your lack of response shows that my suggestion worked.  Glad to help.

  • I have try your advice, but it still has short time output high at initial time, may be it is wrong of my code, but finally I use one shot trip zone to turn off the pwm at initial time. And it worked.
  • Thanks for providing your solution :)