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:是否可以同时启用 TBPRDHR 和 CMPAHR?

Guru**** 2540720 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1350336/tms320f28379d-is-it-possible-to-enable-both-tbprdhr-and-cmpahr-at-the-same-time

器件型号:TMS320F28379D
主题中讨论的其他器件:C2000WARE

大家好!

是否可以同时启用 TBPRDHR 和 CMPAHR?

TBPRDHR 和 CMPAHR 与 TRM "15.14.1.3 HRPWM 设置"中所述、
然而、在"边沿模式"中似乎只能选择 TBPRDHR 和 CMPAHR。
因此、就 TRM 而言、不可能同时支持两者。

此致、

伊藤

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

    尊敬的 Ito:

    可以、通过使用"边沿模式"和启用周期控制来启用 TBPRDHR 和 CMPAHR。 我认为某些寄存器说明有些令人困惑、我正在对其进行更新。  

    此致、

    艾里森

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

    尊敬的 Allison:

    感谢您的答复。

    我还尝试了设置两个边沿(BE)、但它不会反映 CMPAHR。
    我感觉还需要其他设置、
    例如是使用向上向下计数模式还是 AQ 模块设置。
    如果您知道 PWM 的详细设置来同时启用 TBPRDHR 和 CMPAHR、请告诉我。

    此致、

    伊藤

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

    尊敬的 Ito:

    让我来看看我们是否有一些现有示例可供您使用

    此致、

    艾里森

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

    尊敬的 Ito:

    我刚才整理了一些代码、使用我们现有的示例以高度简化的方式实现占空比控制和周期控制。 只使用 EPWM1模块(通道 A 和 B)、CMPxHR 值保持不变(可由用户更改)、TBPRDHR 递增时非常缓慢。

    我建议您将一个现有示例(例如 {C2000Ware}\driverlib\f2837xd\examples\cpu\HRPWM\HRPWM_ex4_DUTY_updown_SFO)导入到 CCS 中、然后将 HRPWM_ex4_DUTY_updown_SFO.c 文件内容替换为下面的内容。 希望这有助于显示您应该实施哪些设置!

    //#############################################################################
    //
    // FILE:   hrpwm_simple_duty_and_period_control_updown_sfo.c
    //
    // TITLE:  HRPWM DUTY and PERIOD CONTROL (simplified).
    //
    //#############################################################################
    //
    // This is a simplified HRPWM example where HRPWM duty control and
    // HRPWM period control capability are both already set up for you on only
    // one PWM module (EPWM1). This example uses CMPAHR, CMPBHR, and TBPRDHR to show the
    // implementation of HR duty and period modulation together. The user can alter
    // CMPAHR and CMPBHR values during run time in the register viewing window of CCS.
    // the example slowly increments the TBPRDHR value to increase the TBPRDHR value.
    // You can see the outputs of channels EPWM1A and EPWM1B change on an oscilloscope.
    // Increasing CMPxHR values will decrease the duty cycle of channel 'x'.
    // The incrementing of TBPRDHR will lower the frequency by lengthening the period of both channels.
    //
    // Period is incremented by default. To adjust the duty cycle while running the code:
    // 1. Open the Registers window in CCS.
    // 2. Turn on Continuous Refresh using the yellow arrows button.
    // 3. Scroll to EPWM1 registers and expand them.
    // 4. Find the CMPA and CMPB registers. Click the arrow to expand them so you see the HR elements.
    // 5. Right-click on CMPAHR and CMPBHR and change the number formats to Hex for readability.
    // 6. Double-click on the CMPAHR or CMPBHR register and change the value from 0x0100 to 0xFF00.
    // This changes the CMPxHR value from 1 to the max (255). Maxing out CMPxHR to 255 should result
    // in a 1-clock-cycle change.
    //
    // From here, you can continue to alter the HR numbers as needed for HR duty and period control.
    //
    //
    //#############################################################################
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    #include "SFO_V8.h"
    
    //
    // Defines
    //
    #define EPWM_TIMER_TBPRD    100UL           // TBPRD value for this example is set to 100
    #define LAST_EPWM_INDEX_FOR_EXAMPLE    2    // Used for the EPWM initialization function
    
    //
    // Globals
    //
    
    float32_t periodFine = 0.20; //HRPWM period percentage
    uint16_t status;
    
    int MEP_ScaleFactor; // Global variable used by the SFO library
                         // Result can be used for all HRPWM channels
                         // This variable is also copied to HRMSTEP
                         // register by SFO() function.
    
    //
    // Store the EPWM1 'base' name here (can append other EPWM modules as needed)
    //
    volatile uint32_t ePWM[] = {0, myEPWM1_BASE};
    
    //
    // Function Prototypes
    //
    void initHRPWM(uint32_t period);
    void error(void);
    __interrupt void epwm1ISR(void);
    
    
    //
    // Main
    //
    void main(void)
    {
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pull ups.
        //
        Device_initGPIO();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // Assign the interrupt service routines to ePWM interrupts
        //
        Interrupt_register(INT_EPWM1, &epwm1ISR);
    
    
        //
        // Initialize the EPWM GPIOs and change XBAR inputs from using GPIO0
        // This will implement any SysConfig configurations. Note that any configurations
        // that occur after this will overwrite your SysConfig configurations.
        //
        Board_init();
    
        //
        // Calling SFO() updates the HRMSTEP register with calibrated MEP_ScaleFactor.
        // HRMSTEP must be populated with a scale factor value prior to enabling
        // high resolution period control.
        //
        while(status == SFO_INCOMPLETE)
        {
            status = SFO();
            if(status == SFO_ERROR)
            {
                error();   // SFO function returns 2 if an error occurs & # of MEP
            }              // steps/coarse step exceeds maximum of 255.
        }
    
        //
        // Disable sync(Freeze clock to PWM as well)
        //
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
    
        //
        // Initialize the EPWM1 module in code with PRD set to EPWM_TIMER_TBPRD (in this example, 100)
        //
        initHRPWM(EPWM_TIMER_TBPRD);
    
        //
        // Enable sync and clock to PWM
        //
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
    
        // Enable ePWM interrupts
        //
        Interrupt_enable(INT_EPWM1);
    
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
    
        for(;;)
        {
            //
            // Apply HRPWM Period Control (slowly increments 0.2 to 0.9 in 0.1 steps, then starts over)
            //
            for(periodFine = 0.2; periodFine < 0.9; periodFine += 0.1)
            {
                DEVICE_DELAY_US(1000000);
                uint16_t i = 0;
    
                for(i=1; i<LAST_EPWM_INDEX_FOR_EXAMPLE; i++)
                {
                    float32_t count = ((EPWM_TIMER_TBPRD-1) << 8UL) + (float32_t)(periodFine * 256);
                    uint32_t compCount = count;
                    HRPWM_setTimeBasePeriod(ePWM[i], compCount);
                }
    
                //
                // 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.
            }
        }
    }
    
    //
    // Define the EPWM1 ISR
    //
    __interrupt void epwm1ISR(void)
    {
        //
        // This is left empty for the user to fill as needed
        //
    
        EPWM_clearEventTriggerInterruptFlag(EPWM1_BASE); // Clear the interrupt flag from the PWM module
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3); // Acknowledge the EPWM interrupt group in the PIE to reset the ACK bit
    }
    
    //
    // Initialize your EPWM1 module as with HR configurations (PRD is function input)
    //
    void initHRPWM(uint32_t period)
    {
        uint16_t j;
    
        // Parse through all EPWM modules you want this to apply to. In this case, only EPWM1 will be initalized.
    
        for (j=1;j<LAST_EPWM_INDEX_FOR_EXAMPLE;j++)
        {
            //
            // Set PWM mode to free run so that debugger does not stop it
            //
            EPWM_setEmulationMode(ePWM[j], EPWM_EMULATION_FREE_RUN);
    
            //
            // Set-up TBCLK
            //
            EPWM_setPeriodLoadMode(ePWM[j], EPWM_PERIOD_SHADOW_LOAD);
            EPWM_setTimeBasePeriod(ePWM[j], period-1);
            EPWM_setPhaseShift(ePWM[j], 0U);
            EPWM_setTimeBaseCounter(ePWM[j], 0U);
    
            //
            // Set up base duty to be 50% (CMPx = 50, TBPRD = 100)
            // Initialize CMPxHR values to be 1 (these are within the CMPA and CMPB registers, but must be written to in a particular way as shown below.
            //
            HRPWM_setCounterCompareValue(ePWM[j], HRPWM_COUNTER_COMPARE_A, (period/2 << 8) + 1);
            HRPWM_setCounterCompareValue(ePWM[j], HRPWM_COUNTER_COMPARE_B, (period/2 << 8) + 1);
    
    
            //
            // Set up counter mode to be up-down counter mode
            //
            EPWM_setTimeBaseCounterMode(ePWM[j], EPWM_COUNTER_MODE_UP_DOWN);
    
            //
            // Disable phase shifting
            //
            EPWM_disablePhaseShiftLoad(ePWM[j]);
    
            //
            // Set up both EPWM1 clock dividers and disable sync out pulses
            //
            EPWM_setClockPrescaler(ePWM[j],
                                   EPWM_CLOCK_DIVIDER_1,
                                   EPWM_HSCLOCK_DIVIDER_1);
            EPWM_setSyncOutPulseMode(ePWM[j], EPWM_SYNC_OUT_PULSE_DISABLED);
    
            //
            // Set up shadowing
            // MUST BE CTR=(ZER & PRD)
            //
            EPWM_setCounterCompareShadowLoadMode(ePWM[j],
                                                 EPWM_COUNTER_COMPARE_A,
                                                 EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);
            EPWM_setCounterCompareShadowLoadMode(ePWM[j],
                                                 EPWM_COUNTER_COMPARE_B,
                                                 EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);
    
            //
            // Set up Action Qualifiers for Channels A and B
            // (set high on CMPxU, set low on CMPxD for both channels)
            //
    
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_A,
                                          EPWM_AQ_OUTPUT_HIGH,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_A,
                                          EPWM_AQ_OUTPUT_LOW,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_B,
                                          EPWM_AQ_OUTPUT_HIGH,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
            EPWM_setActionQualifierAction(ePWM[j],
                                          EPWM_AQ_OUTPUT_B,
                                          EPWM_AQ_OUTPUT_LOW,
                                          EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
    
            //
            // Select Channel A and B control mode to utilize CMPxHR or TBPRDHR
            //
            HRPWM_setMEPControlMode(ePWM[j], HRPWM_CHANNEL_A, HRPWM_MEP_DUTY_PERIOD_CTRL);
            HRPWM_setMEPControlMode(ePWM[j], HRPWM_CHANNEL_B, HRPWM_MEP_DUTY_PERIOD_CTRL);
    
            //
            // Select Channel A and B edge mode to control both edges
            //
            HRPWM_setMEPEdgeSelect(ePWM[j], HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);
            HRPWM_setMEPEdgeSelect(ePWM[j], HRPWM_CHANNEL_B, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);
    
            //
            // Set up shadow loading for CMPAHR (this MUST be set to shadow load on CTR=(ZER & PRD))
            //
            HRPWM_setCounterCompareShadowLoadEvent(ePWM[j], HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);
            HRPWM_setCounterCompareShadowLoadEvent(ePWM[j], HRPWM_CHANNEL_B, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);
    
            //
            // Turn on auto-conversion
            //
            HRPWM_enableAutoConversion(ePWM[j]);
    
            //
            // Turn on high-resolution period control in order to let HR duty control occur on BOTH EDGEs.
            //
            HRPWM_enablePeriodControl(ePWM[j]);
            HRPWM_disablePhaseShiftLoad(ePWM[j]);
    
    
            //
            // Set up an empty interrupt where user can fill with whatever is desired
            // Select INT on Time base counter zero event,
            // Enable INT, generate INT on 1st event
            //
            EPWM_setInterruptSource(ePWM[j], EPWM_INT_TBCTR_ZERO);
            EPWM_enableInterrupt(ePWM[j]);
            EPWM_setInterruptEventCount(ePWM[j], 1U);
    
            //
            // Turn on high-resolution period control.
            //
    
            HRPWM_enablePeriodControl(ePWM[j]);
            HRPWM_enablePhaseShiftLoad(ePWM[j]);
    
            EPWM_forceSyncPulse(ePWM[j]);
        }
    
    }
    
    //
    // error - Halt debugger when called
    //
    void error (void)
    {
        ESTOP0;         // Stop here and handle error
    }
    

    此致、

    艾里森

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

    尊敬的 Allison:

    感谢您的答复。

    我将与我的客户分享这个代码。

    此致、

    伊藤

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

    好的、听起来不错、伊藤。

    此致!

    艾里森