如何为在低占空比下实现更佳分辨率所需的递减计数器运行 HRPWM? 我已按照 如下方式修改了示例代码"HRPWM_Duty_SFO_V8"、但使用示波器观察时、PWMxA 和 PWMxB 信号都为低电平。
主要变化包括:
(* ePWM[j]).TBCTL.bit.CTRMODE = TB_COUNT_DOWN;
(* ePWM[j]).HRCNFG.bit.EDGMODE = HR_REP;
(* ePWM[j]).HRCNFG.bit.EDGMODEB = HR_REP;
(* ePWM[j]).AQCTLA.bit.ZRO = AQ_CLEAR;// PWM 切换为高电平/低电平
(* ePWM[j]).AQCTLA.bit.CAU = AQ_SET;
(* ePWM[j]).AQCTLB.bit.ZRO = AQ_CLEAR;
(* ePWM[j]).AQCTLB.bit.CBU = AQ_SET;
void HRPWM_Config(period)
{
Uint16 j;
//
// ePWM channel register configuration with HRPWM
// ePWMxA / ePWMxB toggle low/high with MEP control on Rising edge
//
for (j=1;j<PWM_CH;j++)
{
(*ePWM[j]).TBCTL.bit.PRDLD = TB_SHADOW; // set Immediate load
(*ePWM[j]).TBPRD = period-1; // PWM frequency = 1 / period
(*ePWM[j]).CMPA.bit.CMPA = period / 2; // set duty 50% initially
(*ePWM[j]).CMPA.bit.CMPAHR = (1 << 8); // initialize HRPWM extension
(*ePWM[j]).CMPB.bit.CMPB = period / 2; // set duty 50% initially
(*ePWM[j]).CMPB.all |= (1 << 8); // initialize HRPWM extension
(*ePWM[j]).TBPHS.all = 0;
(*ePWM[j]).TBCTR = 0;
(*ePWM[j]).TBCTL.bit.CTRMODE = TB_COUNT_DOWN;
(*ePWM[j]).TBCTL.bit.PHSEN = TB_DISABLE;
(*ePWM[j]).TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
(*ePWM[j]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
(*ePWM[j]).TBCTL.bit.CLKDIV = TB_DIV1;
(*ePWM[j]).TBCTL.bit.FREE_SOFT = 11;
(*ePWM[j]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
(*ePWM[j]).CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
(*ePWM[j]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
(*ePWM[j]).CMPCTL.bit.SHDWBMODE = CC_SHADOW;
(*ePWM[j]).AQCTLA.bit.ZRO = AQ_CLEAR; // PWM toggle high/low
(*ePWM[j]).AQCTLA.bit.CAU = AQ_SET;
(*ePWM[j]).AQCTLB.bit.ZRO = AQ_CLEAR;
(*ePWM[j]).AQCTLB.bit.CBU = AQ_SET;
EALLOW;
(*ePWM[j]).HRCNFG.all = 0x0;
(*ePWM[j]).HRCNFG.bit.EDGMODE = HR_REP; // MEP control on falling edge
(*ePWM[j]).HRCNFG.bit.CTLMODE = HR_CMP;
(*ePWM[j]).HRCNFG.bit.HRLOAD = HR_CTR_ZERO;
(*ePWM[j]).HRCNFG.bit.EDGMODEB = HR_REP; // MEP control on falling edge
(*ePWM[j]).HRCNFG.bit.CTLMODEB = HR_CMP;
(*ePWM[j]).HRCNFG.bit.HRLOADB = HR_CTR_ZERO;
#if (AUTOCONVERT)
(*ePWM[j]).HRCNFG.bit.AUTOCONV = 1; // Enable auto-conversion
// logic
#endif
(*ePWM[j]).HRPCTL.bit.HRPE = 0; // Turn off high-resolution period
// control.
EDIS;
}
}
占空比的剩余代码如下所示:
DutyFine = 0x3000;
if(UpdateFine)
{
for(i=1; i<PWM_CH; i++)
{
CMPA_reg_val = ((long)DutyFine * (*ePWM[i]).TBPRD)>>15;
CMPB_reg_val = ((long)DutyFine * (*ePWM[i]).TBPRD)>>15;
temp = ((long)DutyFine * (*ePWM[i]).TBPRD) ;
temp1 = ((long)DutyFine * (*ePWM[i]).TBPRD) ;
temp = temp - ((long)CMPA_reg_val<<15);
temp1 = temp1 - ((long)CMPB_reg_val<<15);
#if (AUTOCONVERT)
CMPAHR_reg_val = temp<<1; // convert to Q16
CMPBHR_reg_val = temp<<1; // convert to Q16
#else
CMPAHR_reg_val = ((temp*MEP_ScaleFactor)+(0x0080<<7))>>15;
CMPAHR_reg_val = CMPAHR_reg_val << 8;
CMPBHR_reg_val = ((temp1*MEP_ScaleFactor)+(0x0080<<7))>>15;
CMPBHR_reg_val = CMPBHR_reg_val << 8;
#endif
//
// Example for a 32 bit write to CMPA:CMPAHR
//
(*ePWM[i]).CMPA.all = ((long)CMPA_reg_val)<<16 |
CMPAHR_reg_val; // loses lower 8-bits
//
// Example for a 32 bit write to CMPB:CMPBHR
//
(*ePWM[i]).CMPB.all = ((long)CMPB_reg_val)<<16 |
CMPBHR_reg_val; // loses lower 8-bits
}
}
else
{
//
// CMPA_reg_val is calculated as a Q0.
// Since DutyFine is a Q15 number, and the period is Q0
// the product is Q15. So to store as a Q0, we shift right
// 15 bits.
//
for(i=1; i<PWM_CH; i++)
{
(*ePWM[i]).CMPA.bit.CMPA = ((long)DutyFine *
(*ePWM[i]).TBPRD>>15);
(*ePWM[i]).CMPB.bit.CMPB = ((long)DutyFine *
(*ePWM[i]).TBPRD>>15);
}
}
//
// Call the scale factor optimizer lib function SFO()
// periodically to track for any change due to temp/voltage.
// This function generates MEP_ScaleFactor by running the
// MEP calibration module in the HRPWM logic. This scale
// factor can be used for all HRPWM channels. The SFO()
// function also updates the HRMSTEP register with the
// scale factor value.
//
status = SFO(); // in background, MEP calibration module
// continuously updates MEP_ScaleFactor
if (status == SFO_ERROR)
{
error(); // SFO function returns 2 if an error occurs & #
// of MEP steps/coarse step
} // exceeds maximum of 255.