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.

TMS320F280025C: 关于ePWM模块信号同步时,会有周期性不同步

Part Number: TMS320F280025C

利用两个epwm模块 epwm1A和 epwm2A。epwm1A设置为同步信号输出,epwm2A接收epwm1A的同步信号。当epwm1A的PRD改变时,CMA变为0.1*PRD。epwm2A的PRD跟随epwm1A变化,CMA也是0.1*PRD。而此过程,epwm1A与epwm2A的相对相移需要一直保持恒定。

正常情况如下,这是我需要的波形。注意绿色为1A,黄色为2A,后面的波形都是以此情况。

但是在运行过程中,它会周期性出现以下两种波形,这是为什么?

只有当我的PRD由小变大的时候才出现,而PRD由大变小一切正常。如下图。

代码配置如下

初始化PWM

改变PRD,CMA,PHS代码如下

  • 您好,您的初始化代码中,有关装载的配置只明确配置了ePWM2的周期装载时刻,我建议您将装载的时刻全部都明确配置一下试试看。

    另外希望您除了上传代码截图以外,也能一并将代码通过代码插入功能上传,谢谢:

  • 你好,非常感谢你的回复,我明确配置了EPWM1的装载方式,问题仍然存在。根据手册,利用寄存器LINK,问题也没有解决。代码如下。

    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    __interrupt void cpuTimer0ISR(void);
    void initCPUTimers(void);
    void configCPUTimer(uint32_t cpuTimer, float freq, float period);
    void pin_init(void);
    void init_PWM(void);
    #define myEPWM1_BASE EPWM1_BASE
    #define myEPWM2_BASE EPWM2_BASE
    uint32_t epwm_period1 = 1000;
    uint32_t epwm_compare1 = 100;
    uint32_t epwm_shift = 500;
    //
    // Main
    //
    void main(void)
    {
        //
        // Initializes device clock and peripherals
        //
        Device_init();
        //
        // Initializes PIE and clears PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
        //
        // Initializes the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
        pin_init();
        init_PWM();
        initCPUTimers();
        //
        // Configure CPU-Timer 0,
        //
        configCPUTimer(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 100);
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
        //
        // ISRs for each CPU Timer interrupt
        //
        Interrupt_register(INT_TIMER0, &cpuTimer0ISR);
        //
        // Enables CPU int1 which are connected to CPU-Timer 0.
        // Enable TINT0 in the PIE: Group 1 interrupt 7
        //
        Interrupt_enable(INT_TIMER0);
        //
        // Starts CPU-Timer 0.
        //
        CPUTimer_startTimer(CPUTIMER0_BASE);
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
        while(1)
        {
    
    
        }
    }
    __interrupt void
    cpuTimer0ISR(void)
    {
        if(epwm_period1 == 1000)
        {
            epwm_period1 = 100;
            epwm_compare1 = 10;
            epwm_shift = 50;
            //updata epwm1 and epwm2 CMA
            HWREG(0X0000406B)=epwm_compare1;
            HWREG(0X0000416B)=epwm_compare1;
            //updata epwm1 and epwm2 PRD
            HWREG(0X00004063)=epwm_period1;
            HWREG(0X00004163)=epwm_period1;
            //updata epwm2 PHS
            HWREG(0X00004161)=epwm_shift;
        }
        else if(epwm_period1 == 100)
        {
            epwm_period1 = 1000;
            epwm_compare1 = 100;
            epwm_shift = 500;
    
    
            //updata epwm1 and epwm2 PRD
            HWREG(0X00004063)=epwm_period1;
            HWREG(0X00004163)=epwm_period1;
            //updata epwm1 and epwm2 CMA
            HWREG(0X0000406B)=epwm_compare1;
            HWREG(0X0000416B)=epwm_compare1;
            //updata epwm2 PHS
            HWREG(0X00004161)=epwm_shift;
        }
        //
        // Acknowledge this interrupt to receive more interrupts from group 1
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
    }
    
    void
    initCPUTimers(void)
    {
        //
        // Initialize timer period to maximum
        //
        CPUTimer_setPeriod(CPUTIMER0_BASE, 0xFFFFFFFF);
    
    
        //
        // Initialize pre-scale counter to divide by 1 (SYSCLKOUT)
        //
        CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);
    
    
        //
        // Make sure timer is stopped
        //
        CPUTimer_stopTimer(CPUTIMER0_BASE);
    
        //
        // Reload all counter register with period value
        //
        CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);
    
    
    }
    void
    configCPUTimer(uint32_t cpuTimer, float freq, float period)
    {
        uint32_t temp;
    
        //
        // Initialize timer period:
        //
        temp = (uint32_t)((freq / 1000000) * period);
        CPUTimer_setPeriod(cpuTimer, temp);
    
        //
        // Set pre-scale counter to divide by 1 (SYSCLKOUT):
        //
        CPUTimer_setPreScaler(cpuTimer, 0);
    
        //
        // Initializes timer control register. The timer is stopped, reloaded,
        // free run disabled, and interrupt enabled.
        // Additionally, the free and soft bits are set
        //
        CPUTimer_stopTimer(cpuTimer);
        CPUTimer_reloadTimerCounter(cpuTimer);
        CPUTimer_setEmulationMode(cpuTimer,
                                  CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
        CPUTimer_enableInterrupt(cpuTimer);
    
    
    }
    void init_PWM(void)
    {
        EPWM_setClockPrescaler(myEPWM1_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
        EPWM_setTimeBasePeriod(myEPWM1_BASE, 1000);
        EPWM_setPeriodLoadMode(myEPWM1_BASE, EPWM_PERIOD_SHADOW_LOAD);
        EPWM_selectPeriodLoadEvent(myEPWM1_BASE, EPWM_SHADOW_LOAD_MODE_COUNTER_ZERO);
        EPWM_setTimeBaseCounter(myEPWM1_BASE, 0);
        EPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_UP);
        EPWM_disablePhaseShiftLoad(myEPWM1_BASE);
        EPWM_setPhaseShift(myEPWM1_BASE, 0);
        EPWM_enableSyncOutPulseSource(myEPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);
        EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, 500);
        EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B, 500);
        EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    
        EPWM_setClockPrescaler(myEPWM2_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
        EPWM_setTimeBasePeriod(myEPWM2_BASE, 1000);
        EPWM_setPeriodLoadMode(myEPWM2_BASE, EPWM_PERIOD_SHADOW_LOAD);
        EPWM_selectPeriodLoadEvent(myEPWM2_BASE, EPWM_SHADOW_LOAD_MODE_COUNTER_SYNC);
        EPWM_setTimeBaseCounter(myEPWM2_BASE, 0);
        EPWM_setTimeBaseCounterMode(myEPWM2_BASE, EPWM_COUNTER_MODE_UP);
        EPWM_enablePhaseShiftLoad(myEPWM2_BASE);
        EPWM_setPhaseShift(myEPWM2_BASE, 500);
        EPWM_setSyncInPulseSource(myEPWM2_BASE, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);
        EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A, 500);
        EPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_B, 500);
        EPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);
        EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
        EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    
    }
    void pin_init(void)
    {
        GPIO_setPinConfig(GPIO_0_EPWM1_A);
        GPIO_setPinConfig(GPIO_1_EPWM1_B);
    
        GPIO_setPinConfig(GPIO_2_EPWM2_A);
        GPIO_setPinConfig(GPIO_3_EPWM2_B);
    
    
    }
    //
    // End of File
    //
    

  • 方便发下您的工程吗?我看下

  • Yale LI,你好。你将我发的代码放入tms320f28002x的空工程就好啦。将代码拷贝,粘帖到empty_projectmain.c中即可。要使用drverlib哈。 我使用的是2820025c ladpad.

  • 好的,我看一下