按照tida_010054方案配置DAB驱动程序,算法控制移相时,移相比例在从大于50%到小于50%切换时,会出现PWM丢失问题
//======================================================================
//功能:配置上升/下降沿死区
//参数:无
//返回:无
//======================================================================
static void HRPWM_setupUpDownCountWithDeadBand(uint32_t base1,float32_t pwmFreq_Hz,uint16_t inverter,float32_t red_ns,float32_t fed_ns)
{
uint32_t pwmPeriod_ticks;
uint32_t dbFED_ticks, dbRED_ticks;
pwmPeriod_ticks = (uint32_t)((PWMSYSCLOCK_FREQ_HZ * (float32_t)(float32_t)65536.0) / (float32_t)pwmFreq_Hz) >> 1;
pwmPeriod_ticks = (pwmPeriod_ticks & 0xFFFFFF00);
dbRED_ticks = ((uint32_t)(red_ns * (float32_t)(float32_t)65536.0 * ((float32_t)1.0e-9) * PWMSYSCLOCK_FREQ_HZ * 2.0f));
dbRED_ticks = ( dbRED_ticks & 0xFFFFFE00);
dbFED_ticks = ((uint32_t)(red_ns * (float32_t)(float32_t)65536.0 * ((float32_t)1.0e-9) * PWMSYSCLOCK_FREQ_HZ * 2.0f));
dbFED_ticks = ( dbFED_ticks & 0xFFFFFE00);
//设置周期
EPWM_setPeriodLoadMode(base1, EPWM_PERIOD_SHADOW_LOAD);
HWREG(base1 + HRPWM_O_TBPRDHR) = pwmPeriod_ticks;
EPWM_setTimeBaseCounter(base1, 0);
EPWM_setPhaseShift(base1, 0);
EPWM_setTimeBaseCounterMode(base1, EPWM_COUNTER_MODE_UP_DOWN);
EPWM_setClockPrescaler(base1, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
HWREG(base1 + HRPWM_O_CMPA) = pwmPeriod_ticks >> 1; //duty = 50%
//设置影子模式
EPWM_setCounterCompareShadowLoadMode(base1, EPWM_COUNTER_COMPARE_A,EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);
EPWM_setCounterCompareShadowLoadMode(base1, EPWM_COUNTER_COMPARE_B,EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);
HWREG(base1 + HRPWM_O_CMPB) = pwmPeriod_ticks >> 1; //duty = 50%
EPWM_disableCounterCompareShadowLoadMode(base1, EPWM_COUNTER_COMPARE_C);
EALLOW;
//清除动作寄存器及死区寄存器
HWREGH(base1 + EPWM_O_AQCTLA) = 0x0000;
HWREGH(base1 + EPWM_O_AQCTLB) = 0x0000;
HWREGH(base1 + EPWM_O_DCBCTL) = 0x0000;
EDIS;
//设置动作限定符,PWM高电平有效
if(inverter == 0)
{
EPWM_setActionQualifierAction(base1, EPWM_AQ_OUTPUT_A,EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(base1, EPWM_AQ_OUTPUT_A,EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
}
else
{
EPWM_setActionQualifierAction(base1, EPWM_AQ_OUTPUT_A,EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(base1, EPWM_AQ_OUTPUT_A,EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
}
//影子模式,在零点加载死区值
EPWM_setRisingEdgeDelayCountShadowLoadMode(base1,EPWM_RED_LOAD_ON_CNTR_ZERO);
EPWM_setFallingEdgeDelayCountShadowLoadMode(base1,EPWM_FED_LOAD_ON_CNTR_ZERO);
EPWM_setDeadBandCounterClock(base1, EPWM_DB_COUNTER_CLOCK_HALF_CYCLE);
//使能上/下边沿死区
EPWM_setDeadBandDelayMode(base1, EPWM_DB_RED, true);
EPWM_setDeadBandDelayMode(base1, EPWM_DB_FED, true);
//上升/下降沿死区输入
EPWM_setRisingEdgeDeadBandDelayInput(base1, EPWM_DB_INPUT_EPWMA);
EPWM_setFallingEdgeDeadBandDelayInput(base1, EPWM_DB_INPUT_EPWMA);
//设置死区极性
EPWM_setDeadBandDelayPolarity(base1, EPWM_DB_FED,EPWM_DB_POLARITY_ACTIVE_LOW);
EPWM_setDeadBandDelayPolarity(base1, EPWM_DB_RED,EPWM_DB_POLARITY_ACTIVE_HIGH);
//设置死区值
HWREG(base1 + HRPWM_O_DBFEDHR) = dbFED_ticks;
HWREG(base1 + HRPWM_O_DBREDHR) = dbRED_ticks;
//选择双边沿MEP控制
HRPWM_setMEPEdgeSelect(base1, HRPWM_CHANNEL_A,HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);
HRPWM_setCounterCompareShadowLoadEvent(base1, HRPWM_CHANNEL_A,HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);
HRPWM_setMEPEdgeSelect(base1, HRPWM_CHANNEL_B,HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);
HRPWM_setCounterCompareShadowLoadEvent(base1, HRPWM_CHANNEL_B,HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);
//MEP控制相位
HRPWM_setMEPControlMode(base1, HRPWM_CHANNEL_A, HRPWM_MEP_PHASE_CTRL);
HRPWM_setMEPControlMode(base1, HRPWM_CHANNEL_B, HRPWM_MEP_PHASE_CTRL);
//死区MEP
HRPWM_setDeadbandMEPEdgeSelect(base1, HRPWM_DB_MEP_CTRL_RED_FED);
//使能MEP自动比例模式
HRPWM_enableAutoConversion(base1);
//开启高分辨率周期
// HRPWM_enablePeriodControl(base1);
#if DAB_GLOBAL_LOAD_ENABLED == 1
// 一次装弹是PWM精确更新的关键机制,首先启用连接到全局重新加载的寄存器机制,对于所有其他寄存器将使用默认机制
EPWM_enableGlobalLoadRegisters(base1, (EPWM_GL_REGISTER_CMPA_CMPAHR | EPWM_GL_REGISTER_CMPB_CMPBHR) );
//将PWM设置在指定事件时重新加载新值
EPWM_setGlobalLoadTrigger(base1, EPWM_GL_LOAD_PULSE_CNTR_ZERO_PERIOD);
EPWM_enableGlobalLoadOneShotMode(base1);
//使能全局加载
EPWM_enableGlobalLoad(base1);
//执行一次全局加载
EPWM_setGlobalLoadOneShotLatch(base1);
#endif
}
//======================================================================
//======================================================================
//功能:PWM配置
//参数:无
//返回:无
//======================================================================
void DAB_setupPWM(void)
{
uint16_t status;
status = SFO_INCOMPLETE;
//计算SFO()用于校正HRMSTEP寄存器(在启动高分辨率控制前执行)
while(status == SFO_INCOMPLETE)
{
status = SFO();
if(status == SFO_ERROR)
{
SysFaultWord_Bits.bit.PWM_Error = 1;
}
else
{
SysFaultWord_Bits.bit.PWM_Error = 0;
}
}
HRPWM_setupUpDownCountWithDeadBand(PRIM_LEG1_PWM_BASE,
NOMINAL_PWM_SWITCHING_FREQUENCY_HZ,
0,
PRIM_PWM_DEADBAND_RED_NS,
PRIM_PWM_DEADBAND_FED_NS);
HRPWM_setupUpDownCountWithDeadBand(PRIM_LEG2_PWM_BASE,
NOMINAL_PWM_SWITCHING_FREQUENCY_HZ,
1,
PRIM_PWM_DEADBAND_RED_NS,
PRIM_PWM_DEADBAND_FED_NS);
HRPWM_setupUpDownCountWithDeadBand(SEC_LEG1_PWM_BASE,
NOMINAL_PWM_SWITCHING_FREQUENCY_HZ,
1,
SEC_PWM_DEADBAND_RED_NS,
SEC_PWM_DEADBAND_FED_NS);
HRPWM_setupUpDownCountWithDeadBand(SEC_LEG2_PWM_BASE,
NOMINAL_PWM_SWITCHING_FREQUENCY_HZ,
0,
SEC_PWM_DEADBAND_RED_NS,
SEC_PWM_DEADBAND_FED_NS);
//初级LEG1为主PWM
EPWM_disablePhaseShiftLoad(PRIM_LEG1_PWM_BASE);
EPWM_disablePhaseShiftLoad(PRIM_LEG2_PWM_BASE);
EPWM_enableSyncOutPulseSource(PRIM_LEG1_PWM_BASE,EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);
//初级LEG2为从PWM,与主PWM同步
EPWM_setPhaseShift(PRIM_LEG2_PWM_BASE,2); // 写一个2到TBPHS以适应同步脉冲的prop延迟
EPWM_enablePhaseShiftLoad(PRIM_LEG2_PWM_BASE);
EPWM_setCountModeAfterSync(PRIM_LEG2_PWM_BASE,EPWM_COUNT_MODE_UP_AFTER_SYNC);
//次级LEG1为从PWM,与主PWM同步,移相控制
EPWM_enablePhaseShiftLoad(SEC_LEG1_PWM_BASE);
EPWM_enableSyncOutPulseSource(SEC_LEG1_PWM_BASE,EPWM_SYNC_OUT_PULSE_ON_SOFTWARE);
EPWM_setPhaseShift(SEC_LEG1_PWM_BASE, 2); // 写一个2到TBPHS以适应同步脉冲的prop延迟
EPWM_setCountModeAfterSync(SEC_LEG1_PWM_BASE,EPWM_COUNT_MODE_DOWN_AFTER_SYNC);
//次级LEG2为从PWM,与主PWM同步,移相控制
EPWM_setSyncInPulseSource(SEC_LEG2_PWM_BASE ,EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);
EPWM_enablePhaseShiftLoad(SEC_LEG2_PWM_BASE);
EPWM_setPhaseShift(SEC_LEG2_PWM_BASE, 2); // 写一个2到TBPHS以适应同步脉冲的prop延迟
EPWM_setCountModeAfterSync(SEC_LEG2_PWM_BASE,EPWM_COUNT_MODE_DOWN_AFTER_SYNC);
EPWM_setActionQualifierContSWForceShadowMode(PRIM_LEG1_PWM_BASE, EPWM_AQ_SW_SH_LOAD_ON_CNTR_ZERO);
EPWM_setActionQualifierContSWForceShadowMode(PRIM_LEG2_PWM_BASE, EPWM_AQ_SW_SH_LOAD_ON_CNTR_ZERO);
EPWM_setActionQualifierContSWForceShadowMode(SEC_LEG1_PWM_BASE, EPWM_AQ_SW_SH_LOAD_ON_CNTR_ZERO);
EPWM_setActionQualifierContSWForceShadowMode(SEC_LEG2_PWM_BASE, EPWM_AQ_SW_SH_LOAD_ON_CNTR_ZERO);
//配置死区交换(OUTSWAP = 11)
HWREGH(PRIM_LEG2_PWM_BASE + EPWM_O_DBCTL) = (HWREGH(PRIM_LEG2_PWM_BASE + EPWM_O_DBCTL) | 0x3000);
HWREGH(SEC_LEG2_PWM_BASE + EPWM_O_DBCTL) = (HWREGH(SEC_LEG2_PWM_BASE + EPWM_O_DBCTL) | 0x3000);
//PRIM_LEG2, SEC_LEG1, SEC_LEG2与PRIM_LEG1同周期
EPWM_setupEPWMLinks(PRIM_LEG2_PWM_BASE,EPWM_LINK_WITH_EPWM_1, EPWM_LINK_TBPRD);
EPWM_setupEPWMLinks(SEC_LEG1_PWM_BASE,EPWM_LINK_WITH_EPWM_1, EPWM_LINK_TBPRD);
EPWM_setupEPWMLinks(SEC_LEG2_PWM_BASE,EPWM_LINK_WITH_EPWM_1, EPWM_LINK_TBPRD);
//PRIM_LEG2与PRIM_LEG1同占空比
EPWM_setupEPWMLinks(PRIM_LEG2_PWM_BASE,EPWM_LINK_WITH_EPWM_1, EPWM_LINK_COMP_A);
EPWM_setupEPWMLinks(PRIM_LEG2_PWM_BASE,EPWM_LINK_WITH_EPWM_1, EPWM_LINK_COMP_B);
//SEC_LEG2与SEC_LEG1同占空比
EPWM_setupEPWMLinks(SEC_LEG2_PWM_BASE,EPWM_LINK_WITH_EPWM_3, EPWM_LINK_COMP_A);
EPWM_setupEPWMLinks(SEC_LEG2_PWM_BASE,EPWM_LINK_WITH_EPWM_3, EPWM_LINK_COMP_B);
EPWM_setGlobalLoadOneShotLatch(PRIM_LEG1_PWM_BASE);
EPWM_forceTripZoneEvent(PRIM_LEG1_PWM_BASE, EPWM_TZ_FORCE_EVENT_OST);
EPWM_forceTripZoneEvent(PRIM_LEG2_PWM_BASE, EPWM_TZ_FORCE_EVENT_OST);
EPWM_forceTripZoneEvent(SEC_LEG1_PWM_BASE, EPWM_TZ_FORCE_EVENT_OST);
EPWM_forceTripZoneEvent(SEC_LEG2_PWM_BASE, EPWM_TZ_FORCE_EVENT_OST);
//配置ADC触发源
EPWM_setADCTriggerSource(EPWM1_BASE,EPWM_SOC_A, EPWM_SOC_TBCTR_ZERO);
EPWM_setADCTriggerEventPrescale(EPWM1_BASE,EPWM_SOC_A, 1);
EPWM_enableADCTrigger(EPWM1_BASE,EPWM_SOC_A);
//保护功能配置
DAB_setupProtection();
//配置PWM中断
EPWM_setInterruptSource(PRIM_LEG1_PWM_BASE,EPWM_INT_TBCTR_U_CMPC);
EPWM_setCounterCompareValue(PRIM_LEG1_PWM_BASE,EPWM_COUNTER_COMPARE_C,
((TICKS_IN_PWM_FREQUENCY(NOMINAL_PWM_SWITCHING_FREQUENCY_HZ, PWMSYSCLOCK_FREQ_HZ) >> 1) - 20));
EPWM_setInterruptEventCount(PRIM_LEG1_PWM_BASE, 1);
EPWM_clearEventTriggerInterruptFlag(PRIM_LEG1_PWM_BASE);
EPWM_enableInterrupt(PRIM_LEG1_PWM_BASE);
Interrupt_register(PWM_INTERRUPT_NUMBER, &ISR1);
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
Interrupt_enable(PWM_INTERRUPT_NUMBER);
//将GPIO配置成PWM
DAB_setupPWMpins();
}
//======================================================================