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.

[参考译文] TMS320F28379D:具有递减计数器的 HRPWM

Guru**** 2526700 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1124259/tms320f28379d-hrpwm-with-a-down-counter

器件型号:TMS320F28379D

如何为在低占空比下实现更佳分辨率所需的递减计数器运行 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.

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

    您好!

    [~报价 userid="488952" URL"/support/microset/C2000-microset-group/C2000/f/C2000-microset-forum/1124259/tms320f28379d-HRPWM-with a-down-counter"](* ePWM[j]).AQCTAQAQLAA.bit.CAU = LA_set;[/quot]

    保持 CAU 位处于置位状态的逻辑是什么? 我认为这应该用 CAD 取代、而不是 CAU。 在 递减计数模式中检查计数器何时等于 CMPA、计数器何时等于零将是同一时刻。 请使用 CAD 替换 CAU 进行检查。

    谢谢、
    Aditya

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

    您好、Aditya、这无疑有助于至少获得一些开关波形、但结果还不能满足预期。 我正在使用 ePWM3、配置代码如下:

    void HRPWM_Config(period)
    {
    
        //
        // ePWM channel register configuration with HRPWM
        // ePWMxA / ePWMxB toggle low/high with MEP control on Rising edge
        //
    
            EPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW;  // set Shadow load
            EPwm3Regs.TBPRD = period-1;             // PWM frequency = 1 / period
            EPwm3Regs.CMPA.bit.CMPA = 0;   // set duty 0% initially
            EPwm3Regs.CMPA.bit.CMPAHR = (0 << 8);   // initialize HRPWM extension
            EPwm3Regs.CMPB.bit.CMPB = 0;   // set duty 0% initially
            EPwm3Regs.CMPB.all |= (0 << 8);         // initialize HRPWM extension
            EPwm3Regs.TBPHS.all = 0;
            EPwm3Regs.TBCTR = 0;
    
            EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_DOWN;
            EPwm3Regs.TBCTL.bit.PHSEN = TB_DISABLE;
            EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
            EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
            EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
            EPwm3Regs.TBCTL.bit.FREE_SOFT = 0x11;
    
            EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;  // LOAD CMPA on CTR = 0
            EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
            EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
            EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    
    
            EPwm3Regs.AQCTLA.bit.ZRO = AQ_CLEAR;      // PWM toggle high/low
            EPwm3Regs.AQCTLA.bit.CAD = AQ_SET;
            EPwm3Regs.AQCTLB.bit.ZRO = AQ_CLEAR;
            EPwm3Regs.AQCTLB.bit.CBD = AQ_SET;
    
    
        EALLOW;
    
          EPwm3Regs.HRCNFG.all = 0x0;
          EPwm3Regs.HRCNFG.bit.EDGMODE = HR_REP;  // MEP control on rising edge
          EPwm3Regs.HRCNFG.bit.CTLMODE = HR_CMP; // CMPAHR controls the MEP
          EPwm3Regs.HRCNFG.bit.HRLOAD  = HR_CTR_ZERO;  // Shadow load on CTR=Zero
          EPwm3Regs.HRCNFG.bit.EDGMODEB = HR_REP;  // MEP control on rising edge
          EPwm3Regs.HRCNFG.bit.CTLMODEB = HR_CMP;
          EPwm3Regs.HRCNFG.bit.HRLOADB  = HR_CTR_ZERO;
          EPwm3Regs.HRCNFG.bit.SELOUTB  = HR_INVERT_B; // 1: ePWMxB output is inverted version of ePWMxA signal.
          #if(AUTOCONVERT)
          EPwm3Regs.HRCNFG.bit.AUTOCONV = 1;      // Enable auto-conversion
                                                   // logic
          #endif
          EPwm3Regs.HRPCTL.bit.HRPE = 0; // Turn off high-resolution period
                                          // control.
    
       EDIS;
    
    
            // Interrupt where we will change the Compare Values
                //
                EPwm3Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
                EPwm3Regs.ETSEL.bit.INTEN = 1;                // Enable INT
                EPwm3Regs.ETPS.bit.INTPRD = ET_3RD;           // Generate INT on 3rd event
    
    }
      

    主要问题是占空比与其由以下代码中的变量"input"控制的设定值不匹配。 在这里、"DutyFineA"和"input"是类型 uint16和 float。 即使我更改了0.0f 至0.7f 范围内变化的"输入"值、开关波形的占空比也保持不变。 感谢您为解决此代码问题提供的所有帮助。  

            DutyFineA = _IQ15(input);
                        /* all below calculation apply for CMPB as well
                        // CMPA_reg_val , 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.
    
                        CMPA_reg_val = ((long)DutyFine * EPwm1Regs.TBPRD)>>15;
    
                        // This next step is to obtain the remainder which was
                        // truncated during our 15 bit shift above.
                        // compute the whole value, and then subtract CMPA_reg_val
                        // shifted LEFT 15 bits:
                        temp = ((long)DutyFine * EPwm1Regs.TBPRD) ;
                        temp = temp - ((long)CMPA_reg_val<<15);
    
                        ** If auto-conversion is disabled, the following step can be
                        // skipped. If autoconversion is enabled, the SFO function will
                        // write the MEP_ScaleFactor to the HRMSTEP register and the
                        // hardware will automatically scale the remainder in the CMPAHR
                        // register by the MEP_ScaleFactor.
                        // Because the remainder calculated above (temp) is in Q15 format,
                        // it must be shifted left by 1 to convert to Q16 format for the
                        // hardware to properly convert.
                        CMPAHR_reg_val = temp<<1;
    
                        ** If auto-conversion is enabled, the following step is performed
                           automatically in hardware and can be skipped
                        // This obtains the MEP count in digits, from
                        // 0,1, .... MEP_Scalefactor.
                        // 0x0080 (0.5 in Q8) is converted to 0.5 in Q15 by shifting left 7.
                        // This is added to fractional duty*MEP_SF product in order to round
                        // the decimal portion of the product up to the next integer if the
                        // decimal portion is >=0.5.
                        //
                        //Once again since this is Q15
                        // convert to Q0 by shifting:
                        CMPAHR_reg_val = (temp*MEP_ScaleFactor+(0x0080<<7))>>15;
    
                        ** If auto-conversion is enabled, the following step is performed
                           automatically in hardware and can be skipped
                        // Now the lower 8 bits contain the MEP count.
                        // Since the MEP count needs to be in the upper 8 bits of
                        // the 16 bit CMPAHR register, shift left by 8.
                        CMPAHR_reg_val = CMPAHR_reg_val << 8;
    
                        ** If auto-conversion is enabled, the following step is performed
                           automatically in hardware and can be skipped
                        // Add the offset and rounding
                        CMPAHR_reg_val += 0x0080;
    
                        // Write the values to the registers as one 32-bit or two 16-bits
                        EPwm1Regs.CMPA.bit.CMPA = CMPA_reg_val;
                        EPwm1Regs.CMPA.bit.CMPAHR = CMPAHR_reg_val;
                        */
    
                        //
                        // All the above operations may be condensed into
                        // the following form:
                        // EPWM1 calculations
    
    
             if(UpdateFine)
                             {
                                     CMPA_reg_val = ((long)DutyFineA * (EPwm3Regs.TBPRD)) >> 15;
                                     temp = ((long)DutyFineA * (EPwm3Regs.TBPRD)) ;
                                     temp = temp - ((long)CMPA_reg_val << 15);
    
    
                                    #if(AUTOCONVERT)
                                     CMPAHR_reg_val = temp << 1; // convert to Q16
    
                                    #else
                                     CMPAHR_reg_val = ((temp * MEP_ScaleFactor) +
                                                       (0x0080 << 7)) >> 15;
                                     CMPAHR_reg_val = CMPAHR_reg_val << 8;
    
                                    #endif
    
                                    //
                                    // Example for a 32 bit write to CMPA:CMPAHR
                                    //
                                     EPwm3Regs.CMPA.all = ((long)CMPA_reg_val) << 16 |
                                                           CMPAHR_reg_val; // loses lower 8-bits
    
    
                                     if (Reference==4 && duty_counter < 1000)
                                     {
                                         Duty_Capture[duty_counter] = EPwm3Regs.CMPA.all;
                                         Duty_Capture1[duty_counter] = _IQ16(input);
                                         duty_counter++;
    
                                     }
    
                             }
             //
                         // 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.

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

    当您将值从0更改为0.7时、您看到的占空比是多少?

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

    大家好、结果不明智。 当设定值小于0.1时、占空比没有变化、并且即使  占空比的某些值也会保持相同的开关波形。  

    最后、对我们有效的解决 方案是仍然具有一个具有递增计数器的 HRPWM、PWM 的反相信号(请参阅下面的代码)、MEP 基于上升沿、最后以1-D 作为基准占空比。 我希望这将对其他人有所帮助。  

            EPwm3Regs.AQCTLA.bit.ZRO = AQ_CLEAR;      // PWM toggle high/low
            EPwm3Regs.AQCTLA.bit.CAU = AQ_SET;
            EPwm3Regs.AQCTLB.bit.ZRO = AQ_CLEAR;
            EPwm3Regs.AQCTLB.bit.CBU = AQ_SET;

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

    您好!

    感谢您分享。 我需要返回并在较低占空比下检查向下计数 HRPWM 的性能。

    您所做的解决方案非常智能! 感谢您在此处分享这一想法。

    此致、

    Aditya