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:内核2上相同配置的 ePWM 模块之间的行为不同

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1030641/tms320f28379d-different-behavior-between-identically-configured-epwm-modules-on-core-2

器件型号:TMS320F28379D

我有一个项目利用了 CPU2提供的所有12个 PWM 模块。 所有引脚的配置几乎完全相同、但在探测输出时、只有 PWM<7-12>看起来工作正常、对应 PWM<1-6>的12个输出引脚在没有开关的情况下处于高电平或低电平。

下面显示的是 EPWM6的配置、但几乎相同的配置用于所有器件。

void init()
{
    // PWM H
    GPIO_setPadConfig(10, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_10_EPWM6A);
    GPIO_setMasterCore(10, GPIO_CORE_CPU2);
    // PWM L
    GPIO_setPadConfig(11, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_11_EPWM6B);
    GPIO_setMasterCore(11, GPIO_CORE_CPU2);
    
    SysCtl_selectCPUForPeripheral(SYSCTL_CPUSEL0_EPWM, 6, SYSCTL_CPUSEL_CPU2);
    
    base = EPWM6_BASE;
    
    EPWM_setTimeBasePeriod(base, 1000);
    EPWM_setPhaseShift(base, 0U);
    EPWM_setTimeBaseCounter(base, 0U);
    EPWM_disableInterrupt(base);
    
    EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, 0U);
    EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_B, 0U);
    
    EPWM_setTimeBaseCounterMode(base, EPWM_COUNTER_MODE_UP_DOWN);
    EPWM_disablePhaseShiftLoad(base);
    EPWM_setClockPrescaler(base, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
    
    EPWM_setCounterCompareShadowLoadMode(base, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
    EPWM_setCounterCompareShadowLoadMode(base, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
    
    EPWM_setInterruptSource(base, EPWM_INT_TBCTR_ZERO);
    EPWM_enableInterrupt(base);
    EPWM_setInterruptEventCount(base, 10);
    Interrupt_enable(INT_EPWM6);

    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
}

__interrupt void pwm_isr(void)
{
    // new_val as placeholder for this demo
    EPWM_setCounterCompareValue(EPWM6_BASE, EPWM_COUNTER_COMPARE_A, new_val);
    EPWM_setCounterCompareValue(EPWM6_BASE, EPWM_COUNTER_COMPARE_B, new_val);

    EPWM_clearEventTriggerInterruptFlag(EPWM6_BASE);

    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
}

注: 为完整起见、上面包括了 SYSCTL_enablePeripheral (SYSCTL_Periph_CLK_TBCLKSYNC)调用。 实际上、直到所有 PWM 都被设置后、才会调用它。

我最初以为中断配置和处理可能会出错、但是如果我禁用 PWM<1-6>的中断并从 PWM<7-12>的 ISR 更新它们的比较寄存器、则仍然无法正常工作。

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

    Owen、所有 ePWM 分配给 CPU2?

    是否在 CPU2上完成了 ePWM 寄存器的所有配置?

    EPWM1-6配置与 EPWM7-12有何区别?

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

    NIMA、所有 EPWM 都分配给 CPU2。 在将所有配置信息一起拉到一个函数中(如上所示)时、CPU1正在运行第4-12行这一事实丢失了。 在我的实际程序中、CPU1将所有 ePWM 模块委派给 CPU2并设置 GPIO 配置。  

    ePWM 模块配置全部发生在 CPU2上。  任何 ePWM 配置之间都不应存在差异-它们都使用与上面所示完全相同的代码(在我的项目中、它进行了参数化、因此我只能传递不同的基址)。  

    以下是我的项目中的实际 init_pwm ()函数:

    void init_epwm(uint32_t base, bool ie)
    {
    	// Set-up TBCLK
    	EPWM_setTimeBasePeriod(base, EPWM_TIMER_TBPRD);
    	EPWM_setPhaseShift(base, 0U);
    	EPWM_setTimeBaseCounter(base, 0U);
    	EPWM_disableInterrupt(base);
    
    	// Set Compare values
    	EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, 0U);
    	EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_B, 0U);
    
    	// Set up counter mode
    	EPWM_setTimeBaseCounterMode(base, EPWM_COUNTER_MODE_UP_DOWN);//EPWM_COUNTER_MODE_UP);
    	EPWM_disablePhaseShiftLoad(base);
    	EPWM_setClockPrescaler(base, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
    
    	// Set up shadowing
    	EPWM_setCounterCompareShadowLoadMode(base, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
    	EPWM_setCounterCompareShadowLoadMode(base, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO);
    
    	// Set actions - PWM A/B are configured to be inverse from one another, based on the CMPA register
    	EPWM_setActionQualifierAction(base,
    											EPWM_AQ_OUTPUT_A,
    											EPWM_AQ_OUTPUT_LOW,
    											EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    	EPWM_setActionQualifierAction(base,
    											EPWM_AQ_OUTPUT_A,
    											EPWM_AQ_OUTPUT_HIGH,
    											EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
    
    
    	EPWM_setActionQualifierAction(base,
    											EPWM_AQ_OUTPUT_B,
    											EPWM_AQ_OUTPUT_HIGH,
    											EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
    	EPWM_setActionQualifierAction(base,
    											EPWM_AQ_OUTPUT_B,
    											EPWM_AQ_OUTPUT_LOW,
    											EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
    
    	// Select INT on Time base counter zero event,
    	// Enable INT, generate INT on Nth event
    	if(ie)
    	{
    		EPWM_setInterruptSource(base, EPWM_INT_TBCTR_ZERO);
    		EPWM_enableInterrupt(base);
    		EPWM_setInterruptEventCount(base, EPWM_ISR_EVENT_COUNT);
    	}
    }

    下面是一个代码片段、展示了如何将 PWM 委派到其各自的电机组:

    	switch (m_num)
    	{
    	case M1:
    		pwm1_base = EPWM12_BASE;
    		pwm2_base = EPWM11_BASE;
    		pwm3_base = EPWM8_BASE;
    		break;
    	case M2:
    		pwm1_base = EPWM7_BASE;
    		pwm2_base = EPWM10_BASE;
    		pwm3_base = EPWM9_BASE;
    		break;
    	case M3:
    		pwm1_base = EPWM6_BASE;
    		pwm2_base = EPWM5_BASE;
    		pwm3_base = EPWM2_BASE;
    		break;
    	case M4:
    		pwm1_base = EPWM4_BASE;
    		pwm2_base = EPWM3_BASE;
    		pwm3_base = EPWM1_BASE;
    		break;
    
    	}

    下面是一个代码片段,显示了何时调用 init_ePWM()函数(分别用于 M1、M2、M3和 M4)。

    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
    	init_epwm(pwm1_base, true); // ie only for first PWM in group
    	init_epwm(pwm2_base, false);
    	init_epwm(pwm3_base, false);
    
    
    	switch (m_num)
    	{
    		case M1:
    				Interrupt_register(INT_EPWM12, &m1_pwm_isr)
    				Interrupt_enable(INT_EPWM12);
    				break;
    		case M2:
    				Interrupt_register(INT_EPWM7, &m2_pwm_isr);
    				Interrupt_enable(INT_EPWM7);
    				break;
    		case M3:
    				Interrupt_register(INT_EPWM6, &m3_pwm_isr);
    				Interrupt_enable(INT_EPWM6);
    				break;
    		case M4:
    				Interrupt_register(INT_EPWM4, &m4_pwm_isr);
    				Interrupt_enable(INT_EPWM4);
    				break;
    	}

    以下是4个 PWM 中断中每个中断的 ISR:

    __interrupt void m1_pwm_isr(void)
    {
        m1_tick();
    	// Clear INT flag for this timer
    	EPWM_clearEventTriggerInterruptFlag(EPWM12_BASE);
    
    	// Acknowledge interrupt group
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    __interrupt void m2_pwm_isr(void)
    {
        m2_tick();
    	// Clear INT flag for this timer
    	EPWM_clearEventTriggerInterruptFlag(EPWM7_BASE);
    
    	// Acknowledge interrupt group
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    __interrupt void m3_pwm_isr(void)
    {
        m3_tick();
    	// Clear INT flag for this timer
    	EPWM_clearEventTriggerInterruptFlag(EPWM6_BASE);
    
    	// Acknowledge interrupt group
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }
    
    __interrupt void m4_pwm_isr(void)
    {
        m4_tick();
    	// Clear INT flag for this timer
    	EPWM_clearEventTriggerInterruptFlag(EPWM4_BASE);
    
    	// Acknowledge interrupt group
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    }

    应该注意的是、与 M1和 M2相关的 ePWM 模块没有问题-只有 M3和 M4 (PWM<1-6>)似乎不工作(输出不切换、但被驱动)。  

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

    Owen、

    我刚刚检查了、它们都可以在 CPU2上访问。 您的代码中必须存在导致此问题的小逻辑错误。 您能否创建一个仅具有不工作的 ePWM (仅一个 ePWM)的小型项目并对其进行测试?

    NIMA

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

    NIMA、所有 PWM 模块都在单独的测试项目中工作。 我的问题不是 PWM 配置、而是我的 PWM ISR 花费太长时间、这不会更新与 M3和 M4关联的 PWM (巧合的是 PWM<1-6>)。 问题已解决。

    再次感谢!

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

    Owen、

    感谢您的回复! 我很高兴一切都得到了解决。 我已经关闭了线程。

    NIMA