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.

[参考译文] TMS320F280039C:中断嵌套

Guru**** 2796165 points

Other Parts Discussed in Thread: TMS320F28388D

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1329961/tms320f280039c-interrupt-nesting

器件型号:TMS320F280039C
主题中讨论的其他器件:TMS320F28388D

 启用 SCI 和 CAN 中断后、我们的其中一个周期性中断(ePWM_ISR)的占空比出现增加。

CAN 中断每50ms 接收一次

启用 CLA

EPWM_ISR 设置为每~71us (14kHz)触发一次

ADC_ISR 设置为每~7us (140kHz)触发一次

在尚未启用 SCI 的情况下、ePWM_ISR 的最大占空比约为80%。

启用 SCI 中断时、即使未触发、EPWM_ISR 的最大占空比也会达到100%。

即使仍然没有数据通过、仅启用 SCI 中断也会对 EPWM_ISR 产生影响、这是否正常?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    即使仍然没有数据仍通过 SCI 中断仅启用 SCI 中断对 ePWM_ISR 产生影响是否正常?

    是的、由于 SCI + CAN IRQ/ISR 待处理访问 ePIE 较慢、TXD/RXD 需要 CPU 时间。 我们需要在 SCI 和 CAN ISR 中给 ePWM 最高的全局外设内核优先级。 一些 TI Wiki 页面概述了如何实现优先级顺序、但通常看到其他页面只在 ISR 调用中添加 DINT/ENT。

    C28x 中断嵌套

    (1)[常见问题解答]我的 C2000 SCI 无法正确发送和/或接收数据、如何解决此问题? - C2000微控制器论坛- C2000 ︎ 微控制器- TI E2E 支持论坛

    C2000 CLA 软件开发指南—C2000 CLA 软件指南

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

    如果您在谈论 PWM 波形的占空比或处理 PWM 中断的延迟、则不清楚。 如果您谈论的是前者、启用其他中断应该不会影响占空比。 如果您讨论后者、那么在启用更多中断时、预计延迟会增加。 话虽如此、如果 SCI 上没有活动、则不应生成中断、并且不应影响 PWM 运行。

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

    尊敬的 Genatco 和 Hareesh:

    感谢您的回复

    要向您提供 一些其他 详细信息、请参阅以下波形

    第一个 波形每50ms 接收一次 CAN 消息、SCI 仍未初始化。 EPWM_ISR 约为最大占空比的80%。

    第二个波形每50ms 接收一次 CAN 消息、SCI 被初始化并为 TX 和 RX 启用中断。 但 SCI 线路中没有消息。 ePWM_ISR 达到100%最大占空比。

    这里是 ISR 的一些代码片段、您可能会发现一些错误或有待改进的空间。 感谢您的帮助。

    __interrupt void ADC_ISR(void)
    {
        HWREGH(GPIODATA_BASE + GPIO_O_GPBSET) = 0x01; //GPIO32
        /* clear interrupt */
        HWREGH(ADCA_BASE + ADC_O_INTFLGCLR) = 1U << (dsp_math_uint16_t)ADC_INT_NUMBER1;
    
        /* user code */
    
        HWREGH(PIECTRL_BASE + PIE_O_ACK) = INTERRUPT_ACK_GROUP1;
        HWREGH(GPIODATA_BASE + GPIO_O_GPBCLEAR) = 0x01; //GPIO32
    }

    __interrupt void EPWM_ISR(void)
    {
        HWREGH(GPIODATA_BASE + GPIO_O_GPBSET) = 0x02; //GPIO33
        volatile dsp_math_uint16_t tempPIEIER1 = HWREGH(PIECTRL_BASE + PIE_O_IER1);
    
        IER |= INTERRUPT_CPU_INT1;
    
        HWREGH(PIECTRL_BASE + PIE_O_IER1) &= 0x0001;
    
        HWREGH(PIECTRL_BASE + PIE_O_ACK) = 0xFFFFU;
    
        __asm("  NOP");
    
        EINT;
    
        /* clear interrupt */
        HWREGH(EPWM1_BASE + EPWM_O_ETCLR) |= EPWM_ETCLR_INT;
    
        /* user code */
    
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
    
        DINT;
    
        HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER1;
        HWREGH(GPIODATA_BASE + GPIO_O_GPBCLEAR) = 0x02; //GPIO33
    }

    __interrupt void canISR(void)
    {
        HWREGH(GPIODATA_BASE + GPIO_O_GPASET) = 0x800; //GPIO11
        volatile uint16_t tempPIEIER1 = HWREGH(PIECTRL_BASE + PIE_O_IER1);
        volatile uint16_t tempPIEIER3 = HWREGH(PIECTRL_BASE + PIE_O_IER3);
    
        IER |= INTERRUPT_CPU_INT1 | INTERRUPT_CPU_INT3;
    
        HWREGH(PIECTRL_BASE + PIE_O_IER1) &= 0x0001;
        HWREGH(PIECTRL_BASE + PIE_O_IER3) &= 0x0001;
    
        HWREGH(PIECTRL_BASE + PIE_O_ACK) = 0xFFFFU;
    
        __asm("  NOP");
    
        EINT;
    
        /* user code */
    
        DINT;
    
        HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER1;
        HWREGH(PIECTRL_BASE + PIE_O_IER3) = tempPIEIER3;
        HWREGH(GPIODATA_BASE + GPIO_O_GPACLEAR) = 0x800; //GPIO11
    }

    __interrupt void sciaTXFIFOISR(void)
    {
        volatile uint16_t tempPIEIER1 = HWREGH(PIECTRL_BASE + PIE_O_IER1);
        volatile uint16_t tempPIEIER3 = HWREGH(PIECTRL_BASE + PIE_O_IER3);
    
        IER |= INTERRUPT_CPU_INT1 | INTERRUPT_CPU_INT3;
    
        HWREGH(PIECTRL_BASE + PIE_O_IER1) &= 0x0001;
        HWREGH(PIECTRL_BASE + PIE_O_IER3) &= 0x0001;
        HWREGH(PIECTRL_BASE + PIE_O_ACK) = 0xFFFFU;
    
        __asm("  NOP");
    
        EINT;
    
        /* user code */
    
        DINT;
    
        HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER1;
        HWREGH(PIECTRL_BASE + PIE_O_IER3) = tempPIEIER3;
    }

    __interrupt void sciaRXFIFOISR(void)
    {
        HWREG(GPIODATA_BASE + GPIO_O_GPASET) = 0x800000; //GPIO23
        volatile uint16_t tempPIEIER1 = HWREGH(PIECTRL_BASE + PIE_O_IER1);
        volatile uint16_t tempPIEIER3 = HWREGH(PIECTRL_BASE + PIE_O_IER3);
    
        IER |= INTERRUPT_CPU_INT1 | INTERRUPT_CPU_INT3;
    
        HWREGH(PIECTRL_BASE + PIE_O_IER1) &= 0x0001;
        HWREGH(PIECTRL_BASE + PIE_O_IER3) &= 0x0001;
        HWREGH(PIECTRL_BASE + PIE_O_ACK) = 0xFFFFU;
    
        __asm("  NOP");
    
        EINT;
    
        /* user code */
    
        DINT;
    
        HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER1;
        HWREGH(PIECTRL_BASE + PIE_O_IER3) = tempPIEIER3;
        HWREG(GPIODATA_BASE + GPIO_O_GPACLEAR) = 0x800000; //GPIO23
    }

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

    您好!
    您遇到的问题似乎与我遇到的问题类似。 当尝试通过四条 SCI (串行通信接口)线路的中断读取数据时、我可以读取所有数据而不会丢失任何数据(波特率:115200位/秒)。 但是、当我尝试通过中断读取带有 SCI 的两个 CAN (控制器局域网)通信时、我开始在 SCI 线路上丢失数据。 我还没有找到解决方案、但它看起来与您所面临的问题类似。 我正在使用 C2000:tms320f28388d。

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

    您好!

    看似 ePWM/ADC_ISR 不应具有任何 HWREG IR/PIER 或 EINT/DINT、ADC 样本的 ePIE 嵌套在 SCI 中控制、而在不同 ISR 组之间嵌套时、CAN ISR 则在 SCI 和 CAN ISR 中控制。 这些错误都应该给外设内核最高优先级、使 ADC ISR 成为 SOIC、在开始 ADC 采样的窗口时间内触发来自 ePWM (14kHz (71.43µs))的中断。  PPB 输出可控制 PWM 占空比的 EPWM CMPA 向上计数和向下计数。  

    我们随机发现的最大问题是 SCI_RX_FIFO 中断导致 RX 缓冲区溢出。 还必须测试 TX PIE_IFR 标志位已设置并调用以发送 FIFO 数据、或者它锁定 ePIE x49c (115,200BPS) 。TXD 循环在 ePWM 20kHz 50µs 以下运行循环。  

    	/* TX FIFO level interrupt full or ready status?  */
    	if((ui32IntStatus &SCI_INT_TXFF) || (ui32IntStatus &SCI_INT_TXRDY)) //
    	{
    
            /* Check IFR register flag is not late arriving */
            if(HWREGH(PIECTRL_BASE + PIE_O_IFR9) == PIE_IFR9_INTX4)
            {
                //HWREGH(SCIB_BASE + SCI_O_FFTX) |= SCI_FFTX_TXFFINTCLR;
    
                /* Block TX FIFO FULL status, disable transmit interrupt */
                while((HWREG(SCIB_BASE + SCI_O_FFTX &SCI_FFTX_TXFFST_M) >>
                                            SCI_FFTX_TXFFST_S) >= SCI_FIFO_TX8){}
                                            
                                            
            }
                                            
        
        }

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

    您好!

    当我删除 ePWM 和 ADC ISR 中的 HWREG IER/PIER 或 EINT/DINT 时、会使 ADC 时序混乱。 请参阅下面的波形

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

    您好、Ronald、

    似乎很奇怪、您为 RXFIFO 设置了两个 IER 标志位、并且每个优先级组 IRQ 是否只有一个 ISR。 还有一点、UMCSDK 不使用 ePWM ISR 作为函数 PWM hal.c 配置 ADC1触发源 SOC1 ADC1或您在 hal.h 中选择的任何 ISR。 也许霍尔配置使用 ePWM ISR? 但是、无传感器 FOC 使用 ADC 触发源来启动 SOC 采样、例如  HAL_setupPWM (HAL_MTR_Handle handle)。 我看到他们似乎为 BLDC 驱动器配置了 ePWM 中断。

    您使用什么模式。

    #else   //!(MOTOR1_ISBLDC || MOTOR1_DCLINKSS)
        // setup the Event Trigger Selection Register (ETSEL)
        EPWM_setInterruptSource(obj->pwmHandle[0], EPWM_INT_TBCTR_ZERO);
    
        EPWM_enableInterrupt(obj->pwmHandle[0]);
    
        EPWM_setADCTriggerSource(obj->pwmHandle[0],
                                 EPWM_SOC_A, EPWM_SOC_TBCTR_D_CMPC);
    
        EPWM_enableADCTrigger(obj->pwmHandle[0], EPWM_SOC_A);
    #endif  // !(MOTOR1_ISBLDC || MOTOR1_DCLINKSS)

        /* Get SCIB interrupt flag status */
        ui32IntStatus = SCI_getInterruptStatus(SCIB_BASE);
    
        /* The receive interrupt is cleared by performing
         * a single read of the receive INT status, or by clearing
         * the interrupt by writing a 1 to the RXIC bit. */
        SCI_clearInterruptStatus(SCIB_BASE, ui32IntStatus);
        //
        DINT;
        // Save group1 IER register on stack
        volatile uint16_t tempPIEIER = HWREGH(PIECTRL_BASE + PIE_O_IER1);
    
    	// Set "global" Group 1 priority
        IER |= M_INT1;
        IER &= M_INT1;
    
        /* Give ADCC1 priorty over SCIB RXD ISR */
        HWREGH(PIECTRL_BASE + PIE_O_IER1) &= PIE_IER1_INTX3;
        /* PieCtrlRegs.PIEACK.all = 0xFFFF */
        Interrupt_clearACKGroup(0xFFFFU);
        // Fix for Errata 4.1.1 B2B PIEACK writes.
        __asm("  NOP");
        //
        EINT;
    

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

    尊敬的 Genatco:

    有两个 IER 标志位、一个用于 ADC、另一个用于 ePWM。 它们都被配置为高优先级并应该优先于 CAN 和 SCI。

    中断优先级应遵循以下顺序。 ADC->ePWM->CAN->SCI

    更新了:当禁用 SCI_TX 中断时、ePWM 保持在80%的占空比。 如果我们改为轮询、仍然需要检查它的影响。

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

    尝试将 SCI_TX 转换为非中断、并将 SCI_RX 保持为中断。

    ePWM 占空比仍然达到100%的频率不如以前高、但仍然达到、尤其是当有消息通过 SCI 线路传入时。

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

    您好、Ronald、

    为什么您的代码要服务 ePWM 中断源? FAST 估算器 ISR (FOC)使用 motor1CtrlISR ()组1 ADCn 中断源。 很抱歉在我看来造成了任何混淆、以为您是在添加通用电机控制示例代码。 如果不是实际使用 ePWM ISR、请不要将 C 代码配置为处理未使用的 ISR。 设置 FAST 估算器的 ADC 触发源 Sock、以处理 Park 变换数据、从而产生正弦波交流相电流。  

    通过使用 EPWM 来触发 ADC 源 Sock、EOCn 脉冲中断会使 ADC 保持对同步 CMPA 负载值进行采样。 因此、通常将下一个周期的占空比设置为 TBCLK = 0。 然而、具有霍尔效应锁存器的 BLDC 能够通过 ePWM ISR 进行全局同步更新(CMPn x3)、以避免在直流逆变器或半桥上发生虚假 PWM 脉冲。 但是、UMCSDK 示例代码中的 FAST 估算器库似乎并未配置 ePWM ISR 处理程序、因为 BLDC 模式只会将 user_mtr1.h #define USER_M1_MAX_VS_MAG_PU 设置  为在每个相位上创建梯形波形。   

    //! 简明设置 USER_MAX_VS_MAG = 2/3 = 0.6666来生成梯形
    //! 短电压波形。 将需要使用电流重构技术
    //! 此场景的简介(Lab08)。

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

    Ronald、

      您的问题是否已得到解决?

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

    您好、Hareesh:

    问题在于中断嵌套代码。 当重新启用较高中断时、较低的中断保持不变。 这就是更低中断可以意外取代更高中断(ePWM)的原因。