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.

[参考译文] TMS320F280049C:如何在 TMS320F280049C 中更新 PWM 占空比

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

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1230955/tms320f280049c-how-to-update-pwm-duty-cycle-in-tms320f280049c

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

我正在尝试修改代码 C:\ti\c2000\C2000Ware_4_00_00\driverlib\f28004x\examples\epwm\epwm_ex3_synchronization.c

我的目标是将 PWM 占空比从1%缓慢增加到50%。 目前、我没有任何设定点或 ADC 输入。 我只是想逐渐更新占空比。

如果可能、我会很乐意提供帮助。

Ashik

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

    您好!

    您可以根据 PWM 上升/下降沿在常规事件上发出中断。 在中断服务例程中、您可以选择使用 CMPA/B 逐渐更新 EPWM 占空比
    C2000Ware 中确实有一个示例、您可以参阅- epwm_ex2_updown_AQ

    谢谢。
    Aditya.

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

    感谢您提供的信息。  目前、我需要2组 PWM。 我尝试做的是在 PWM 1和2之间给出相移。 最初、PWM 1和2都将从0%/1%占空比开始。 此时、相移将为零。 随着相移的增加、占空比将增加、它将达到最大50%。 我正在尝试将 PWM 占空比与相移的增量同步、这似乎非常困难。 我们将感谢您提供任何帮助。

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

    您好!

    我不确定 C2000Ware 中是否提供了确切的示例。  最初使用的示例-  epwm_ex3_synchronous 是我可以在您的应用中看到的最接近您的应用的值。 您可以合并示例2和3、这将非常符合您的要求。


    Aditya.

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

    您好、Aditya:

    我现在正在使用代码 epwm_ex13_up_aq.c。我已在此处附加了代码。  我现在可以将占空比更改至50%。 我还可以使用看门狗中的变量"Ph"放置相移。 但是、要更改"Ph"、我需要在看门狗中使 AshikFlag 和 loop_counter===2900。 但我希望使代码独立于这两个变量(AshikFlag 和 loop_counter)。 当 PWM 达到50%占空比时、我要从看门狗更改变量的相位。 但我不知道如何在 PWM 达到50%占空比时编写条件。 希望您可以帮助解决这个问题。 谢谢

    //###########################################################################
    //
    // FILE:   epwm_ex13_up_aq.c
    //
    // TITLE:  Action Qualifier Module - Using up count.
    //
    //! \addtogroup driver_example_list
    //! <h1> EPWM Action Qualifier (epwm_up_aq)</h1>
    //!
    //! This example configures ePWM1, ePWM2, ePWM3 to produce an
    //! waveform with independent modulation on EPWMxA and
    //! EPWMxB.
    //!
    //! The compare values CMPA and CMPB are modified within the ePWM's ISR.
    //!
    //! The TB counter is in up count mode for this example.
    //!
    //! View the EPWM1A/B(GPIO0 & GPIO1), EPWM2A/B(GPIO2 & GPIO3)
    //! and EPWM3A/B(GPIO4 & GPIO5) waveforms via an oscilloscope.
    //!
    //
    //###########################################################################
    //
    //
    // $Copyright:
    // Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //###########################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    //
    // Defines
    //
    #define EPWM1_TIMER_TBPRD  2000  // Period register
    #define EPWM1_MAX_CMPA     1000
    #define EPWM1_MIN_CMPA       0
    #define EPWM1_MAX_CMPB     1000
    #define EPWM1_MIN_CMPB       0
    
    #define EPWM2_TIMER_TBPRD  2000  // Period register
    #define EPWM2_MAX_CMPA     1000  //1950
    #define EPWM2_MIN_CMPA       0   //50
    #define EPWM2_MAX_CMPB     1000  //1950
    #define EPWM2_MIN_CMPB       0   //50
    
    #define EPWM3_TIMER_TBPRD  2000  // Period register
    #define EPWM3_MAX_CMPA      950
    #define EPWM3_MIN_CMPA       50
    #define EPWM3_MAX_CMPB     1950
    #define EPWM3_MIN_CMPB     1050
    
    #define EPWM_CMP_UP           1
    #define EPWM_CMP_DOWN         0
    
    //
    // Globals
    //
    typedef struct
    {
        uint32_t epwmModule;
        uint16_t epwmCompADirection;
        uint16_t epwmCompBDirection;
        uint16_t epwmTimerIntCount;
        uint16_t ePWMDone;
        uint16_t epwmMaxCompA;
        uint16_t epwmMinCompA;
        uint16_t epwmMaxCompB;
        uint16_t epwmMinCompB;
    } epwmInfo;
    
    epwmInfo epwm1Info;
    epwmInfo epwm2Info;
    epwmInfo epwm3Info;
    uint16_t AshikFlag = 0 ; //Ashik Added
    uint16_t Ph = 0 ; //Ashik Added
    uint16_t loop_counter = 0 ; //Ashik Added
    
    volatile uint16_t compAVal, compBVal;
    
    //
    //  Function Prototypes
    //
    void initEPWM1(void);
    void initEPWM2(void);
    void initEPWM3(void);
    __interrupt void epwm1ISR(void);
    __interrupt void epwm2ISR(void);
    __interrupt void epwm3ISR(void);
    void updateCompare(epwmInfo*);
    
    //
    // 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();
    
        //
        // For this case just init GPIO pins for ePWM1, ePWM2, ePWM3
        //
        Board_init();
    
        //
        // Interrupts that are used in this example are re-mapped to
        // ISR functions found within this file.
        //
        Interrupt_register(INT_EPWM1, &epwm1ISR);
        Interrupt_register(INT_EPWM2, &epwm2ISR);
        Interrupt_register(INT_EPWM3, &epwm3ISR);
    
        //
        // Disable sync(Freeze clock to PWM as well)
        //
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        // Initialize PWM1 without phase shift as master
        initEPWM1();
    
        // Initialize PWM2 with phase shift of X
        initEPWM2();
        //EPWM_selectPeriodLoadEvent(myEPWM2_BASE, EPWM_SHADOW_LOAD_MODE_SYNC);
        //EPWM_setPhaseShift(myEPWM2_BASE, Ph); //ashik added Ph
       // EPWM_setTimeBaseCounter(myEPWM2_BASE, Ph); //ashik added Ph
    
        initEPWM3();
    
        EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO);
    
        //
        // ePWM2 uses the ePWM 1 SYNCO as its SYNCIN.
        // ePWM2 SYNCO is generated from its SYNCIN, which is ePWM1 SYNCO
        //
        EPWM_setSyncOutPulseMode(myEPWM2_BASE, EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN);
    
        //
        // ePWM4 uses the ePWM 1 SYNCO as its SYNCIN.
        //
        //SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM4, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
        //
        // Enable all phase shifts.
        //
        EPWM_enablePhaseShiftLoad(myEPWM2_BASE);
    
        //
        // Enable sync and clock to PWM
        //
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        //
        // Enable interrupts required for this example
        //
        Interrupt_enable(INT_EPWM1);
        Interrupt_enable(INT_EPWM2);
        Interrupt_enable(INT_EPWM3);
    
        //
        // Enable global Interrupts and higher priority real-time debug events:
        //
        EINT;  // Enable Global interrupt INTM
        ERTM;  // Enable Global realtime interrupt DBGM
    
        //
        // IDLE loop. Just sit and loop forever (optional):
        //
        for(;;)
        {
            asm ("  NOP");
        }
    }
    
    //
    // epwm1ISR - EPWM1 ISR to update compare values
    //
    __interrupt void epwm1ISR(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        updateCompare(&epwm1Info);
    
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(myEPWM1_BASE);
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    //
    // epwm2ISR - EPWM2 ISR to update compare values
    //
    __interrupt void epwm2ISR(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        if (loop_counter!=AshikFlag)
        {
        updateCompare(&epwm2Info);
        }
        else
        {
    
            //Ph=300;
            EPWM_selectPeriodLoadEvent(myEPWM2_BASE, EPWM_SHADOW_LOAD_MODE_SYNC);
            EPWM_setPhaseShift(myEPWM2_BASE, Ph); //ashik added Ph
            EPWM_setTimeBaseCounter(myEPWM2_BASE, Ph); //ashik added Ph
    
        }
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(myEPWM2_BASE);
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    //
    // epwm3ISR - EPWM3 ISR to update compare values
    //
    __interrupt void epwm3ISR(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        updateCompare(&epwm3Info);
    
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(myEPWM3_BASE);
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    //
    // initEPWM1 - Initialize EPWM1 values
    //
    void initEPWM1()
    {
        //
        // Setup TBCLK
        //
        EPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_UP);
        EPWM_setTimeBasePeriod(myEPWM1_BASE, EPWM1_TIMER_TBPRD);
        EPWM_disablePhaseShiftLoad(myEPWM1_BASE);
        EPWM_setPhaseShift(myEPWM1_BASE, 0U);
        EPWM_setTimeBaseCounter(myEPWM1_BASE, 0U);
    
        //
        // Set ePWM clock pre-scaler
        //
        EPWM_setClockPrescaler(myEPWM1_BASE,
                               EPWM_CLOCK_DIVIDER_2,
                               EPWM_HSCLOCK_DIVIDER_2);
    
        //
        // Setup shadow register load on ZERO
        //
        EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE,
                                             EPWM_COUNTER_COMPARE_A,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE,
                                             EPWM_COUNTER_COMPARE_B,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        //
        // Set Compare values
        //
        EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A,
                                    EPWM1_MIN_CMPA);
        EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B,
                                    EPWM1_MIN_CMPB);
    
        //
        // Set actions for ePWM1A & ePWM1B
        //
        // Set PWM1A on Zero
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        // Clear PWM1A on event A, up count
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    
        // Set PWM1B on Zero
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        // Clear PWM1B on event B, up count
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    
    //    // Set PWM1B on Zero
    //    EPWM_setActionQualifierAction(myEPWM1_BASE,
    //                                  EPWM_AQ_OUTPUT_B,
    //                                  EPWM_AQ_OUTPUT_HIGH,
    //                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
    //    // Clear PWM1B on event B, up count
    //    EPWM_setActionQualifierAction(myEPWM1_BASE,
    //                                  EPWM_AQ_OUTPUT_B,
    //                                  EPWM_AQ_OUTPUT_LOW,
    //                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    
        //
        // Interrupt where we will change the Compare Values
        //
        EPWM_setInterruptSource(myEPWM1_BASE, EPWM_INT_TBCTR_ZERO);
        EPWM_enableInterrupt(myEPWM1_BASE);
        EPWM_setInterruptEventCount(myEPWM1_BASE, 3U);
    
       //
       // Information this example uses to keep track
       // of the direction the CMPA/CMPB values are
       // moving, the min and max allowed values and
       // a pointer to the correct ePWM registers
       //
    
        // Start by increasing CMPA & CMPB
        epwm1Info.epwmCompADirection = EPWM_CMP_UP;
        epwm1Info.epwmCompBDirection = EPWM_CMP_UP;
    
        // Clear interrupt counter
        epwm1Info.epwmTimerIntCount = 0;
        epwm1Info.ePWMDone = 0;
    
        // Set base as ePWM1
        epwm1Info.epwmModule = myEPWM1_BASE;
    
        // Setup min/max CMPA/CMP values
        epwm1Info.epwmMaxCompA = EPWM1_MAX_CMPA;
        epwm1Info.epwmMinCompA = EPWM1_MIN_CMPA;
        epwm1Info.epwmMaxCompB = EPWM1_MAX_CMPB;
        epwm1Info.epwmMinCompB = EPWM1_MIN_CMPB;
    }
    
    //
    // initEPWM2 - Initialize EPWM2 values
    //
    void initEPWM2()
    {
        //
        // Setup TBCLK
        //
        EPWM_setTimeBaseCounterMode(myEPWM2_BASE, EPWM_COUNTER_MODE_UP);
        EPWM_setTimeBasePeriod(myEPWM2_BASE, EPWM2_TIMER_TBPRD);
        EPWM_disablePhaseShiftLoad(myEPWM2_BASE);
        EPWM_setPhaseShift(myEPWM2_BASE, 0U);
        EPWM_setTimeBaseCounter(myEPWM2_BASE, 0U);
    
        //
        // Set ePWM clock pre-scaler
        //
        EPWM_setClockPrescaler(myEPWM2_BASE,
                               EPWM_CLOCK_DIVIDER_2,
                               EPWM_HSCLOCK_DIVIDER_2);
    
        //
        // Setup shadow register load on ZERO
        //
        EPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE,
                                             EPWM_COUNTER_COMPARE_A,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE,
                                             EPWM_COUNTER_COMPARE_B,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        //
        // Set Compare values
        //
        EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A,
                                    EPWM2_MIN_CMPA);
        EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_B,
                                    EPWM2_MIN_CMPB); //EPWM2_MAX_CMPB
    
        //
        // Set actions for ePWM1A & ePWM1B
        //
        // Clear PWM2A on period and set on event A, up-count
    //    EPWM_setActionQualifierAction(myEPWM2_BASE,
    //                                  EPWM_AQ_OUTPUT_A,
    //                                  EPWM_AQ_OUTPUT_LOW,
    //                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
    //    EPWM_setActionQualifierAction(myEPWM2_BASE,
    //                                  EPWM_AQ_OUTPUT_A,
    //                                  EPWM_AQ_OUTPUT_HIGH,
    //                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    
        // Clear PWM2A on period and set on event A, up-count
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);// EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    
        // Clear PWM2B on Period & set on event B, up-count
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);// EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    
        //
        // Interrupt where we will change the Compare Values
        //
        EPWM_setInterruptSource(myEPWM2_BASE, EPWM_INT_TBCTR_ZERO);
        EPWM_enableInterrupt(myEPWM2_BASE);
        EPWM_setInterruptEventCount(myEPWM2_BASE, 3U);
    
        //
        // Information this example uses to keep track
        // of the direction the CMPA/CMPB values are
        // moving, the min and max allowed values and
        // a pointer to the correct ePWM registers
        //
    
        // Start by increasing CMPA & decreasing CMPB
        epwm2Info.epwmCompADirection = EPWM_CMP_UP;
        epwm2Info.epwmCompBDirection = EPWM_CMP_DOWN;
    
        // Clear interrupt counter
        epwm2Info.epwmTimerIntCount = 0;
    
        // Set base as ePWM2
        epwm2Info.epwmModule = myEPWM2_BASE;
    
        // Setup min/max CMPA/CMP values
        epwm2Info.epwmMaxCompA = EPWM2_MAX_CMPA;
        epwm2Info.epwmMinCompA = EPWM2_MIN_CMPA;
        epwm2Info.epwmMaxCompB = EPWM2_MAX_CMPB;
        epwm2Info.epwmMinCompB = EPWM2_MIN_CMPB;
    }
    
    //
    // initEPWM3 - Initialize EPWM3 values
    //
    void initEPWM3(void)
    {
        //
        // Setup TBCLK
        //
        EPWM_setTimeBaseCounterMode(myEPWM3_BASE, EPWM_COUNTER_MODE_UP);
        EPWM_setTimeBasePeriod(myEPWM3_BASE, EPWM3_TIMER_TBPRD);
        EPWM_disablePhaseShiftLoad(myEPWM3_BASE);
        EPWM_setPhaseShift(myEPWM3_BASE, 0U);
        EPWM_setTimeBaseCounter(myEPWM3_BASE, 0U);
    
        //
        // Set ePWM clock pre-scaler
        //
        EPWM_setClockPrescaler(myEPWM3_BASE,
                               EPWM_CLOCK_DIVIDER_1,
                               EPWM_HSCLOCK_DIVIDER_1);
    
        //
        // Setup shadow register load on ZERO
        //
        EPWM_setCounterCompareShadowLoadMode(myEPWM3_BASE,
                                             EPWM_COUNTER_COMPARE_A,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareShadowLoadMode(myEPWM3_BASE,
                                             EPWM_COUNTER_COMPARE_B,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        //
        // Set Compare values
        //
        EPWM_setCounterCompareValue(myEPWM3_BASE, EPWM_COUNTER_COMPARE_A,
                                    EPWM3_MIN_CMPA);
        EPWM_setCounterCompareValue(myEPWM3_BASE, EPWM_COUNTER_COMPARE_B,
                                    EPWM3_MAX_CMPB);
    
        //
        // Set actions for ePWM1A & ePWM1B
        //
        // Set PWM3A on event B, up-count & clear on event B, up-count
        EPWM_setActionQualifierAction(myEPWM3_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(myEPWM3_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    
        // Toggle EPWM3B on counter = zero
        EPWM_setActionQualifierAction(myEPWM3_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_TOGGLE,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
    
        //
        // Interrupt where we will change the Compare Values
        //
        EPWM_setInterruptSource(myEPWM3_BASE, EPWM_INT_TBCTR_ZERO);
        EPWM_enableInterrupt(myEPWM3_BASE);
        EPWM_setInterruptEventCount(myEPWM3_BASE, 3U);
    
       //
       // Information this example uses to keep track
       // of the direction the CMPA/CMPB values are
       // moving, the min and max allowed values and
       // a pointer to the correct ePWM registers
       //
    
        // Start by increasing CMPA & decreasing CMPB
        epwm3Info.epwmCompADirection = EPWM_CMP_UP;
        epwm3Info.epwmCompBDirection = EPWM_CMP_UP;
    
        // Start the count at 0
        epwm3Info.epwmTimerIntCount = 0;
    
        // Set base as ePWM1
        epwm3Info.epwmModule = myEPWM3_BASE;
    
        // Setup min/max CMPA/CMP values
        epwm3Info.epwmMaxCompA = EPWM3_MAX_CMPA;
        epwm3Info.epwmMinCompA = EPWM3_MIN_CMPA;
        epwm3Info.epwmMaxCompB = EPWM3_MAX_CMPB;
        epwm3Info.epwmMinCompB = EPWM3_MIN_CMPB;
    }
    
    //
    // updateCompare - Update the compare values for the specified EPWM
    //
    void updateCompare(epwmInfo *epwm_info)
    {
       //
       // Every 10'th interrupt, change the CMPA/CMPB values
       //
       if(epwm_info->epwmTimerIntCount == 10)
       {
           epwm_info->epwmTimerIntCount = 0;
           compAVal = EPWM_getCounterCompareValue(epwm_info->epwmModule,
                                                  EPWM_COUNTER_COMPARE_A);
           compBVal = EPWM_getCounterCompareValue(epwm_info->epwmModule,
                                                  EPWM_COUNTER_COMPARE_B);
    //       if (compAVal==epwm_info->epwmMaxCompA) {epwm1Info.ePWMDone = 1;}
           //
           // If we were increasing CMPA, check to see if
           // we reached the max value.  If not, increase CMPA
           // else, change directions and decrease CMPA
           //
           if(epwm_info->epwmCompADirection == EPWM_CMP_UP)
           {
               if(compAVal < epwm_info->epwmMaxCompA)
               {
                   EPWM_setCounterCompareValue(epwm_info->epwmModule,
                                               EPWM_COUNTER_COMPARE_A, ++compAVal);
                   AshikFlag = AshikFlag+1;
               }
               else
               {
    //               epwm_info->epwmCompADirection = EPWM_CMP_DOWN;
    //               EPWM_setCounterCompareValue(epwm_info->epwmModule,
    //                                           EPWM_COUNTER_COMPARE_A, --compAVal);
    //               epwm1Info.ePWMDone = 1;
    
               }
    
           }
    
           //
           // If we were decreasing CMPA, check to see if
           // we reached the min value.  If not, decrease CMPA
           // else, change directions and increase CMPA
           //
           else
           {
               if(compAVal == epwm_info->epwmMinCompA)
               {
                   epwm_info->epwmCompADirection = EPWM_CMP_UP;
                   EPWM_setCounterCompareValue(epwm_info->epwmModule,
                                               EPWM_COUNTER_COMPARE_A, ++compAVal);
    
               }
               else
               {
                   EPWM_setCounterCompareValue(epwm_info->epwmModule,
                                               EPWM_COUNTER_COMPARE_A, --compAVal);
               }
           }
    
           //
           // If we were increasing CMPB, check to see if
           // we reached the max value.  If not, increase CMPB
           // else, change directions and decrease CMPB
           //
           if(epwm_info->epwmCompBDirection == EPWM_CMP_UP)
           {
               if(compBVal < epwm_info->epwmMaxCompB)
               {
                   EPWM_setCounterCompareValue(epwm_info->epwmModule,
                                               EPWM_COUNTER_COMPARE_B, ++compBVal);
               }
               else
               {
    //               epwm_info->epwmCompBDirection = EPWM_CMP_DOWN;
    //               EPWM_setCounterCompareValue(epwm_info->epwmModule,
    //                                           EPWM_COUNTER_COMPARE_B, --compBVal);
    
               }
           }
    
           //
           // If we were decreasing CMPB, check to see if
           // we reached the min value.  If not, decrease CMPB
           // else, change directions and increase CMPB
           //
           else
           {
               if(compBVal == epwm_info->epwmMinCompB)
               {
                   epwm_info->epwmCompBDirection = EPWM_CMP_UP;
                   EPWM_setCounterCompareValue(epwm_info->epwmModule,
                                               EPWM_COUNTER_COMPARE_B, ++compBVal);
               }
               else
               {
                   EPWM_setCounterCompareValue(epwm_info->epwmModule,
                                               EPWM_COUNTER_COMPARE_B, --compBVal);
               }
           }
       }
    
       //
       // Increment interrupt count if < 10
       //
       else
       {
          epwm_info->epwmTimerIntCount++;
       }
    
       return;
    
    }
    //
    // End of file
    //
    

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

    您好 Ashik:

    很高兴您能够获得所需的占空比。 对于相位要求、您可以在 PWM 的中断子例程中添加一个检查、检查占空比是否达到50%。 达到50%后、您可以选择更改相位值。

    实际上、如果不会给计时计算带来麻烦、那么当前的方法也没有问题。

    更通用的方法是、您可以在 ISR 中读取比较器值并检查它是否达到50%、然后可以根据这种方法选择更新相位值。

    谢谢。

    Aditya.

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

    感谢 Aditya

    您能告诉我、除了更改 TBPRD 值外、如何更改开关频率? 目前、ePWM_Timer_TBPRD 值为2000、给出的频率为12.5kHz。 我需要100kHz 的开关频率。

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

    //###########################################################################
    //
    // FILE:   epwm_ex13_up_aq.c
    //
    // TITLE:  Action Qualifier Module - Using up count.
    //
    //! \addtogroup driver_example_list
    //! <h1> EPWM Action Qualifier (epwm_up_aq)</h1>
    //!
    //! This example configures ePWM1, ePWM2, ePWM3 to produce an
    //! waveform with independent modulation on EPWMxA and
    //! EPWMxB.
    //!
    //! The compare values CMPA and CMPB are modified within the ePWM's ISR.
    //!
    //! The TB counter is in up count mode for this example.
    //!
    //! View the EPWM1A/B(GPIO0 & GPIO1), EPWM2A/B(GPIO2 & GPIO3)
    //! and EPWM3A/B(GPIO4 & GPIO5) waveforms via an oscilloscope.
    //!
    //
    //###########################################################################
    //
    //
    // $Copyright:
    // Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //###########################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    //
    // Defines
    //
    #define EPWM1_TIMER_TBPRD  100  // Period register //2000
    #define EPWM1_MAX_CMPA     50   //1000
    #define EPWM1_MIN_CMPA       0
    #define EPWM1_MAX_CMPB     50     //1000
    #define EPWM1_MIN_CMPB       0
    
    #define EPWM2_TIMER_TBPRD  100  // Period register
    #define EPWM2_MAX_CMPA     50  //1950
    #define EPWM2_MIN_CMPA      0   //50
    #define EPWM2_MAX_CMPB     50  //1950
    #define EPWM2_MIN_CMPB      0   //50
    
    #define EPWM3_TIMER_TBPRD  100  // Period register
    #define EPWM3_MAX_CMPA      50
    #define EPWM3_MIN_CMPA       0
    #define EPWM3_MAX_CMPB      50
    #define EPWM3_MIN_CMPB       0
    
    #define EPWM_CMP_UP           1
    #define EPWM_CMP_DOWN         0
    
    //
    // Globals
    //
    typedef struct
    {
        uint32_t epwmModule;
        uint16_t epwmCompADirection;
        uint16_t epwmCompBDirection;
        uint16_t epwmTimerIntCount;
        uint16_t ePWMDone;
        uint16_t epwmMaxCompA;
        uint16_t epwmMinCompA;
        uint16_t epwmMaxCompB;
        uint16_t epwmMinCompB;
    } epwmInfo;
    
    epwmInfo epwm1Info;
    epwmInfo epwm2Info;
    epwmInfo epwm3Info;
    uint16_t AshikFlag = 0 ; //Ashik Added
    uint16_t Ph = 0 ; //Ashik Added
    uint16_t loop_counter = 0 ; //Ashik Added
    
    volatile uint16_t compAVal, compBVal;
    
    //
    //  Function Prototypes
    //
    void initEPWM1(void);
    void initEPWM2(void);
    void initEPWM3(void);
    __interrupt void epwm1ISR(void);
    __interrupt void epwm2ISR(void);
    __interrupt void epwm3ISR(void);
    void updateCompare(epwmInfo*);
    
    //
    // 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();
    
        //
        // For this case just init GPIO pins for ePWM1, ePWM2, ePWM3
        //
        Board_init();
    
        //
        // Interrupts that are used in this example are re-mapped to
        // ISR functions found within this file.
        //
        Interrupt_register(INT_EPWM1, &epwm1ISR);
        Interrupt_register(INT_EPWM2, &epwm2ISR);
        Interrupt_register(INT_EPWM3, &epwm3ISR);
    
        //
        // Disable sync(Freeze clock to PWM as well)
        //
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        // Initialize PWM1 without phase shift as master
        initEPWM1();
    
        // Initialize PWM2 with phase shift of X
        initEPWM2();
        //EPWM_selectPeriodLoadEvent(myEPWM2_BASE, EPWM_SHADOW_LOAD_MODE_SYNC);
        //EPWM_setPhaseShift(myEPWM2_BASE, Ph); //ashik added Ph
       // EPWM_setTimeBaseCounter(myEPWM2_BASE, Ph); //ashik added Ph
    
        initEPWM3();
    
        EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO);
    
        //
        // ePWM2 uses the ePWM 1 SYNCO as its SYNCIN.
        // ePWM2 SYNCO is generated from its SYNCIN, which is ePWM1 SYNCO
        //
        EPWM_setSyncOutPulseMode(myEPWM2_BASE, EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN);
    
        //
        // ePWM4 uses the ePWM 1 SYNCO as its SYNCIN.
        //
        //SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM4, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT);
        //
        // Enable all phase shifts.
        //
        EPWM_enablePhaseShiftLoad(myEPWM2_BASE);
    
        //
        // Enable sync and clock to PWM
        //
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        //
        // Enable interrupts required for this example
        //
        Interrupt_enable(INT_EPWM1);
        Interrupt_enable(INT_EPWM2);
        Interrupt_enable(INT_EPWM3);
    
        //
        // Enable global Interrupts and higher priority real-time debug events:
        //
        EINT;  // Enable Global interrupt INTM
        ERTM;  // Enable Global realtime interrupt DBGM
    
        //
        // IDLE loop. Just sit and loop forever (optional):
        //
        for(;;)
        {
            asm ("  NOP");
        }
    }
    
    //
    // epwm1ISR - EPWM1 ISR to update compare values
    //
    __interrupt void epwm1ISR(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        updateCompare(&epwm1Info);
    
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(myEPWM1_BASE);
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    //
    // epwm2ISR - EPWM2 ISR to update compare values
    //
    __interrupt void epwm2ISR(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        if (loop_counter!=AshikFlag)
        {
        updateCompare(&epwm2Info);
        }
        else
        {
    
            //Ph=300;
            EPWM_selectPeriodLoadEvent(myEPWM2_BASE, EPWM_SHADOW_LOAD_MODE_SYNC);
            EPWM_setPhaseShift(myEPWM2_BASE, Ph); //ashik added Ph
            EPWM_setTimeBaseCounter(myEPWM2_BASE, Ph); //ashik added Ph
    
        }
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(myEPWM2_BASE);
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    //
    // epwm3ISR - EPWM3 ISR to update compare values
    //
    __interrupt void epwm3ISR(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        updateCompare(&epwm3Info);
    
        //
        // Clear INT flag for this timer
        //
        EPWM_clearEventTriggerInterruptFlag(myEPWM3_BASE);
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    //
    // initEPWM1 - Initialize EPWM1 values
    //
    void initEPWM1()
    {
        //
        // Setup TBCLK
        //
        EPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_UP);
        EPWM_setTimeBasePeriod(myEPWM1_BASE, EPWM1_TIMER_TBPRD);
        EPWM_disablePhaseShiftLoad(myEPWM1_BASE);
        EPWM_setPhaseShift(myEPWM1_BASE, 0U);
        EPWM_setTimeBaseCounter(myEPWM1_BASE, 0U);
    
        //
        // Set ePWM clock pre-scaler
        //
        EPWM_setClockPrescaler(myEPWM1_BASE,
                               EPWM_CLOCK_DIVIDER_2,
                               EPWM_HSCLOCK_DIVIDER_2);
    
        //
        // Setup shadow register load on ZERO
        //
        EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE,
                                             EPWM_COUNTER_COMPARE_A,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE,
                                             EPWM_COUNTER_COMPARE_B,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        //
        // Set Compare values
        //
        EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A,
                                    EPWM1_MIN_CMPA);
        EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B,
                                    EPWM1_MIN_CMPB);
    
        //
        // Set actions for ePWM1A & ePWM1B
        //
        // Set PWM1A on Zero
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        // Clear PWM1A on event A, up count
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    
        // Set PWM1B on Zero
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        // Clear PWM1B on event B, up count
        EPWM_setActionQualifierAction(myEPWM1_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    
    //    // Set PWM1B on Zero
    //    EPWM_setActionQualifierAction(myEPWM1_BASE,
    //                                  EPWM_AQ_OUTPUT_B,
    //                                  EPWM_AQ_OUTPUT_HIGH,
    //                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
    //    // Clear PWM1B on event B, up count
    //    EPWM_setActionQualifierAction(myEPWM1_BASE,
    //                                  EPWM_AQ_OUTPUT_B,
    //                                  EPWM_AQ_OUTPUT_LOW,
    //                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    
        //
        // Interrupt where we will change the Compare Values
        //
        EPWM_setInterruptSource(myEPWM1_BASE, EPWM_INT_TBCTR_ZERO);
        EPWM_enableInterrupt(myEPWM1_BASE);
        EPWM_setInterruptEventCount(myEPWM1_BASE, 3U);
    
       //
       // Information this example uses to keep track
       // of the direction the CMPA/CMPB values are
       // moving, the min and max allowed values and
       // a pointer to the correct ePWM registers
       //
    
        // Start by increasing CMPA & CMPB
        epwm1Info.epwmCompADirection = EPWM_CMP_UP;
        epwm1Info.epwmCompBDirection = EPWM_CMP_UP;
    
        // Clear interrupt counter
        epwm1Info.epwmTimerIntCount = 0;
        epwm1Info.ePWMDone = 0;
    
        // Set base as ePWM1
        epwm1Info.epwmModule = myEPWM1_BASE;
    
        // Setup min/max CMPA/CMP values
        epwm1Info.epwmMaxCompA = EPWM1_MAX_CMPA;
        epwm1Info.epwmMinCompA = EPWM1_MIN_CMPA;
        epwm1Info.epwmMaxCompB = EPWM1_MAX_CMPB;
        epwm1Info.epwmMinCompB = EPWM1_MIN_CMPB;
    }
    
    //
    // initEPWM2 - Initialize EPWM2 values
    //
    void initEPWM2()
    {
        //
        // Setup TBCLK
        //
        EPWM_setTimeBaseCounterMode(myEPWM2_BASE, EPWM_COUNTER_MODE_UP);
        EPWM_setTimeBasePeriod(myEPWM2_BASE, EPWM2_TIMER_TBPRD);
        EPWM_disablePhaseShiftLoad(myEPWM2_BASE);
        EPWM_setPhaseShift(myEPWM2_BASE, 0U);
        EPWM_setTimeBaseCounter(myEPWM2_BASE, 0U);
    
        //
        // Set ePWM clock pre-scaler
        //
        EPWM_setClockPrescaler(myEPWM2_BASE,
                               EPWM_CLOCK_DIVIDER_2,
                               EPWM_HSCLOCK_DIVIDER_2);
    
        //
        // Setup shadow register load on ZERO
        //
        EPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE,
                                             EPWM_COUNTER_COMPARE_A,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE,
                                             EPWM_COUNTER_COMPARE_B,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        //
        // Set Compare values
        //
        EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A,
                                    EPWM2_MIN_CMPA);
        EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_B,
                                    EPWM2_MIN_CMPB); //EPWM2_MAX_CMPB
    
        //
        // Set actions for ePWM1A & ePWM1B
        //
        // Clear PWM2A on period and set on event A, up-count
    //    EPWM_setActionQualifierAction(myEPWM2_BASE,
    //                                  EPWM_AQ_OUTPUT_A,
    //                                  EPWM_AQ_OUTPUT_LOW,
    //                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
    //    EPWM_setActionQualifierAction(myEPWM2_BASE,
    //                                  EPWM_AQ_OUTPUT_A,
    //                                  EPWM_AQ_OUTPUT_HIGH,
    //                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    
        // Clear PWM2A on period and set on event A, up-count
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);// EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    
        // Clear PWM2B on Period & set on event B, up-count
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);// EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD
        EPWM_setActionQualifierAction(myEPWM2_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    
        //
        // Interrupt where we will change the Compare Values
        //
        EPWM_setInterruptSource(myEPWM2_BASE, EPWM_INT_TBCTR_ZERO);
        EPWM_enableInterrupt(myEPWM2_BASE);
        EPWM_setInterruptEventCount(myEPWM2_BASE, 3U);
    
        //
        // Information this example uses to keep track
        // of the direction the CMPA/CMPB values are
        // moving, the min and max allowed values and
        // a pointer to the correct ePWM registers
        //
    
        // Start by increasing CMPA & decreasing CMPB
        epwm2Info.epwmCompADirection = EPWM_CMP_UP;
        epwm2Info.epwmCompBDirection = EPWM_CMP_DOWN;
    
        // Clear interrupt counter
        epwm2Info.epwmTimerIntCount = 0;
    
        // Set base as ePWM2
        epwm2Info.epwmModule = myEPWM2_BASE;
    
        // Setup min/max CMPA/CMP values
        epwm2Info.epwmMaxCompA = EPWM2_MAX_CMPA;
        epwm2Info.epwmMinCompA = EPWM2_MIN_CMPA;
        epwm2Info.epwmMaxCompB = EPWM2_MAX_CMPB;
        epwm2Info.epwmMinCompB = EPWM2_MIN_CMPB;
    }
    
    //
    // initEPWM3 - Initialize EPWM3 values
    //
    void initEPWM3(void)
    {
        //
        // Setup TBCLK
        //
        EPWM_setTimeBaseCounterMode(myEPWM3_BASE, EPWM_COUNTER_MODE_UP);
        EPWM_setTimeBasePeriod(myEPWM3_BASE, EPWM3_TIMER_TBPRD);
        EPWM_disablePhaseShiftLoad(myEPWM3_BASE);
        EPWM_setPhaseShift(myEPWM3_BASE, 0U);
        EPWM_setTimeBaseCounter(myEPWM3_BASE, 0U);
    
        //
        // Set ePWM clock pre-scaler
        //
        EPWM_setClockPrescaler(myEPWM3_BASE,
                               EPWM_CLOCK_DIVIDER_1,
                               EPWM_HSCLOCK_DIVIDER_1);
    
        //
        // Setup shadow register load on ZERO
        //
        EPWM_setCounterCompareShadowLoadMode(myEPWM3_BASE,
                                             EPWM_COUNTER_COMPARE_A,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareShadowLoadMode(myEPWM3_BASE,
                                             EPWM_COUNTER_COMPARE_B,
                                             EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
        //
        // Set Compare values
        //
        EPWM_setCounterCompareValue(myEPWM3_BASE, EPWM_COUNTER_COMPARE_A,
                                    EPWM3_MIN_CMPA);
        EPWM_setCounterCompareValue(myEPWM3_BASE, EPWM_COUNTER_COMPARE_B,
                                    EPWM3_MAX_CMPB);
    
        //
        // Set actions for ePWM1A & ePWM1B
        //
        // Set PWM3A on event B, up-count & clear on event B, up-count
        EPWM_setActionQualifierAction(myEPWM3_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_HIGH,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(myEPWM3_BASE,
                                      EPWM_AQ_OUTPUT_A,
                                      EPWM_AQ_OUTPUT_LOW,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    
        // Toggle EPWM3B on counter = zero
        EPWM_setActionQualifierAction(myEPWM3_BASE,
                                      EPWM_AQ_OUTPUT_B,
                                      EPWM_AQ_OUTPUT_TOGGLE,
                                      EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
    
        //
        // Interrupt where we will change the Compare Values
        //
        EPWM_setInterruptSource(myEPWM3_BASE, EPWM_INT_TBCTR_ZERO);
        EPWM_enableInterrupt(myEPWM3_BASE);
        EPWM_setInterruptEventCount(myEPWM3_BASE, 3U);
    
       //
       // Information this example uses to keep track
       // of the direction the CMPA/CMPB values are
       // moving, the min and max allowed values and
       // a pointer to the correct ePWM registers
       //
    
        // Start by increasing CMPA & decreasing CMPB
        epwm3Info.epwmCompADirection = EPWM_CMP_UP;
        epwm3Info.epwmCompBDirection = EPWM_CMP_UP;
    
        // Start the count at 0
        epwm3Info.epwmTimerIntCount = 0;
    
        // Set base as ePWM1
        epwm3Info.epwmModule = myEPWM3_BASE;
    
        // Setup min/max CMPA/CMP values
        epwm3Info.epwmMaxCompA = EPWM3_MAX_CMPA;
        epwm3Info.epwmMinCompA = EPWM3_MIN_CMPA;
        epwm3Info.epwmMaxCompB = EPWM3_MAX_CMPB;
        epwm3Info.epwmMinCompB = EPWM3_MIN_CMPB;
    }
    
    //
    // updateCompare - Update the compare values for the specified EPWM
    //
    void updateCompare(epwmInfo *epwm_info)
    {
       //
       // Every 10'th interrupt, change the CMPA/CMPB values
       //
       if(epwm_info->epwmTimerIntCount == 10)
       {
           epwm_info->epwmTimerIntCount = 0;
           compAVal = EPWM_getCounterCompareValue(epwm_info->epwmModule,
                                                  EPWM_COUNTER_COMPARE_A);
           compBVal = EPWM_getCounterCompareValue(epwm_info->epwmModule,
                                                  EPWM_COUNTER_COMPARE_B);
    //       if (compAVal==epwm_info->epwmMaxCompA) {epwm1Info.ePWMDone = 1;}
           //
           // If we were increasing CMPA, check to see if
           // we reached the max value.  If not, increase CMPA
           // else, change directions and decrease CMPA
           //
           if(epwm_info->epwmCompADirection == EPWM_CMP_UP)
           {
               if(compAVal < epwm_info->epwmMaxCompA)
               {
                   EPWM_setCounterCompareValue(epwm_info->epwmModule,
                                               EPWM_COUNTER_COMPARE_A, ++compAVal);
                   AshikFlag = AshikFlag+1;
               }
               else
               {
    //               epwm_info->epwmCompADirection = EPWM_CMP_DOWN;
    //               EPWM_setCounterCompareValue(epwm_info->epwmModule,
    //                                           EPWM_COUNTER_COMPARE_A, --compAVal);
    //               epwm1Info.ePWMDone = 1;
    
               }
    
           }
    
           //
           // If we were decreasing CMPA, check to see if
           // we reached the min value.  If not, decrease CMPA
           // else, change directions and increase CMPA
           //
           else
           {
               if(compAVal == epwm_info->epwmMinCompA)
               {
                   epwm_info->epwmCompADirection = EPWM_CMP_UP;
                   EPWM_setCounterCompareValue(epwm_info->epwmModule,
                                               EPWM_COUNTER_COMPARE_A, ++compAVal);
    
               }
               else
               {
                   EPWM_setCounterCompareValue(epwm_info->epwmModule,
                                               EPWM_COUNTER_COMPARE_A, --compAVal);
               }
           }
    
           //
           // If we were increasing CMPB, check to see if
           // we reached the max value.  If not, increase CMPB
           // else, change directions and decrease CMPB
           //
           if(epwm_info->epwmCompBDirection == EPWM_CMP_UP)
           {
               if(compBVal < epwm_info->epwmMaxCompB)
               {
                   EPWM_setCounterCompareValue(epwm_info->epwmModule,
                                               EPWM_COUNTER_COMPARE_B, ++compBVal);
               }
               else
               {
    //               epwm_info->epwmCompBDirection = EPWM_CMP_DOWN;
    //               EPWM_setCounterCompareValue(epwm_info->epwmModule,
    //                                           EPWM_COUNTER_COMPARE_B, --compBVal);
    
               }
           }
    
           //
           // If we were decreasing CMPB, check to see if
           // we reached the min value.  If not, decrease CMPB
           // else, change directions and increase CMPB
           //
           else
           {
               if(compBVal == epwm_info->epwmMinCompB)
               {
                   epwm_info->epwmCompBDirection = EPWM_CMP_UP;
                   EPWM_setCounterCompareValue(epwm_info->epwmModule,
                                               EPWM_COUNTER_COMPARE_B, ++compBVal);
               }
               else
               {
                   EPWM_setCounterCompareValue(epwm_info->epwmModule,
                                               EPWM_COUNTER_COMPARE_B, --compBVal);
               }
           }
       }
    
       //
       // Increment interrupt count if < 10
       //
       else
       {
          epwm_info->epwmTimerIntCount++;
       }
    
       return;
    
    }
    //
    // End of file
    //

    尊敬的 Aditya:

    我现在的 PWM 频率是250kHz。 但当我使  AshikFlag 和 loop_counter==150时、EPWM2就会变得不稳定。 我可以更改相位、但 PWM 不稳定。 对这一点的任何见解都将有所帮助。

    Ashik

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您能告诉我除了更改 TBPRD 值之外、如何更改开关频率吗? 目前、ePWM_Timer_TBPRD 值为2000、给出的频率为12.5kHz。 我需要100kHz 的开关频率。

    1.可以更改 TBPRD 以获得所需的开关频率。 在本例中、我认为根据电流配置所需的值为250。

    2. 如果 HSPCLKDIV 和 CLKDIV 位当前不是最大值,则可以选择更新 HSPCLKDIV 和 CLKDIV 位,即它还不是/1

    谢谢。

    Aditya.