Hi,
I'm implementing HRPWM control for a buck converter and am seeing some odd behavior. I am using 2 PWMs, each controlling the top and bottom switching for separate legs of the converter. In the PWM controlling the Buck1 leg, the TBPRD register changes in between updates to the register; the TBPRDHR portion of the register changes completely and the LSB of the TBPRD register occasionally changes. I don't see this happen in the PWM controlling the Buck 2 leg. I have verified that there is only one place in the code that writes to these registers. Why would the TBPRD and TBPRDHR registers change between updates? The code that configures the PWMs and the code that updates the registers is inserted below.
Thanks for your help!
-- Matt
Code that configures the PWMs:
// PWM3
Buck1Reg->TBPRD = BUCK_PWM_COUNT;
Buck1Reg->CMPA.half.CMPA = BUCK_PWM_50PC_COUNT;
Buck1Reg->TBPHS.half.TBPHS = 0U;
Buck1Reg->TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
Buck1Reg->TBCTL.bit.PRDLD = TB_SHADOW;
Buck1Reg->TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
Buck1Reg->TBCTL.bit.HSPCLKDIV = TB_DIV1;
Buck1Reg->TBCTL.bit.CLKDIV = TB_DIV1;
Buck1Reg->CMPCTL.bit.SHDWAMODE = CC_SHADOW;
Buck1Reg->CMPCTL.bit.SHDWBMODE = CC_SHADOW;
Buck1Reg->CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD;
Buck1Reg->CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD;
Buck1Reg->AQCTLA.bit.CAU = AQ_SET;
Buck1Reg->AQCTLA.bit.CAD = AQ_CLEAR;
Buck1Reg->DBCTL.bit.OUT_MODE = DB_DISABLE;
EALLOW;
Buck1Reg->HRCNFG.all = 0x0;
Buck1Reg->HRCNFG.bit.EDGMODE = HR_BEP;
Buck1Reg->HRCNFG.bit.CTLMODE = HR_CMP;
Buck1Reg->HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD;
Buck1Reg->HRCNFG.bit.AUTOCONV = 1;
Buck1Reg->HRPCTL.bit.TBPHSHRLOADE = 1;
Buck1Reg->HRPCTL.bit.HRPE = 1; // Turn on high-resolution period control.
EDIS;
// EPWM 4
// Configure for HRPWM high-res period and duty cycle control
Buck2Reg->TBPRD = BUCK_PWM_COUNT;
Buck2Reg->CMPA.half.CMPA = BUCK_PWM_50PC_COUNT;
Buck2Reg->TBPHS.half.TBPHS = 0U;
Buck2Reg->TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
Buck2Reg->TBCTL.bit.PHSEN = TB_ENABLE;
Buck2Reg->TBCTL.bit.PRDLD = TB_SHADOW;
Buck2Reg->TBCTL.bit.PHSDIR = TB_DOWN;
Buck2Reg->TBCTL.bit.HSPCLKDIV = TB_DIV1;
Buck2Reg->TBCTL.bit.CLKDIV = TB_DIV1;
Buck2Reg->CMPCTL.bit.SHDWAMODE = CC_SHADOW;
Buck2Reg->CMPCTL.bit.SHDWBMODE = CC_SHADOW;
Buck2Reg->CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD;
Buck2Reg->CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD;
Buck2Reg->AQCTLA.bit.CAU = AQ_SET;
Buck2Reg->AQCTLA.bit.CAD = AQ_CLEAR;
Buck2Reg->DBCTL.bit.OUT_MODE = DB_DISABLE;
EALLOW;
Buck2Reg->HRCNFG.all = 0x0;
Buck2Reg->HRCNFG.bit.EDGMODE = HR_BEP;
Buck2Reg->HRCNFG.bit.CTLMODE = HR_CMP;
Buck2Reg->HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD;
Buck2Reg->HRCNFG.bit.AUTOCONV = 1;
Buck2Reg->HRPCTL.bit.TBPHSHRLOADE = 1;
Buck2Reg->HRPCTL.bit.HRPE = 1;
EDIS;
Code that updates the PWM registers:
//PWM 3
Buck1Reg->TBPRD = (buckPeriod >> 16); // Period TBCLK counts
Buck1Reg->TBPRDHR = (buckPeriod & 0xFF00); // Period TBCLK counts
Buck1Reg->CMPA.all = (buckPeriod>>1) & (0xFFFFFF00);
//PWM 4
Buck2Reg->TBPRD = (buckPeriod >> 16); // Period TBCLK counts
Buck2Reg->TBPRDHR = (buckPeriod & 0xFF00); // Period TBCLK counts
Buck2Reg->CMPA.all = (buckPeriod>>1) & (0xFFFFFF00);
Buck2Reg->TBPHS.all = (buckPhase) & (0xFFFFFF00);