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.

[参考译文] MSP430FR2433:端口1中断问题:JMP __TI_ISR_TRAP

Guru**** 2531490 points
Other Parts Discussed in Thread: MSP430FR2433

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1078819/msp430fr2433-port-1-interrupt-problem-jmp-__ti_isr_trap

部件号:MSP430FR2433

我目前正在使用 msp430fr2433开发门磁性开关。(环境:CCS10.4.0)

首先,我尝试使用 driverlib 来加速我的开发。 由于启动板上的两个按钮与 P2.3和 P2.7相关联,示例代码上周运行良好,我认为它很简单。

但是,我自己的硬件上还有一个与 P1.1链接的按钮。 我尝试修改这样的代码。

void main (void)
{
    //Stop watchdog timer
    WDT_A_hold(WDT_A_BASE);

    //Set LED to output direction
    GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN0 + GPIO_PIN1);

    //Set LED pins HI
    GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN0 + GPIO_PIN1);

    //Enable S1,S2 internal resistance as pull-Up resistance
    GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1,GPIO_PIN5);
    GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P2,GPIO_PIN2 + GPIO_PIN3 + GPIO_PIN7);

    //S1,S2 interrupt enabled
    GPIO_enableInterrupt(GPIO_PORT_P1,GPIO_PIN5);
    GPIO_enableInterrupt(GPIO_PORT_P2,GPIO_PIN2 + GPIO_PIN3 + GPIO_PIN7);

    //S1 Hi/Lo edge
    GPIO_selectInterruptEdge(GPIO_PORT_P1,GPIO_PIN5,GPIO_HIGH_TO_LOW_TRANSITION);
    GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN2 + GPIO_PIN3 + GPIO_PIN7,GPIO_HIGH_TO_LOW_TRANSITION);


    //S1 IFG cleared
    GPIO_clearInterrupt(GPIO_PORT_P1,GPIO_PIN5);
    GPIO_clearInterrupt(GPIO_PORT_P2,GPIO_PIN2 + GPIO_PIN3 + GPIO_PIN7);

    PMM_unlockLPM5();

    //Enter LPM3 w/interrupt
    __bis_SR_register(LPM3_bits + GIE);

    //For debugger
    __no_operation();
}

#if GPIO_PORT_S1 == GPIO_PORT_P1
//******************************************************************************
//
//This is the PORT1_VECTOR interrupt vector service routine
//
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT1_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(PORT1_VECTOR)))
#endif
void P1_ISR (void)
{
    __delay_cycles(10000);
    GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN0 + GPIO_PIN1);
    GPIO_clearInterrupt(GPIO_PORT_P1,GPIO_PIN5);
}
#elif GPIO_PORT_S1 == GPIO_PORT_P2
//******************************************************************************
//
//This is the PORT2_VECTOR interrupt vector service routine
//
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT2_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(PORT2_VECTOR)))
#endif
void P2_ISR (void)
#endif // #if GPIO_PORT_S1
{
    __delay_cycles(10000);
    if (GPIO_getInterruptStatus(GPIO_PORT_P2 , GPIO_PIN2))
    {
        GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN0 + GPIO_PIN1);
        if (GPIO_INPUT_PIN_HIGH == GPIO_getInputPinValue(GPIO_PORT_P2 , GPIO_PIN2))
        {
            GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN2,GPIO_HIGH_TO_LOW_TRANSITION);
        }
        else
        {
            GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN2,GPIO_LOW_TO_HIGH_TRANSITION);
        }
    }

    if (GPIO_getInterruptStatus(GPIO_PORT_P2 , GPIO_PIN3))
    {
        GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN0);
        if (GPIO_INPUT_PIN_HIGH == GPIO_getInputPinValue(GPIO_PORT_P2 , GPIO_PIN3))
        {
            GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN3,GPIO_HIGH_TO_LOW_TRANSITION);
        }
        else
        {
            GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN3,GPIO_LOW_TO_HIGH_TRANSITION);
        }
    }

    if (GPIO_getInterruptStatus(GPIO_PORT_P2 , GPIO_PIN7))
    {
        GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN1);
        if (GPIO_INPUT_PIN_HIGH == GPIO_getInputPinValue(GPIO_PORT_P2 , GPIO_PIN7))
        {
            GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN7,GPIO_HIGH_TO_LOW_TRANSITION);
        }
        else
        {
            GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN7,GPIO_LOW_TO_HIGH_TRANSITION);
        }
    }

    GPIO_clearInterrupt(GPIO_PORT_P2,GPIO_PIN2 + GPIO_PIN3+GPIO_PIN7);
}

我已将此代码下载到启动板。 两个新按钮:P2.2和 P1.5,我使用 DuPont 电缆将它们短接到 GND,而不是按按钮。

然后出现了一些问题。 代码运行不好,在调试视图中,代码在 ISR_TRATE.ASM 的 JMP __TI_ISR_TRAP 处停止

我只在调试视图中按“开始”和“挂起”,但没有按硬件上的任何按钮。

我再次尝试使用原始示例,似乎  也是同样的问题。

我还尝试了不带驱动程序库的示例: msp430fr243x_P1_03.c,但也失败了。

我很困惑为什么会发生这种情况,我确信我的电脑在这个周末没有发生任何事情。

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

    你好,卢切尼,

    您能否分步运行并查看代码的运行位置? 我看到您的 ISR 出现了很多延迟。 您可以尝试减少延迟周期吗?

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

    >#Elif GPIO 端口_S1 == GPIO 端口_P2

    这会导致编译器生成 Port1_vector 或 port2_vector,但(按编码)您需要两者。  

    我建议您删除所有 GPIO 端口 S1检查,以便获得两个 ISR。

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

    通过查看其他帖子,我尝试使用 杜邦电缆快捷方式5V 和 GND 来让主板完全放电。 (启动板与计算机未连接)

    每次在释放硼后进行调试时,它都可以分步运行到: __bis_SR_register (LPM3_bits + GIE);

    当我按下连接到端口2的三个按钮时,它 仍然工作正常。

    当我尝试将 GND 快捷方式设置为 P1.5时(就像按下一个连接到 P1.5的按钮一样),代码就会消失:JMP __TI_ISR_TRAP。

    代码 ISR 中的 DELAY 循环用于键反跳,因为启动板上没有反跳电容器

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

    我尝试更改示例代码(版本不带驱动程序库)

    #include <msp430.h>
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;               // Stop watchdog timer
    
        // Configure GPIO
        P1OUT &= ~BIT0;                         // Clear P1.0 output latch for a defined power-on state
        P1DIR |= BIT0;                          // Set P1.0 to output direction
        P2OUT &= ~(BIT3+BIT7);
        P2DIR |= BIT3+BIT7;
    
        P1OUT |= BIT3;                          // Configure P1.3 as pulled-up
        P1REN |= BIT3;                          // P1.3 pull-up register enable
        P1IES |= BIT3;                          // P1.3 Hi/Low edge
        P1IE |= BIT3;                           // P1.3 interrupt enabled
        P2OUT |= BIT3+BIT7;                     // Configure P2.3&P2.7 as pulled-up
        P2REN |= BIT3+BIT7;                     // P2.3&P2.7 pull-up register enable
        P2IES |= BIT3+BIT7;                     // P2.3&P2.7 Hi/Low edge
        P2IE |= BIT3+BIT7;                      // P2.3&P2.7 interrupt enabled
    
        // Disable the GPIO power-on default high-impedance mode
        // to activate previously configured port settings
        PM5CTL0 &= ~LOCKLPM5;
    
        P1IFG &= ~BIT3;                         // P1.3 IFG cleared
        P2IFG &= ~(BIT3+BIT7);
    
        while(1)
        {
            __bis_SR_register(LPM3_bits | GIE); // Enter LPM3 w/interrupt
            __no_operation();                   // For debug
            P1OUT ^= BIT0;                      // P1.0 = toggle
        }
    }
    
    // Port 1 interrupt service routine
    #pragma vector=PORT1_VECTOR
    __interrupt void Port_1(void)
    {
        P1IFG &= ~BIT3;                         // Clear P1.3 IFG
        __bic_SR_register_on_exit(LPM3_bits);   // Exit LPM3
    }
    
    // Port 2 interrupt service routine
    #pragma vector=PORT2_VECTOR
    __interrupt void Port_2(void)
    {
        P2IFG &= ~(BIT3+BIT7);                         // Clear P1.3 IFG
        __bic_SR_register_on_exit(LPM3_bits);   // Exit LPM3
    }
    

    此代码现在似乎运行良好。

    然后我尝试更改示例代码(版本带有 driverlib)

    #include "driverlib.h"
    #include "Board.h"
    
    void main (void)
    {
        //Stop watchdog timer
        WDT_A_hold(WDT_A_BASE);
    
        //Set LED to output direction
        GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN0 + GPIO_PIN1);
    
        //Set LED pins HI
        GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN0 + GPIO_PIN1);
    
        //Enable S1,S2 internal resistance as pull-Up resistance
        GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1,GPIO_PIN5);
        GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P2,GPIO_PIN2 + GPIO_PIN3 + GPIO_PIN7);
    
        //S1,S2 interrupt enabled
        GPIO_enableInterrupt(GPIO_PORT_P1,GPIO_PIN5);
        GPIO_enableInterrupt(GPIO_PORT_P2,GPIO_PIN2 + GPIO_PIN3 + GPIO_PIN7);
    
        //S1 Hi/Lo edge
        GPIO_selectInterruptEdge(GPIO_PORT_P1,GPIO_PIN5,GPIO_HIGH_TO_LOW_TRANSITION);
        GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN2 + GPIO_PIN3 + GPIO_PIN7,GPIO_HIGH_TO_LOW_TRANSITION);
    
    
        //S1 IFG cleared
        GPIO_clearInterrupt(GPIO_PORT_P1,GPIO_PIN5);
        GPIO_clearInterrupt(GPIO_PORT_P2,GPIO_PIN2 + GPIO_PIN3 + GPIO_PIN7);
    
        PMM_unlockLPM5();
    
        //Enter LPM3 w/interrupt
        __bis_SR_register(LPM3_bits + GIE);
    
        //For debugger
        __no_operation();
    }
    
    //******************************************************************************
    //
    //This is the PORT1_VECTOR interrupt vector service routine
    //
    //******************************************************************************
    #pragma vector=PORT1_VECTOR
    void P1_ISR (void)
    {
        __delay_cycles(10000);
        GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN0 + GPIO_PIN1);
        GPIO_clearInterrupt(GPIO_PORT_P1,GPIO_PIN5);
    }
    //******************************************************************************
    //
    //This is the PORT2_VECTOR interrupt vector service routine
    //
    //******************************************************************************
    #pragma vector=PORT2_VECTOR
    void P2_ISR (void)
    {
        __delay_cycles(10000);
        if (GPIO_getInterruptStatus(GPIO_PORT_P2 , GPIO_PIN2))
        {
            GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN0 + GPIO_PIN1);
            if (GPIO_INPUT_PIN_HIGH == GPIO_getInputPinValue(GPIO_PORT_P2 , GPIO_PIN2))
            {
                GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN2,GPIO_HIGH_TO_LOW_TRANSITION);
            }
            else
            {
                GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN2,GPIO_LOW_TO_HIGH_TRANSITION);
            }
        }
    
        if (GPIO_getInterruptStatus(GPIO_PORT_P2 , GPIO_PIN3))
        {
            GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN0);
            if (GPIO_INPUT_PIN_HIGH == GPIO_getInputPinValue(GPIO_PORT_P2 , GPIO_PIN3))
            {
                GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN3,GPIO_HIGH_TO_LOW_TRANSITION);
            }
            else
            {
                GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN3,GPIO_LOW_TO_HIGH_TRANSITION);
            }
        }
    
        if (GPIO_getInterruptStatus(GPIO_PORT_P2 , GPIO_PIN7))
        {
            GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN1);
            if (GPIO_INPUT_PIN_HIGH == GPIO_getInputPinValue(GPIO_PORT_P2 , GPIO_PIN7))
            {
                GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN7,GPIO_HIGH_TO_LOW_TRANSITION);
            }
            else
            {
                GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN7,GPIO_LOW_TO_HIGH_TRANSITION);
            }
        }
    
        GPIO_clearInterrupt(GPIO_PORT_P2,GPIO_PIN2 + GPIO_PIN3+GPIO_PIN7);
    }
    

    出现了一些旧问题。 上周发生了这种情况,但昨天不能再发生,因此没有被发送出去。

    代码可以逐步调试,直到:_ bis_sr_register (LPM3_bits + GIE);

    但当我按下按钮时,就会发生这种情况。

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

    > 无效 P1_ISR (无效)

    这应该是:

    >__interrupt void P1_ISR (void)

    ---

    同样适用于 P2_ISR()

    ---

    未经请求:要启用引脚中断,您应该(1)设置 IES (2)清除 IFG (3)设置 IE。 您可以在清除 LOCKLPM5之前执行(1)操作,但必须在清除后执行(2)/(3)操作。 症状可能是假中断,而不是崩溃。

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

    它现在就工作了。

    感谢您的解释。