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.

[参考译文] MSP432P401R:Launchpad S2 GPIO中断错误

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/618474/msp432p401r-launchpad-s2-gpio-interrupt-bug

部件号:MSP432P401R

我正在尝试编写一些简单的代码,以便使用Launchpad上的两个开关打开和关闭板载LED。 但是,只要我在端口1引脚4上启用中断,中断标志就会出现。 此引脚连接到Launchpad上的开关2 (常开),并在其关闭时将引脚连接到GND。 我开始做一些实验,当我启用端口1引脚5上的中断时也会发生这种情况,该端口1引脚5没有连接到任何按钮。 我已经使用了几种不同的配置,但我根本不知道为什么在启用中断时会发生中断。 端口1引脚1具有完全相同的寄存器和交换机配置,不会以这种方式运行。

我最初使用TI的驱动程序库为MSP432编写代码,然后通过设置寄存器值再次编写代码。 两个代码都有相同的问题。

我尝试了将引脚配置为具有下拉功能的输入时的上升边缘触发和将引脚配置为具有上拉功能的输入时的下降边缘中断触发,这两个引脚都有相同的问题。 我知道在MSP430s上,当寄存器初始化到正在设置的标志时,您必须清除中断。 但是,P1IFG寄存器将初始化为所有未断言的标志。

代码如下:

void main (void)
{
WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; //停止监视计时器

/* S1 */
GPIO_setAsInputPinWithPullUp阻 器(GPIO_PORT_P1, GPIO_PIN1);

/* S2 */
GPIO_setAsInputPinWithPullUp阻 器(GPIO_PORT_P1, GPIO_PIN4);

/*红色LED */
GPIO _setAsOutputPin (GPIO端口P1,GPIO _PIN0);
GPIO _setOutputLowOnPin (GPIO端口P1,GPIO _PIN0);

GPIO中断边缘选择(GPIO_PORT_P1, GPIO PIN1, GPIO高电平转换);
GPIO中断边缘选择(GPIO_PORT_P1, GPIO_PIN4, GPIO高电平转换);

//上3位控制硬件优先级,下7位控制子优先级
InterrupT_setPriority (INT_Port1,0xC0);

GPIO注册器中断(GPIO_PORT_P1, InputIRQHandler);

中断= gPIO_getEnabledInterruptStatus(GPIO_PORT_P1);

GPIO _启用中断(GPIO_PORT_P1, GPIO _PIN1);
GPIO _启用中断(GPIO_PORT_P1, GPIO _PIN4);

/*注册级别代码
P1->SEL0 &=~BIT4;
P1->SEL1 &=~BIT4;
P1->DIR &=~BIT4;
P1->OUT |= BIT4;
P1->REN |= BIT4;
P1->IES |= BIT4;
P1->IE |= BIT4;
*/

interrup_enableMaster();

whid(1);
}

void inputIRQHandler(void){

UINT_FAST16_t中断;

中断= gPIO_getEnabledInterruptStatus(GPIO_PORT_P1);

IF (中断和GPIO _PIN1)
{
GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN1);
GPIO _setOutputLowOnPin (GPIO_PORT_P1, GPIO _PIN0);
}

IF (中断和GPIO _PIN4)
{
GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN4);
GPIO _setOutputHighOnPin (GPIO_PORT_P1, GPIO _PIN0);
}
} 

有什么想法吗?

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

    我知道您在上一个陈述中编写了该声明,但在您的代码中看不到它,因此,在启用所用中断之前,请先清除所有GPIO IFG,以确保之前的事件没有触发标志,该标志将在您启用后立即触发您的ISR 中断?

    P1->IFG &=~BIT4;

    GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN4);

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

    Dietmar的建议是否解决了您的问题。

    谢谢!

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

    下面是我的代码:

    #include <stdint.h>/*
    
    MSP432 driverlib includes */
    #include <ti/devices/msp432p4xx/driverlib/gPIO.h>
    #include <ti/devices/msp432p4xx/driverlib/interrupti.h>
    
    void inputIRQHandler(void){
    
    UINT_FAST16_t中断;
    
    中断= gPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
    
    IF (中断和GPIO _PIN1)
    {
    GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN1);
    GPIO _setOutputLowOnPin (GPIO_PORT_P1, GPIO _PIN0);
    }
    
    IF (中断和GPIO _PIN4)
    {
    GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN4);
    GPIO _setOutputHighOnPin (GPIO_PORT_P1, GPIO _PIN0);
    }
    }
    
    void main(void){
    
    UINT_FAST16_t中断;
    
    WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; //停止监视计时器
    
    interrup_disableMaster();
    
    /* S1 */
    GPIO_setAsInputPinWithPullUp阻 器(GPIO_PORT_P1, GPIO_PIN1);
    
    /* S2 */
    GPIO_setAsInputPinWithPullUp阻 器(GPIO_PORT_P1, GPIO_PIN4);
    
    
    /*红色LED */
    GPIO _setAsOutputPin (GPIO端口P1,GPIO _PIN0);
    GPIO _setOutputLowOnPin (GPIO端口P1,GPIO _PIN0);
    
    GPIO中断边缘选择(GPIO_PORT_P1, GPIO PIN1, GPIO高电平转换);
    GPIO中断边缘选择(GPIO_PORT_P1, GPIO_PIN4, GPIO高电平转换);
    
    //上3位控制硬件优先级,下7位控制子优先级
    //中断_setPriority (INT_Port1,0xC0);
    
    GPIO _启用中断(GPIO_PORT_P1, GPIO _PIN1);
    GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN1);
    GPIO _启用中断(GPIO_PORT_P1, GPIO _PIN4);
    GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN4);
    
    GPIO注册器中断(GPIO_PORT_P1, InputIRQHandler);
    
    中断= gPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
    
    interrup_enableMaster();
    
    中断= gPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
    
    while (1);
    } 

    我发现主中断在默认情况下是启用的,所以我在执行所有设置之前禁用了它,并在设置结束时重新启用它。 我在启用主中断之前和之后检查GPIO中断状态。 两次都显示未声明中断标志,但ISR仍输入一次。 但是,由于ISR逻辑检查GPIO中断标志(这些标志仍然都未断言),因此ISR不执行任何操作。

    当我注释掉清除GPIO中断标志的代码时,返回其状态的函数将显示与WFP 1.4 关联的中断已声明。 我一启用中断,就好像中断就以某种方式锁定在NVIC中。 这甚至可能吗? 我是99 % ,确定这不是按钮的问题,因为WFP 1.1 的配置完全相同,不会出现此问题。 我尝试用与WFP 1.1 和WFP 1.4 相同的方法在端口1上设置所有的引脚,只有WFP 1.5 (一个浮动引脚)也表现出这种奇怪的行为,一启动就断言中断。  

    有什么想法吗?

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

    我使用CMSIS函数 NVIC_GetPendingIRQ(Port1_IRQn)来检查NVIC中端口1中断的状态。 在我启用了WFP 1.4 中断之前,该功能返回0。 之后,它返回1。 因此,启用中断会导致断言NVIC端口1中断。 怎么会发生这种情况?

    此代码似乎可以修复它,但我不应该为了使其正常运行而清除特定的引脚中断。 我想确切地了解在启用此特定的引脚中断时,会发生什么情况导致自动断言此特定的引脚中断。

    #include <stdint.h>/*
    
    MSP432 driverlib includes */
    #include <ti/devices/msp432p4xx/driverlib/gPIO.h>
    #include <ti/devices/msp432p4xx/driverlib/interrupti.h>
    
    void inputIRQHandler(void){
    
    UINT_FAST16_t中断;
    
    中断= gPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
    
    IF (中断和GPIO _PIN1)
    {
    GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN1);
    GPIO _setOutputLowOnPin (GPIO_PORT_P1, GPIO _PIN0);
    }
    
    IF (中断和GPIO _PIN4)
    {
    GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN4);
    GPIO _setOutputHighOnPin (GPIO_PORT_P1, GPIO _PIN0);
    }
    }
    
    void main(void){
    
    UINT_FAST16_t中断;
    
    WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; //停止监视计时器
    
    interrup_disableMaster();
    
    /* S1 */
    GPIO_setAsInputPinWithPullUp阻 器(GPIO_PORT_P1, GPIO_PIN1);
    
    /* S2 */
    GPIO_setAsInputPinWithPullUp阻 器(GPIO_PORT_P1, GPIO_PIN4);
    
    
    /*红色LED */
    GPIO _setAsOutputPin (GPIO端口P1,GPIO _PIN0);
    GPIO _setOutputLowOnPin (GPIO端口P1,GPIO _PIN0);
    
    GPIO中断边缘选择(GPIO_PORT_P1, GPIO PIN1, GPIO高电平转换);
    GPIO中断边缘选择(GPIO_PORT_P1, GPIO_PIN4, GPIO高电平转换);
    
    //上3位控制硬件优先级,下7位控制子优先级
    //中断_setPriority (INT_Port1,0xC0);
    
    GPIO _启用中断(GPIO_PORT_P1, GPIO _PIN1);
    GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN1);
    GPIO _启用中断(GPIO_PORT_P1, GPIO _PIN4);
    GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN4);
    
    NVIC_ClearPendingIRQ (端口1_IRQn);
    
    GPIO注册器中断(GPIO_PORT_P1, InputIRQHandler);
    
    interrup_enableMaster();
    
    while (1);
    }
    
    

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

    你好,Nicholas,

    请告诉我您使用的是哪个Launchpad版本(可能发送图片)。 另外,请告诉我芯片的标记,以便我知道您组装的模具版本。

    我将使用RevC器件设置启动板v 1.9 ,并将尝试MSP432 1.40 - v:01.00 示例"gPIO_INPUT_INTERRUC"示例,使驱动程序库实现虚拟化。

    结果出来后,我会再找你们。

    此致,
    Dietmar

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

    我使用了下面的代码,它按预期工作。 仅当按下S1或S2时,LED才会亮起。 按下任何按钮后,指示灯都不会亮起。
    您是否有第二个启动垫,您可以尝试,也许您的芯片已损坏。 另请尝试以下代码。

    * MSP432 GPIO -输入中断
    *
    *说明:此示例演示了的一个非常简单的用例
    * DriverLib GPIO API。 配置了WFP 1.1 (连接了一个交换机)
    *在启用中断和WFP 1.0 (连接LED)的情况下作为输入
    *配置为输出。 按下开关时,LED输出
    *已切换。
    *
    * MSP432P401
    * -----------
    * /|\\| |
    * || |
    * --|RST WFP 1.0 |-->WFP 1.0 LED
    * | |
    * | WFP 1.1 |<--切换开关
    * | |
    * | |
    *
    ***************** /
    /* DriverLib包括*/
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>

    /*标准包括*/
    #include <stdint.h>
    #include <stdbool.h>

    内部主(无效)

    易失性UINT32_t ii;

    /*停止监视程序*/
    MAP_WDT_A_HoldTimer();

    /*将WFP 1.0 配置为输出,将WFP 1.1 (开关)配置为输入*/
    MAP_GPIO_setAsOutputPin (GPIO端口P1,GPIO _PIN0);
    GPIO _setOutputLowOnPin (GPIO端口P1,GPIO _PIN0);

    /*将WFP 1.1 配置为输入并启用中断*/
    MAP_GPIO_setAsInputPinWithPullUp阻 器(GPIO_PORT_P1, GPIO_PIN1);
    MAP_GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN1);
    MAP_GPIO_enableInterrupt (GPIO端口_P1,GPIO _PIN1);

    /*将WFP 1.4 配置为输入并启用中断*/
    MAP_GPIO_setAsInputPinWithPullUp阻 器(GPIO_PORT_P1, GPIO_PIN4);
    MAP_GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN4);
    MAP_GPIO_enableInterrupt (GPIO端口P1,GPIO_PIN4);
    MAP_Interrupt_enableInterrupt (INT_Port1);

    /*启用SRAM Bank Retention */
    map_sysctl_enableSRAMBankRetention (sysctl_SRAM_Bank1);

    /*启用主中断*/
    MAP_Interrupt_enableMaster();

    /*转至LPM3 */
    同时(1)

    MAP_PCM_GotoLPM3();
    }
    }

    /* GPIO ISR */
    void Port1_IRQHandler(void)

    UINT32_t状态;

    状态= MAP_GPIO _getEnabledInterruptStatus(GPIO_PORT_P1);


    /*切换LED上的输出*/
    IF (状态和GPIO _PIN1)

    MAP_GPIO清除InterruptFlag (GPIO端口P1,状态);
    MAP_GPIO_toggleOutputOnPin (GPIO端口P1,GPIO _PIN0);
    }


    IF (状态和GPIO _PIN4)


    MAP_GPIO清除InterruptFlag (GPIO端口P1,状态);
    MAP_GPIO_toggleOutputOnPin (GPIO端口P1,GPIO _PIN0);
    }


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

    尝试在ISR中设置断点,并查看它是否进入。 我发布的代码正常工作,但意外进入ISR,没有明显的原因。

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

    尼古拉斯,

    当然,我也尝试了它的断点,但一旦让程序通过调试器运行,它就不会进入ISR。

    第一次进入ISR时,我按下了2个按钮之一。

    您能告诉我您使用的启动板版本和设备吗? 也许有不同之处。

    此致,
    Dietmar

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

    我正在使用MSP-EXP432P401R Rev 2.1 Launchpad

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Nicholas,谢谢,我会尝试让版本2.1 尝试复制它,因为我的版本1.9 看不到它。
    我有了结果后,会及时向您发布信息。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尼古拉斯,

    幸运的是,我得到了一个全新的2.1 Launchpad,组装了Rev C。 在使用我的CCSv7环境运行项目之前,我尝试了上面发布的代码并在ISR内设置了断点,但未按按钮就无法看到ISR已执行。

    请更新到最新的驱动程序库(与我使用的版本相同)并重试。 否则,我会假设您的启动板上的某个部件已损坏。 您是否在ESD安全环境中根据ESD处理准则使用此设备?
    您没有关联权限的第二个启动板?

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

    我明白了。 我是在启用中断后直接清除中断标志,而不是直接在它之前清除。 我改变了

    GPIO_enableInterrupt (GPIO端口P1,GPIO PIN4);
    GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN4); 

    GPIO清除InterruptFlag (GPIO端口P1,GPIO PIN4);
    GPIO _启用中断(GPIO端口P1,GPIO PIN4); 

     它起了作用...只是表明您不能一定信任寄存器的默认值。 抱歉,没有问题。 我知道你早些时候曾建议过这一点,但我没有意识到我的旗帜是在中断启用之后才被清除的,这实际上是与清除旗帜的目的背道而驰的。 我仍然不知道为什么只有引脚4和5上的GPIO中断才会自动断言,但我想这也不是问题...感谢您的帮助!

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

    很高兴听到它在使用正确的编码时起作用。 只有部分GPIO显示它是随机的原因。 未初始化的位可以增加一个或另一个,取决于设备到设备的变化。 因此,务必注意所有GPIO设置,尤其是未使用的GPIO设置,以防止因浮动输入和意外功能行为导致的意外高电流。
    祝您的未来发展好运!