MSP430中断开销

时间:2016-02-15 03:26:15

标签: c interrupt msp430 isr

我正在为MSP430编写ISR。它读取易失性PxIFG寄存器并将其复制到第一条指令的堆栈变量中。 ISR跳转是否有任何开销,或者我可以预期

__interrupt void SW_PRESSED_ISR(void)
{
  unsigned short currnet_ifg = P4IFG;
...
}

编译成类似

的东西
... Register saving instructions
JSR ...       // jump into ISR
LD  P4IFG ... // load volatile register P4IFG value
...

我知道如果ISR跳转后的第一条指令是寄存器加载,我的ISR将按预期工作。我的理解是MSP430在跳转之后保证一条指令再次被中断。如果负载不是跳转后的第一条指令,那么问题是我可能会在读取P4IFG寄存器之前再次中断,并且它的值可能会更改为不同的值,这将是一个问题。

我期望编译器在跳转后立即放置我的加载指令是否合理,从而确保在另一个中断可以改变之前我总是得到该寄存器的副本?

谢谢

1 个答案:

答案 0 :(得分:1)

您在使用的任何MSP430芯片的用户指南中都会回答您的所有问题。

您的代码不会调用中断;当外部事件触发它们时,CPU会自动执行它们。 将PC和SR寄存器保存到堆栈,清零GIE位,以及读取和跳转到中断向量,需要六个周期。但是,如果禁止中断,则中断可以延迟任意时间。

在中断处理程序中,中断被禁用(除非您明确地重新启用它们)。

P4IFG寄存器中的位不是由您的代码设置的,因此无论是否启用中断都无关紧要。只要配置的信号边沿发生在其中一个引脚上(可能发生在任何时间),新位就会置1,但先前设置的位不会被清除。

在你的中断处理程序中,你应该读取中断标志并清除你读过的那些位。 (如果在执行中断处理程序时发生新事件,则在返回后会出现新的中断。)

__interrupt void SW_PRESSED_ISR(void)
{
    uint16_t ifg = P4IFG;
    P4IFG &= ~ifg;

    if (ifg & ...)
        ...
}

最好使用中断向量寄存器,该寄存器以原子方式返回端口的一个中断,并重置相应的标志位:

__interrupt void SW_PRESSED_ISR(void)
{
    switch (P4IV) {
    case P4IV_P4IFG0:
        // event at bit 0
        break;
    case P4IV_P4IFG1:
        // event at bit 1
        break;
    ...
    }
}