最初的问题
我对微控制器中的中断处理有一个一般性的问题。我正在使用MSP430,但我认为这个问题可能会扩展到其他uC。我想知道是否经常在代码中启用/禁用中断是一种好习惯。我的意思是,如果我有一部分对中断不敏感的代码(或者更糟糕的是,出于某种原因,一定不能监听中断),那么这样做会更好:
- 在关键部分之前禁用中断,然后在其后重新启用它们。
- 在相应的ISR中放置一个标志,并(而不是禁用该中断),在关键部分之前将标志设置为false,然后在紧要部分之前将其重置为true。防止执行ISR的代码。
- 两者都不提供,因此欢迎提出建议!
更新:中断和状态图
我将提供具体情况。让我们假设我们要实现一个状态图,该状态图由4个块组成:
- 过渡/效果。
- 退出条件。
- 进入活动。
- 做活动。
这就是教授在大学里教给我们的。遵循此方案可能不是最好的方法:
while(true) {
/* Transitions/Effects */
//----------------------------------------------------------------------
next_state = current_state;
switch (current_state)
{
case STATE_A:
if(EVENT1) {next_state = STATE_C}
if(d == THRESHOLD) {next_state = STATE_D; a++}
break;
case STATE_B:
// transitions and effects
break;
(...)
}
/* Exit activity -> only performed if I leave the state for a new one */
//----------------------------------------------------------------------
if (next_state != current_state)
{
switch(current_state)
{
case STATE_A:
// Exit activity of STATE_A
break;
case STATE_B:
// Exit activity of STATE_B
break;
(...)
}
}
/* Entry activity -> only performed the 1st time I enter a state */
//----------------------------------------------------------------------
if (next_state != current_state)
{
switch(next_state)
{
case STATE_A:
// Entry activity of STATE_A
break;
case STATE_B:
// Entry activity of STATE_B
break;
(...)
}
}
current_state = next_state;
/* Do activity */
//----------------------------------------------------------------------
switch (current_state)
{
case STATE_A:
// Do activity of STATE_A
break;
case STATE_B:
// Do activity of STATE_B
break;
(...)
}
}
让我们还假设,例如STATE_A
,我想对来自一组按钮(带有反推系统等)的中断敏感。当有人按下这些按钮之一时,将产生一个中断,并将与输入端口相关的标志复制到变量中buttonPressed
。如果通过某种方式(看门狗定时器,定时器,计数器等)将防抖动设置为200 ms,我们确信buttonPressed
在200 ms之前不能用新值进行更新。当然,这就是我要问你(和我自己:)
我是否需要在DO活动中启用中断STATE_A
并在离开前禁用?
/* Do activity */
//-------------------------------------
switch (current_state)
{
case STATE_A:
// Do activity of STATE_A
Enable_ButtonsInterrupt(); // and clear flags before it
// Do fancy stuff and ...
// ... wait until a button is pressed (e.g. LPM3 of the MSP430)
// Here I have my buttonPressed flag ready!
Disable_ButtonsInterrupt();
break;
case STATE_B:
// Do activity of STATE_B
break;
(...)
}
通过某种方式,我可以确定下一次在下一次迭代中执行块1(过渡/效果)时,我确定沿过渡检查的条件不是来自随后的中断,该中断已覆盖了buttonPressed
该I 的先前值需要(尽管由于必须经过250毫秒,所以不可能发生这种情况)。