C MSP430中断开销

C MSP430中断开销,c,interrupt,msp430,isr,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 vol

我正在为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保证在跳转后一条指令可以再次中断。如果load不是跳转后的第一条指令,那么在读取P4IFG寄存器之前,我可能会再次中断,并且它的值可能会更改为不同的值,这将是一个问题

对于我来说,期望编译器在跳转之后立即放置我的加载指令,从而确保在另一个中断可以更改它之前,我总是能够获得该寄存器的副本,这合理吗


谢谢您

无论您使用的是什么MSP430芯片,《用户指南》都会回答您的所有问题

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

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

P4IFG寄存器中的位不是由代码设置的,因此中断是否启用并不重要。只要配置的信号边缘发生在一个管脚上(可以随时发生),就会设置新的位,但以前设置的位不会被清除

在中断处理程序中,您应该读取中断标志并清除已读取的位。(如果在中断处理程序执行时发生新事件,则在返回后将得到一个新的中断。)

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

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

C标准不要求对自动变量使用堆栈。你不应该假设它实际上是。你想完成什么?你的问题不清楚。阅读和理解《用户指南》始终是一个良好的开端。您不会跳入ISR。执行路径进入ISR以响应触发相关中断的某个事件。ISR的链接(在大多数情况下)与函数调用的链接截然不同。ISR中的第一条指令可以是禁用中断。然后,让ISR执行任何您想要视为“关键”代码的操作,然后重新启用中断
__interrupt void SW_PRESSED_ISR(void)
{
    switch (P4IV) {
    case P4IV_P4IFG0:
        // event at bit 0
        break;
    case P4IV_P4IFG1:
        // event at bit 1
        break;
    ...
    }
}