TMS320F280039C: F280039C在DAB控制中出现PWM丢失问题

Part Number: TMS320F280039C
Other Parts Discussed in Thread: C2000WARE

按照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();
    }
    //======================================================================

  • 已经收到了您的案例,调查需要些时间,感谢您的耐心等待。

  • 您好

    您使用哪个版本的 DPSDK。

  • 您好

    导入的代码来自哪个版本的数字电源 SDK?

  • C2000Ware_DigitalPower_SDK_5_01_00_00

  • 您好

    此问题已在最新版本的 DPSDK 中修复。 请使用最新版本、然后查看是否再次出现该行为。

x 出现错误。请重试或与管理员联系。