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.

[参考译文] TIDA-010054:HRPWM 相移计算-潜在误差

Guru**** 2609685 points


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

https://e2e.ti.com/support/tools/simulation-hardware-system-design-tools-group/sim-hw-system-design/f/simulation-hardware-system-design-tools-forum/1321851/tida-010054-hrpwm-phase-shift-calculation---potential-error

器件型号:TIDA-010054

大家好!

我正在尝试了解在"DAB.h"文件下的"DAB_calculatePWMDutyPeriodPhaseShiftTicks ()"函数中 HRPWM 相移的实现。 该函数计算"扩展相移模式"或"单相移模式"的移位。 这里是 "dab.h"文件中原始函数的副本。

#pragma FUNC_ALWAYS_INLINE(DAB_calculatePWMDutyPeriodPhaseShiftTicks)
static inline void DAB_calculatePWMDutyPeriodPhaseShiftTicks(void)
{
    uint32_t temp;
    //
    // Calculation for the period is done in high resolution
    // as it is used by the phase shift variable in high resolution
    //
    temp = ((uint32_t)(((float32_t)(DAB_pwmPeriod_pu *
                                   DAB_pwmPeriodMax_ticks) *
                       (float32_t)65536.0)))>> 1;

    DAB_pwmPeriod_ticks = temp & 0xFFFFFF00;

    //
    // In high resolution phase shift,high resolution duty is not available
    // when using HRCFG.CTLMODE as 1 but the calculation below calculates the
    // CMPAHR value, it's easier to do so as the period ticks are in high
    // resolution format
    //
    DAB_pwmDutyAPrim_ticks = (uint32_t)((float32_t)DAB_pwmPeriod_ticks *
                                         (float32_t)
                                         (1.0f - fabsf(DAB_pwmDutyPrim_pu)));

    DAB_pwmDutyASec_ticks = (uint32_t)((float32_t)DAB_pwmPeriod_ticks *
                                         (float32_t)
                                         (1.0f - fabsf(DAB_pwmDutySec_pu)));

    //
    // the below is to make sure CMPAHR is never 0x00,
    //
    if((DAB_pwmDutyAPrim_ticks & 0x00FF00) == 0)
    {
        DAB_pwmDutyAPrim_ticks = DAB_pwmDutyAPrim_ticks | 0x000100;
    }

    if((DAB_pwmDutyASec_ticks & 0x00FF00) == 0)
    {
        DAB_pwmDutyASec_ticks = DAB_pwmDutyASec_ticks | 0x000100;
    }

    //
    // If EPS is enabled, subtract half the added delay (alpha p or alpha S) to get the fundamental phase shift.
    //
    if(DAB_pwmSwState.pwmSwState == pwmSwState_extendedPhaseShiftControl){

        float32_t phi_pu = DAB_pwmPhaseShiftPrimSec_pu - ((DAB_pwmEPSAlphaP_pu + DAB_pwmEPSAlphaS_pu) / 2);

        DAB_pwmEPSPhaseShift_P1_P2_ns = DAB_pwmEPSAlphaP_pu *
                      ((float32_t)1.0 / DAB_pwmFrequency_Hz) *
                                        (1 / ONE_NANO_SEC);

        DAB_pwmEPSPhaseShift_P1_P2_ticks =
                (int32_t)((float32_t)DAB_pwmEPSPhaseShift_P1_P2_ns *
                            DAB_PWMSYSCLOCK_FREQ_HZ * ONE_NANO_SEC *
                        TWO_RAISED_TO_THE_POWER_SIXTEEN) - ((int32_t) 2 << 16);

        if(DAB_pwmEPSPhaseShift_P1_P2_ticks >= 0)
        {
            DAB_phaseSyncP1_P2CountDirection = EPWM_COUNT_MODE_DOWN_AFTER_SYNC;
            //
            // DAB_pwmPhaseShiftPrimSec_ticks has the correct value already
            //
        }
        else
        {
            DAB_phaseSyncP1_P2CountDirection =  EPWM_COUNT_MODE_UP_AFTER_SYNC;
            DAB_pwmEPSPhaseShift_P1_P2_ticks = DAB_pwmEPSPhaseShift_P1_P2_ticks * -1;

            DAB_pwmPhaseShiftP1_P2_HiResticks =  ((uint16_t) 0xFF - ((uint16_t)
                        (DAB_pwmEPSPhaseShift_P1_P2_ticks & 0x0000FFFF) >> 8));

            DAB_pwmEPSPhaseShift_P1_P2_ticks =
                ((DAB_pwmEPSPhaseShift_P1_P2_ticks & 0xFFFF0000) + 0x10000) +
                                    (DAB_pwmPhaseShiftP1_P2_HiResticks << 8);
        }


        DAB_pwmEPSPhaseShift_P1_S1_ns = (phi_pu + DAB_pwmEPSAlphaP_pu) *
                                ((float32_t)1.0 / DAB_pwmFrequency_Hz) *
                                                    (1 / ONE_NANO_SEC);

        DAB_pwmEPSPhaseShift_P1_S1_ticks =
                (int32_t)((float32_t)DAB_pwmEPSPhaseShift_P1_S1_ns *
                            DAB_PWMSYSCLOCK_FREQ_HZ * ONE_NANO_SEC *
                            TWO_RAISED_TO_THE_POWER_SIXTEEN) - ((int32_t)2 << 16);

        if(DAB_pwmEPSPhaseShift_P1_S1_ticks >= 0)
        {
            DAB_phaseSyncP1_S1CountDirection = EPWM_COUNT_MODE_DOWN_AFTER_SYNC;
            //
            // DAB_pwmPhaseShiftPrimSec_ticks has the correct value already
            //
        }
        else
        {
            DAB_phaseSyncP1_S1CountDirection =  EPWM_COUNT_MODE_UP_AFTER_SYNC;
            DAB_pwmEPSPhaseShift_P1_S1_ticks = DAB_pwmEPSPhaseShift_P1_S1_ticks * -1;

            DAB_pwmPhaseShiftP1_S1_HiResticks =  ((uint16_t) 0xFF - ((uint16_t)
                            (DAB_pwmEPSPhaseShift_P1_S1_ticks & 0x0000FFFF)>>8));

            DAB_pwmEPSPhaseShift_P1_S1_ticks =
                    ((DAB_pwmEPSPhaseShift_P1_S1_ticks & 0xFFFF0000) + 0x10000) +
                                        (DAB_pwmPhaseShiftP1_S1_HiResticks << 8);
        }

        DAB_pwmEPSPhaseShift_P1_S2_ns = (phi_pu + DAB_pwmEPSAlphaP_pu + DAB_pwmEPSAlphaS_pu) *
                                                    ((float32_t)1.0 / DAB_pwmFrequency_Hz) *
                                                    (1 / ONE_NANO_SEC);

        DAB_pwmEPSPhaseShift_P1_S2_ticks =
                (int32_t)((float32_t)DAB_pwmEPSPhaseShift_P1_S2_ns *
                            DAB_PWMSYSCLOCK_FREQ_HZ * ONE_NANO_SEC *
                TWO_RAISED_TO_THE_POWER_SIXTEEN) - ((int32_t)2 << 16);

        if(DAB_pwmEPSPhaseShift_P1_S2_ticks >= 0)
        {
            DAB_phaseSyncP1_S2CountDirection = EPWM_COUNT_MODE_DOWN_AFTER_SYNC;
            //
            // DAB_pwmPhaseShiftPrimSec_ticks has the correct value already
            //
        }
        else
        {
            DAB_phaseSyncP1_S2CountDirection =  EPWM_COUNT_MODE_UP_AFTER_SYNC;
            DAB_pwmEPSPhaseShift_P1_S2_ticks = DAB_pwmEPSPhaseShift_P1_S2_ticks * -1;

            DAB_pwmPhaseShiftP1_S2_HiResticks =  ((uint16_t) 0xFF - ((uint16_t)
                        (DAB_pwmEPSPhaseShift_P1_S2_ticks & 0x0000FFFF) >> 8));

            DAB_pwmEPSPhaseShift_P1_S2_ticks =
                    ((DAB_pwmEPSPhaseShift_P1_S2_ticks & 0xFFFF0000) + 0x10000) +
                                        (DAB_pwmPhaseShiftP1_S2_HiResticks << 8);
        }
    }
    else{
        //
        // first the phase shift in pu is converter to ns
        // this is done for better debug and user friendliness
        //
        DAB_pwmEPSPhaseShift_P1_S1_ns = DAB_pwmPhaseShiftPrimSec_pu *
                                  ((float32_t)1.0 / DAB_pwmFrequency_Hz) *
                                   (1 / ONE_NANO_SEC);

        //
        // next this ns is simply converted to ticks
        //
        DAB_pwmEPSPhaseShift_P1_S1_ticks =
                (int32_t)((float32_t)DAB_pwmEPSPhaseShift_P1_S1_ns *
                       DAB_PWMSYSCLOCK_FREQ_HZ * ONE_NANO_SEC *
                       TWO_RAISED_TO_THE_POWER_SIXTEEN) - ((int32_t)2 << 16);

        //
        // due to the delay line implementation depending on whether it is
        // a phase delay or an advance we need to adjust the
        // HR phase shift ticks calculations
        //
        if(DAB_pwmEPSPhaseShift_P1_S1_ticks >= 0)
        {
            DAB_phaseSyncP1_S1CountDirection = EPWM_COUNT_MODE_DOWN_AFTER_SYNC;

            //
            // DAB_pwmPhaseShiftPrimSec_ticks has the correct value already
            //
        }
        else
        {
            DAB_phaseSyncP1_S1CountDirection =  EPWM_COUNT_MODE_UP_AFTER_SYNC;
            DAB_pwmEPSPhaseShift_P1_S1_ticks = DAB_pwmEPSPhaseShift_P1_S1_ticks * -1;

            DAB_pwmPhaseShiftP1_S1_HiResticks =  ((uint16_t) 0xFF - ((uint16_t)
                    (DAB_pwmEPSPhaseShift_P1_S1_ticks & 0x0000FFFF) >> 8));

            DAB_pwmEPSPhaseShift_P1_S1_ticks =
                    ((DAB_pwmEPSPhaseShift_P1_S1_ticks & 0xFFFF0000) + 0x10000) +
                    (DAB_pwmPhaseShiftP1_S1_HiResticks << 8);
        }

        DAB_pwmEPSPhaseShift_P1_P2_ticks = 261888; // Hardcoded offset, equivalent to the phase shift in ticks for input of 0.0ns
        DAB_phaseSyncP1_P2CountDirection = EPWM_COUNT_MODE_UP_AFTER_SYNC; // Hard coded to correct offset
        DAB_pwmEPSPhaseShift_P1_S2_ticks = DAB_pwmEPSPhaseShift_P1_S1_ticks;
        DAB_phaseSyncP1_S2CountDirection = DAB_phaseSyncP1_S1CountDirection;
        DAB_pwmPhaseShiftPrimSec_ns = DAB_pwmEPSPhaseShift_P1_S1_ns; //just for gui
    }
}

根据我的理解、 应该针对所需的整个 HRPWM 相移计算"DAB_pwmPhaseShiftP1_S1_HiResticks"和"DAB_pwmEPSPhaseShift_P1_S1_ticks"的高分辨率节拍、无论是正相移还是负相移。 不过、在代码中、似乎只有在相移为负时才会进行计算。 这是否准确? 下面这是 正在实施的内容的屏幕截图。  

感谢您的帮助!

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

    尊敬的 Mohamed:

    感谢您的联系。

    只 需要 EPWPHaseShift_P1_S1_TICKs。  DAB_pwmPhaseShiftP1_S1_HiResticks 只是一个临时 帮助器变量。

    发生的情况是、  EPWPHaseShift_P1_S1_TICKs 在行83中进行计算。 这可以是正相移、也可以是负相移。  

    如果 EPWPHASeShift_P1_S1_TICK 为正、则该值正常、不需要修改、并且 DAB_phaseSyncP1_S1CountDirection 设置为 EPWM_COUNT_MODE_DOWN_AFTER_SYNC。 (第88行 至第94行)。

    但是、如果相移为负、则会转换为互补 正相移、DAB_phaseSyncP1_S1CountDirection 设置为 EPWM_COUNT_MODE_UP_AFTER_SYNC。  DAB_pwmPhaseShiftP1_S1_HiResticks 只是一个临时帮助器变量。 而不是必需的。  
    这是强制性的、因为它无法将负 值写入相移寄存器。

    发生的事件 、该 事件用于将计算值写入相应的寄存器。   使用 EPWPHaseShift_P1_S1_TICKs。

    我希望这能够澄清您的问题。

    此致、

    安德烈

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

    感谢 Andreas!  我想我对 参考手册中的 MEP_ScaleFactor 计算感到困惑,并忘记了在该代码中启用了自动转换:)