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.

[参考译文] TMS320F28388D:使用非常大的死区时间会导致 PWM 脉冲缺失

Guru**** 2387080 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1529315/tms320f28388d-using-very-large-dead-time-causes-missing-pwm-pulses

器件型号:TMS320F28388D

工具/软件:

当使用非常长的死区时间时、我似乎在半桥的低侧遇到了一些漏掉的 PWM 脉冲。 这会导致半桥中的同步自举 FET 永远不会导通、因此高侧 FET 也无法导通。

以下是我尝试执行的操作:

我正在使用 C2000 F28388D 微控制器控制三相双向直流/直流转换器。
PWM 频率为 500kHz。
实时 HRPWM。
每个相位偏移 120 度、以尽可能减少输出端的纹波。
半桥 IC 是一个 EPC2152、它具有一个同步自举 FET、当低侧 PWM 信号为高电平时会导通、以便为自举电容器充电。
每个相位的输出端都有一个背对背 FET、可在转换器启动时将每个相位与负载断开。
PWM 占空比由 CLA 上运行的任务控制、以保持目标电流。

在转换器启动期间、我希望实现以下行为:
1.从一小段时间内极低的占空比开始为自举电容器充电。 这一阶段具有较小的死区时间。
2.设置固定占空比为输出电容器充电至与背对背 FET(连接了电池)输出侧相同的电压、以更大程度地减小 FET 启用时流经它的电流瞬态。
3.设置一个非常大的死区时间,以降低转换器的最大电流输出。 这个死区时间不到 PWM 周期的一半。 设置这一较大的死区时间是为了在启动期间、当我们“猜测“初始占空比(这不可避免地是错误的)时、系统输出和转换器之间的电流会尽可能减小。 我希望死区时间非常长、但高侧和低侧 FET 的脉冲导通时间应根据占空比成比例。
4.启用背对背 FET、将转换器的输出连接到系统(已连接电池)。 此时、电池和转换器的输出电容器之间有一个小瞬态电流、用于均衡小电压差。
5.使 CLA 任务能够控制转换器的占空比、目标电流为 0A。 此任务以 350kHz 的频率运行。 在 CLA 任务的 1023 次迭代 (~3ms) 之后、在 CPU1 上生成一个中断。 此时、死区时间仍然非常大。
6.生成中断时、CPU1 会检查电流以确保其稳定在接近 0A(确保 CLA 能够控制负载)。 如果电流接近 0、则应缩短死区时间。
7.最终、当死区时间达到目标死区时间(非常短)时、转换器启动完成。 我们现在可以设置需要的任何目标电流、CLA 将控制占空比以满足电流要求。

我希望这种设置是合理的。

问题如下:
当我们设置非常长的死区时间(步骤 3)时、直流/直流转换器低侧 的脉冲会消失、并导致自举电压下降、因为同步自举 FET 绝不会开启以对其进行重新充电。

如有任何帮助、我们将不胜感激。 我猜是 我没有正确使用死区时间和占空比的配置、在不知道这些设置或限值的情况下违反了这些设置或限值。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、Micah、

    感谢您的详细描述! 我从较高层次了解行为、如果您可以快速绘制这些行为步骤所需的 PWM 波形的视图、这也可能有所帮助、以确保我们的理解保持一致。  

    澄清一下、您使用人力资源能力的目的是什么? 这是人力资源职责控制吗? HR 死区? 您正在使用什么计数模式? 如果您可以发送 PWM 初始化信息,这将有助于更好地了解您正在尝试实现的目标以及可能出现问题的地方 — 如果您能够实现,请告诉我。  

    此致、

    Allison

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Allison:

    我们使用 HR 进行占空比控制、PWM 处于向上计数模式。

    下面是在步骤 3 中、在死区时间较长但保持相对导通时间占空比的情况下尝试实现的 PWM 波形图。 请注意、此时转换器将以 DCM 模式运行:

    然后、当我们减少步骤 6 中的死区时间时、导通时间将增加、我希望保持相对占空比。

    我意识到、在我的电流配置下低脉冲消失的原因是、占空比设置的导通时间短于我要使用的死区时间长。
    为了实现这个波形、高侧和低侧是否需要具有不同的死区时间、并且每次更新占空比时都要更改死区时间?

    下面添加了大多数 PWM 配置。

        //Enable the PWM clock and the PWM peripheral for CPU1
        SysCtl_selectCPUForPeripheral(SYSCTL_CPUSEL0_EPWM, pwm_number, SYSCTL_CPUSEL_CPU1);
        SysCtl_enablePeripheral(periph_clk);
    
        //Clock prescaler set to 100Mhz (output need to match macro PWM_CLK_KHZ)
        EPWM_setClockPrescaler(pwm_base, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
    
        /*TIME-BASE COUNTER AND ACTION QUALIFIER ARE CONFIGURED BELOW*/
        //Stimulus PWM is set to run at WAVEGEN_FREQUENCY_KHZ, in up-count mode only.
        EPWM_setTimeBaseCounterMode(pwm_base, EPWM_COUNTER_MODE_UP);
        EPWM_setTimeBasePeriod(pwm_base, WAVEGEN_PRD_COUNTER);
        EPWM_setCounterCompareValue(pwm_base, EPWM_COUNTER_COMPARE_A, WAVEGEN_PRD_COUNTER/2); //Defaults to 50%, arbitrarily chosen.
        //All registers that are modified in runtime are set to load shadow on counter reset
        EPWM_setCounterCompareShadowLoadMode(pwm_base, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareShadowLoadMode(pwm_base, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);
        //Reset the time base counter to zero, disable phase shift for now
        EPWM_disablePhaseShiftLoad(pwm_base);
        EPWM_setTimeBaseCounter(pwm_base, 0U);
        //The action qualifier output is set to go low on timebase reset, and then go high as Counter matches CMPA (i.e. AQ OUT DC will match CMPA's complement0')
        EPWM_setActionQualifierAction(pwm_base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        EPWM_setActionQualifierAction(pwm_base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    
        /*HRPWM IS CONFIGURED BELOW*/
        //Disable the high-res phase shift load
        HRPWM_disablePhaseShiftLoad(pwm_base);
        //For up-down count mode, the shadow load event must be set to load on zero and period
        HRPWM_setCounterCompareShadowLoadEvent(pwm_base, HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_ZERO);
        HRPWM_setCounterCompareShadowLoadEvent(pwm_base, HRPWM_CHANNEL_B, HRPWM_LOAD_ON_CNTR_ZERO);
        //For each output, set to control micro-edge position (MEP) on appropriate edge
        HRPWM_setMEPEdgeSelect(pwm_base, HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_RISING_EDGE);
        HRPWM_setMEPEdgeSelect(pwm_base, HRPWM_CHANNEL_B, HRPWM_MEP_CTRL_FALLING_EDGE);
        //For each output, set to "duty-cycle" control mode
        HRPWM_setMEPControlMode(pwm_base, HRPWM_CHANNEL_A, HRPWM_MEP_DUTY_PERIOD_CTRL);
        HRPWM_setMEPControlMode(pwm_base, HRPWM_CHANNEL_B, HRPWM_MEP_DUTY_PERIOD_CTRL);
        //Set normal output path for HRPWM output B:
        HRPWM_setChannelBOutputPath(pwm_base, HRPWM_OUTPUT_ON_B_NORMAL);
        //Don't swap the outputs.
        HRPWM_setOutputSwapMode(pwm_base, false);
        //Enable auto-conversion
        HRPWM_enableAutoConversion(pwm_base);
        //Disable high-res period control
        HRPWM_disablePeriodControl(pwm_base);
    
        /*DEAD-BAND IS CONFIGURED BELOW*/
        //Use full-clock resolution (100MHz)
        EPWM_setDeadBandCounterClock(pwm_base, EPWM_DB_COUNTER_CLOCK_HALF_CYCLE);
        //Set rising edge delay input as EPWMA, and set falling edge delay input as EPWMA as well
        EPWM_setRisingEdgeDeadBandDelayInput(pwm_base, EPWM_DB_INPUT_EPWMA); //IN_MODE bit, S4
        EPWM_setFallingEdgeDeadBandDelayInput(pwm_base, EPWM_DB_INPUT_EPWMA); //IN_MODE bit, S5 and DEDB_MODE S8
        EPWM_setRisingEdgeDelayCountShadowLoadMode(pwm_base, EPWM_RED_LOAD_ON_CNTR_ZERO);
        EPWM_setFallingEdgeDelayCountShadowLoadMode(pwm_base, EPWM_FED_LOAD_ON_CNTR_ZERO);
        HRPWM_setDeadbandMEPEdgeSelect(pwm_base, HRPWM_DB_MEP_CTRL_RED_FED);
        HRPWM_setRisingEdgeDelayLoadMode(pwm_base, HRPWM_LOAD_ON_CNTR_ZERO);
        HRPWM_setFallingEdgeDelayLoadMode(pwm_base, HRPWM_LOAD_ON_CNTR_ZERO);
        //Flip the polarity on the falling-edge only
        EPWM_setDeadBandDelayPolarity(pwm_base, EPWM_DB_RED, EPWM_DB_POLARITY_ACTIVE_HIGH); //POLSEL bit, S2
        EPWM_setDeadBandDelayPolarity(pwm_base, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW); //POLSEL bit, S3
        //Send both the RED and FED blocks to the output
        EPWM_setDeadBandDelayMode(pwm_base, EPWM_DB_RED, true); //OUT_MODE bit, S1
        EPWM_setDeadBandDelayMode(pwm_base, EPWM_DB_FED, true); //OUT_MODE bit, S0
        //Don't swap the outputs
        EPWM_setDeadBandOutputSwapMode(pwm_base, EPWM_DB_OUTPUT_A, false); //OUTSWAP bit, S6
        EPWM_setDeadBandOutputSwapMode(pwm_base, EPWM_DB_OUTPUT_B, false); //OUTSWAP bit, S7
    
        /*Propagate Trip input 4, 5 to DCAH/DCBH and DCAEVT1/DCBEVT1 (both needed to trip high and low pwm).
        *Trip input 4 and 5 are the cell current and voltage ADC trips (respectively)
        *These trip inputs are  ORed together and set as a one-shot trip for ePWM_xA and ePWM_xB to force both to 0
        */
        set_comparator_epwm_trip(pwm_base);
        EPWM_enableDigitalCompareTripCombinationInput(pwm_base, EPWM_DC_COMBINATIONAL_TRIPIN4 | EPWM_DC_COMBINATIONAL_TRIPIN5, EPWM_DC_TYPE_DCAH);
        EPWM_enableDigitalCompareTripCombinationInput(pwm_base, EPWM_DC_COMBINATIONAL_TRIPIN4 | EPWM_DC_COMBINATIONAL_TRIPIN5, EPWM_DC_TYPE_DCBH);
        EPWM_setTripZoneDigitalCompareEventCondition(pwm_base, EPWM_TZ_DC_OUTPUT_A1, EPWM_TZ_EVENT_DCXH_HIGH);
        EPWM_setTripZoneDigitalCompareEventCondition(pwm_base, EPWM_TZ_DC_OUTPUT_B1, EPWM_TZ_EVENT_DCXH_HIGH);
        EPWM_setDigitalCompareEventSource(pwm_base, EPWM_DC_MODULE_A, EPWM_DC_EVENT_1, EPWM_DC_EVENT_SOURCE_ORIG_SIGNAL);
        /*Finally, configure the EPWM module to one-shot trip on DCAEVT1.*/
        EPWM_enableTripZoneSignals(pwm_base, EPWM_TZ_SIGNAL_DCAEVT1 | EPWM_TZ_SIGNAL_DCBEVT1);
        /*Specify that the PWM outputs are both to be set to low upon trip zone event.*/
        EPWM_setTripZoneAction(pwm_base, EPWM_TZ_ACTION_EVENT_TZA, EPWM_TZ_ACTION_LOW);
        EPWM_setTripZoneAction(pwm_base, EPWM_TZ_ACTION_EVENT_TZB, EPWM_TZ_ACTION_LOW);
        EPWM_setTripZoneAction(pwm_base, EPWM_TZ_ACTION_EVENT_DCAEVT1, EPWM_TZ_ACTION_DISABLE);
        EPWM_setTripZoneAction(pwm_base, EPWM_TZ_ACTION_EVENT_DCBEVT1, EPWM_TZ_ACTION_DISABLE);
    
        //Below we enable and set the phase shift upon synchronization:
        EPWM_setPhaseShift(pwm_base, timebase_phase);
        EPWM_enablePhaseShiftLoad(pwm_base);
    
        //Below we apply configuration that is specific to PWM3, namely the sync output from software force.
        if (pwm_number == 3)
        {
         EPWM_enableSyncOutPulseSource(pwm_base, EPWM_SYNC_OUT_PULSE_ON_SOFTWARE);
    
         Hwi_Params_init(&hwi_params);
         hwi_params.enableInt = false;
         Hwi_create(EPWM3_TZ_INT_ID, limit_trip_hwi, &hwi_params, Error_ABORT);
    
         wavegen_disable_tripzone_int();
         Hwi_enableInterrupt(EPWM3_TZ_INT_ID);
    
        }
        //Below we apply configuration that is specific to PWM4 and 5, namely links to EPWM3 and the sync input
        else
        {
         EPWM_setupEPWMLinks(pwm_base, EPWM_LINK_WITH_EPWM_3, EPWM_LINK_COMP_A);
         EPWM_setupEPWMLinks(pwm_base, EPWM_LINK_WITH_EPWM_3, EPWM_LINK_COMP_B);
    
         EPWM_setSyncInPulseSource(pwm_base, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM3);
        }
    
        EPWM_setEmulationMode(pwm_base, EPWM_EMULATION_FREE_RUN);

        //First we convert the deadtime quantity from nanoseconds to EPWM half clocks, and then store in our global variable.
        g_wavegen_dead_time_count = (uint32_t)(deadtime_length_ns / (float)((float)EPWMCK_PERIOD_NS / 2.0));
        //We then check to make sure the resulting dead time meets our hardware minimum along with the peripheral's maximum.
        if (g_wavegen_dead_time_count < BRIDGE_PWM_MIN_DEAD_TIME_HALF_EPWMCK_CNT){g_wavegen_dead_time_count = BRIDGE_PWM_MIN_DEAD_TIME_HALF_EPWMCK_CNT;}
        if (g_wavegen_dead_time_count > 0x4000U){g_wavegen_dead_time_count = 0x4000U;}
    
        /*Then set the falling and rising edge delays in counts of half EPWM clock periods, such as to apply the above-determined deadtime*/
        EPWM_setRisingEdgeDelayCount(WAVEGEN_PWM_BASE_1, g_wavegen_dead_time_count);
        EPWM_setFallingEdgeDelayCount(WAVEGEN_PWM_BASE_1, g_wavegen_dead_time_count);
        EPWM_setRisingEdgeDelayCount(WAVEGEN_PWM_BASE_2, g_wavegen_dead_time_count);
        EPWM_setFallingEdgeDelayCount(WAVEGEN_PWM_BASE_2, g_wavegen_dead_time_count);
        EPWM_setRisingEdgeDelayCount(WAVEGEN_PWM_BASE_3, g_wavegen_dead_time_count);
        EPWM_setFallingEdgeDelayCount(WAVEGEN_PWM_BASE_3, g_wavegen_dead_time_count);

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Micah:

    非常感谢图表和包括您的配置。 这有助于为设置和目标 PWM 输出提供更好的背景信息 — 请允许我再留出一天时间来查看这些信息并提供一些输入。 感谢您的耐心!

    此致、

    Allison

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Micah:

    对延迟深表歉意。 是的、您需要调整死区以避免这种情况。 您在哪里更新占空比? 这可能是在 ISR 还是 CLA 任务中吗? 您是否也尝试过调整死区时间? 请告诉我您的实施是否有更新。

    此致、

    Allison