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:中断锁存

Guru**** 2587365 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/651909/msp432p401r-interrupt-latching

器件型号:MSP432P401R
主题中讨论的其他器件:MSP430FR2433

您好!

我的问题是有关 MSP432上的中断处理、也许更具体地说、NVIC 锁存中断的程度。 方案如下:

  1. 多个端口4输入中断被启用;
  2. 在端口4线路上发生中断、并进入处理程序;
  3. 当仍在处理程序中时、在第二个端口4线路上发生一个中断-第二个中断大概被"挂起";
  4. 在处理程序退出之前,第二个端口4行的端口 IE 位将被清除;
  5. 然后处理器退出。

那么会发生什么情况? 在我看来、有两种可能:

  • 由于 IE 位现在被清零、处理程序不会再次运行第二个中断;
  • ‘处理程序将再次运行,尽管 IE 位现在已被清除,因为 IE 位在第二次中断时仍然被置位,所以中断会进入“挂起”状态,而这是由 NVIC 锁存的。

我有一个奇怪的错误,我只能真正解释第二个答案是否正确,但我很难相信这是设计意图……

任何景色都很棒!

谢谢…。 圣诞快乐!

John

 

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

    John、

      MSP432技术参考手册中介绍了这种特殊情况、有关端口中断的第12.2.7节介绍了当 GPIO 中断有效而另一个端口中断仍处于 ISR 中时的预期行为: (请参阅下面红色部分以了解您的特定问题的答案-简短答案是您的第二个答案是正确的)。

    12.2.7端口中断

    特定端口的所有 Px 中断标志都被优先化、PxIFG.0是最高的、并且被组合在一起来提供一个中断向量。 使能的最高优先级的中断在 PxIV 寄存器中产生了一个数字。 这个数字可被评估或者被添加到程序计数器以自动进入适当的软件例程。 被禁用的 Px 中断不影响 PxIV 的值。 PxIV 寄存器仅为半字访问。

    每个 PxIFG 位是其相应 I/O 引脚的中断标志、当所选输入信号边沿出现在引脚上时、该标志被置位。 当它们相应的 PxIE 位被置位时、所有 PxIFG 中断标志请求一个中断。 软件还可以设置每个 PxIFG 标志、从而提供一种生成软件启动中断的方法。

      • 位= 0:无中断挂起
      • 位= 1:一个中断正暂挂

    只有转换而不是静态电平会导致中断。 如果在一个 Px 中断处理例程期间或在 Px 中断处理例程执行完成后任何 PxIFG 标志被置位、那么被置位的 PxIFG 标志会生成另一个中断。 这可确保确认每个转换。

    注意:更改 PxOUT、PxDIR 或 PxREN 时、PxIFG 标志
          写入 PxOUT、PxDIR 或 PxREN 会导致相应的 PxIFG 标志被置位。

    对 PxIV 寄存器的任何访问(读取或写入)都会自动复位最高优先级的挂起中断标志。 如果另一个中断标志被置位、则在处理完初始中断后会立即产生另一个中断。

    例如、假设 P1IFG.0具有最高优先级。 当中断服务子程序访问 P1IV 寄存器时、如果 P1IFG.0和 P1IFG.2标志被置位、P1IFG.0会自动复位。 P1IFG.0中断服务例程完成后、P1IFG.2会生成另一个中断。

     

    此致、

     Bob L.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢 Bob 花时间回复! 我本来打算仔细阅读本手册的那一部分,但我已经假设,即使第二条端口线路的 IFG 位被置位,清零第二条端口线路的 IE 位也会阻止第二个中断被占用..... 您似乎说手动操作必须非常准确、IE 位在这种情况下是不相关的、只有 IFG 标志是重要的? 这不是我所期望的,但我必须承认,这似乎是我所看到的…

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

    我对这一结果感到非常惊讶,我不得不尝试这一结果。

    Bob (一如既往)是正确的、但我要引用 SLAU356H sec 2.2.2.1-2 (似乎是根据 ARM 的 DUI0553A sec 4.2.9进行调整)。 我一直认为、由于 IV 的干预、GPIO 呈现了一个电平中断、但显然它是一个直接来自 IFG+IE 的脉冲。

    这种无用的小程序会点亮两个 Launchpad LED、对于电平中断、我只希望其中一个 LED 亮起。 调试器确认、在第二个 ISR 上调用 P1IE.4=0和 P1IV=0 (现在是这里的)。

    /**
    * main.c
    *此无脑示例演示了 GPIO 系统
    *向 NVIC 提供脉冲而不是电平中断。
    *按下 P1.1 Launchpad 按钮会使两个 LED 都亮起、
    *对于电平中断、我们只希望其中一个 LED 亮起。
    *在第二个 ISR 调用中停止显示(P1IFG&P1IE)=0、IV=0。
    //
    #include "MSP.h"
    void main (void)
    {
    WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD;//停止看门狗计时器
    // LED:
    P1->OUT &=~BIT0; // Launchpad P1.0 LED 关闭
    P1->DIR |= BIT0; //+输出
    P2->OUT &=~BIT0; // Launchpad P2.0 LED
    P2->DIR |= BIT0;
    //按钮:
    P1->OUT |= BIT1 |BIT4;// Launchpad 按钮
    P1->REN |= BIT1 |BIT4;//上拉
    P1->IES |= BIT1 |BIT4;//高->低
    __no_operation(); //按 PORT32
    P1->IFG &=~(BIT1 |BIT4);//清除过期
    P1->IE |= BIT1|BIT4;
    NVIC_EnableIRQ (Port1_IRQn);
    while (1)
    {
    __WFI ();
    }/*NOTREACHED*/
    
    RETURN;
    }
    
    void
    Port1_IRQHandler (void)
    {
    IF (P1->IFG 和 BIT1) //我按下(P1.1)按钮
    {
    _DELAY_CYCLES (50000); //廉价反跳
    P1->IFG &=~BIT1; //我想它现在是安静的
    P1->IFG |= BIT4; //触发 P1.4中断
    _DELAY_CYCLES (50); //以防发生传播竞争
    P1->IE &=~BIT4; //现在禁用它
    P1->OUT |= BIT0; //指示我们已到达此处
    的光 LED }
    如果(P1->IFG & BIT4) //我承诺我没有按下(P1.4)按钮
    {
    P1->IFG &=~BIT4; //谢谢,现在就走了
    P2->OUT |= BIT0; //指示我们已到达此处
    的光 LED }
    返回;
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢 Bruce! 嗯,我的词,真是个惊喜… 非常有价值的知识! 圣诞假期后,我想自己做一个小程序测试,但是你已经打败了我… 感谢您的帮助! 也要感谢 Bob。。。

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

    我自己已经玩过这个 只需添加一些最后的澄清(我相信您知道这一点、Bruce、但觉得值得在此发表):

    当、尽管 IE 位被清零、但第二次进入中断例程时、中断矢量实际上是零。 在这种情况下读取矢量寄存器不会清除 IFG 标志-它仍然被置位(很可能已经从技术手册信息中猜到)。

    假定 IFG 标志被保持置位:如果、在中断例程完成后的一段时间内、在正常程序流中、针对那个端口线路的 IE 标志再次被置位、 将触发一个进一步的中断-这更确切地证实了 Bruce 的建议、即这是一个从 IE 位导出的 NVIC 的"脉冲触发器"、并使用 IFG 位进行处理。 在这种情况下(假设 IE 位被左置位)、向量寄存器将包含预期值、读取它将按预期清除 IFG 标志。 因此、如果中断例程将"矢量寄存器= 0"情况正确处理为假中断(很遗憾、我的中断没有)、我怀疑在许多情况下一切都很好、尽管通过中断处理程序进行了额外的意外跳闸...

    再次感谢 Bruce、Bob、

    John

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

    如果有人想知道(我突然知道了):MSP430的行为是另一种方式。 我翻译了 MSP430FR2433的程序(在本例中)、并且只有一个 LED 亮起(没有第二个 ISR 调用):

    /**
    * main.c
    *此无脑示例演示了 MSP430 (FR2433) GPIO 系统
    *向中断控制器呈现更像一个级别中断。
    *按下 P2.3 Launchpad 按钮只会使一个 LED 亮起。
    *(没有第二个 ISR 调用。)
    */
    #include "msp430.h" // MSP430FR2433、但大多数情况下其 Launchpad
    void main (void)
    {
    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
    // LED:
    P1OUT &=~BIT0; // Launchpad P1.0 LED 关闭
    P1DIR |= BIT0; //+输出
    P1OUT &=~BIT1; // Launchpad P1.1 LED 关闭
    P1DIR |= BIT1; //+输出
    //按钮:
    P2OUT |= BIT3|BIT7; // Launchpad 按钮
    P2REN |= BIT3|BIT7; //上拉
    P2IES |= BIT3|BIT7; //高->低
    __no_operation(); //按 PORT32
    PM5CTL0 &=~LOCKLPM5;//现在应该正常
    P2IFG &=~(BIT3|BIT7);//清除过期
    P2IE |= BIT3|BIT7; //启用
    _EINT();
    P1OUT |= BIT0|BIT1; //确保两个 LED 都工作正常。
    __DELAY_CYCLES (50000);//大约半秒
    P1OUT &=~(BIT0|BIT1);//练习结束
    while (1)
    {
    LPM0;
    }
    /*NOTREACHED*/
    return;
    }
    
    #pragma vector=port2_vector
    __interrupt void
    port2_IRQHandler (void)
    {
    IF (P2IFG 和 BIT3) //我按下(P2.3)按钮
    {
    __DELAY_CYCLES (50000);//廉价反跳
    P2IFG &=~BIT3; //我想它现在是安静的
    P2IFG |= BIT7; //触发 P2.7中断
    _DELAY_CYCLES (50); //以防发生传播竞争
    P2IE &=~BIT7; //现在禁用它
    P1OUT |= BIT0; //指示我们已到达此处
    的光 LED }
    否则 IF (P2IFG 和 BIT7) //我保证我没有按下(P2.7)按钮
    {
    P2IFG &=~BIT7; //谢谢,现在就走了
    P1OUT |= BIT1; //指示我们已到达此处
    的光 LED }
    返回;
    }