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.

[参考译文] MSP430F5529:电路板冻结在_bis_SR_register (GIE)上

Guru**** 2589275 points
Other Parts Discussed in Thread: MSP-EXP430F5529LP

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/627591/msp430f5529-board-freezes-on-__bis_sr_register-gie

器件型号:MSP430F5529
主题中讨论的其他器件:MSP-EXP430F5529LP

我正在尝试使用按钮 S2 (端口1.1)的中断来写入基本中断代码、以切换 LED1 (端口 P1.0)。

我已经轮询了寄存器按钮按压操作、但我的中断代码似乎不起作用。 具体而言、使用调试器时、代码似乎没有传递_bis_SR_register (GIE)语句。

是否有人知道为什么此代码不能使用中断来切换 LED?

我的代码是:

#include 


#define RED_LED BIT0
#define Button BIT1

int main (){
P1DIR |= RED_LED;
P1OUT &=~RED_LED;

//设置为输入引脚
P1DIR &=~按钮;

//设置上拉电阻器
P1REN |=按钮;
P1OUT |=按钮;

//中断边沿选择
P1IES &=~按钮;

//清除中断标志
P1IFG &=~按钮;

//设置为中断引脚
P1IE |=按钮;

_bis_SR_register (GIE);

while (1){

}
}

#pragma vector=Port1_vector
__interrupt void port1_ISR (void){
P1OUT ^= RED_LED;
P1IFG &=~按钮;
} 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这可能是调试器引入的幻象:while ()循环只是一条指令,因此 PC 始终指向该指令。

    您可以尝试在循环中放入一些内容(__NOP()或类似无害的内容),看看它是否看起来不同。

    我看不到明显的杂散中断原因。

    未经请求:您可能会观察到一些开关抖动。 如果抖动次数达到偶数次(50:50概率)、则 LED 不会(明显)发生变化。 继续尝试、或谷歌"坏账"。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的快速响应。

    在 while 循环中放置"_nop()"调用确实会修复调试器似乎从未传递_bis_sr_register (GIE)调用。 它现在可以正确地单步执行 while 循环。

    但是、中断似乎仍然没有被调用。 我稍微简化了代码、以便 LED 从低电平位置开始、如果曾经调用过中断、它将变为高电平。 (我认为这应该可以消除调用 ISR 的可能性、但由于开关抖动、我没有意识到)。

    不过、LED 永远不会切换到开启状态、这似乎意味着从未调用过 ISR。

    我的代码是:

    #include 
    
    
    #define RED_LED BIT0
    #define Button BIT1
    
    int main (){
    P1DIR |= RED_LED;
    P1OUT &=~RED_LED;
    
    //设置为输入引脚
    P1DIR &=~按钮;
    
    //设置上拉电阻器
    P1REN |=按钮;
    P1OUT |=按钮;
    
    //中断边沿选择
    P1IES &=~按钮;
    
    //清除中断标志
    P1IFG &=~按钮;
    
    //设置为中断引脚
    P1IE |=按钮;
    
    //_bis_SR_register (GIE);
    _enable_interrupt ();
    
    while (1){
    __nop();
    }
    }
    
    #pragma vector=Port1_vector
    __interrupt void port1_ISR (void){
    P1OUT |= RED_LED;
    P1IFG &=~按钮;
    } 

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

    提供救援的示例代码(从产品页面链接)。 这些东西很容易忘记。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我将这个代码放置为主函数的第一行、但是很遗憾、禁用看门狗也没有改变任何东西。

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

    嗯。 我添加了这一行内容、按下 P1.1按钮打开 LED (修订版1.5 Launchpad)。

    1) 1)您是否尝试在 ISR 中设置断点?
    2) 2)是否已安装 LED 旁边的跳线?
    3) 1)一个好奇心:我必须明确地补充:
    #define _nop() do{asm volatile (" nop");}while (0)
    来构建它。 (intrinsics.h 具有_nop(),带有一个底栏。) 很显然你是从其他地方得到的(?)。 也许可以尝试添加该行或将函数名更改为_nop()。

    [编辑:在 nop 指令中添加了一个空白;结果不变。]

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

    我尝试在我调用__nop()的那一行以及 ISR 的第一行上放置一个断点。
    当我在 GDB 中调用 NEXT 时、我单击 while 循环中的断点、但我从未遇到该断点
    中断例程中的中断、即使我单击按钮也是如此。

    安装了 LED 旁边的跳线(位于 P4.7上的 LED 和 P1.0上的 LED 之间)。

    我尝试将__nop 更改为_nop,并使用您对__nop()的定义,但都没有更改任何内容。

    我的板是 MSP-EXP430F5529LP、修订版1.6
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    今天、我借用了 Rev 1.6 Launchpad、其行为与 Rev 1.5相同、即按预期运行。

    您是否始终使用"下一个"、还是也允许它自由运行? 我模糊地记得,GDB 的"下一个"(以及"步骤")命令与中断有某种模糊的关系----我记得必须在下一个语句中设置断点,"继续"。

    我很遗憾我没有提出任何建议。 您的代码可以正常工作、并且您和我正在做的事情之间存在一些不同的(我不想)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    感谢您的所有帮助。

    我发现我的代码有问题。

    它似乎定义了我需要使用__attribute ((interrupt (Port1_vector)))而不是#pragma vector=Port1_vector __interrupt 的中断

    我的最终工作代码是(注意:这不包括按钮去抖):

    #include 
    
    #define RED_LED BIT0
    #define Button BIT1
    
    int main (){
    WDTCTL = WDTPW + WDTHOLD;
    
    //将 LED1、P1.0设置为输出
    P1DIR |= RED_LED;
    
    //将 LED1、P1.1设置为低电平
    P1OUT &=~RED_LED;
    
    //设置为输入引脚
    P1DIR &=~按钮;
    
    //设置上拉电阻器
    P1REN |=按钮;
    P1OUT |=按钮;
    
    //中断边沿选择
    P1IES &=~按钮;
    
    //清除中断标志
    P1IFG &=~按钮;
    
    //设置为中断引脚
    P1IE |=按钮;
    
    //进入低功耗模式0并启用可屏蔽中断
    _bis_SR_register (LPM0_bits + GIE);
    }
    
    void __attribute__((interrupt (Port1_vector))) port1_ISR (void){
    
    //开关 LED1
    P1OUT ^= RED_LED;
    
    //清除端口1中断标志
    P1IFG &=~按钮;
    }