通过中断或类似方式异步退出循环(MSP430 / C)

时间:2016-01-19 22:48:15

标签: c loops exit msp430 isr

我遇到了一个我很难过的问题,因为我能想到的每个解决方案都存在一个问题,导致它无法完全发挥作用。我正在研究MSP430FF529上的游戏,当第一次启动时,使用循环和循环延迟无限地将两个图像绘制到屏幕上。我想拥有它,以便当用户按下开始按钮(端口上的一个简单的高边触发器)时,程序立即停止绘制这些屏幕,无论进程的哪个部分进入,并开始执行其余的运行游戏的代码。

我可以把把图像放在屏幕上的函数放在do while循环中但是它不会是异步的,因为当前正在绘制的图像必须在它移动之前完成。

我会使用break命令,但我认为这不适用于ISR,只有直接在循环中才有效。

我可以将整个程序的其余部分放在我用于启动按钮按下的ISR中,这样屏幕绘图基本上永远不会返回,但那真的很混乱,编码很差,以后会引起很多问题。 / p>

基本上,我想做到这一点,当按下按钮时,程序将立即跳转到实际游戏的程序部分,忘记在屏幕上绘制这些图像。在执行例程中的代码之后,是否有可能以某种方式使ISR无法返回当前正在发生的情况?基本上,一旦程序开始向前移动(按下开始按钮),我不想回到绘制图像的功能,除非我再次明确地调用它。

我唯一能想到的是goto命令,我觉得在这个特定的例子中实际上并不会太糟糕,尽管我想避免使用它,因为它害怕因为它是一个糟糕的解决方案而成为习惯在多数情况下。然而,这可能甚至不起作用,因为我觉得在ISR中使用goto会使堆栈陷入困境。

有什么想法吗?任何建议都表示赞赏。

2 个答案:

答案 0 :(得分:1)

你想要的基本上是“上下文切换”。您应该修改程序计数器指针和堆栈指针,当您从ISR返回时将返回该指针,然后执行正常的ISR返回,以便清除中断屏蔽,恢复堆栈等。如您对问题的评论中所述,这可能需要一些手动汇编代码。

我不熟悉MSP430,但在其他架构上,这是在内核堆栈或中断上下文堆栈中保存的寄存器结构(或者可能只是某些微控制器上的“堆栈”),或者它可能是在一些特殊的寄存器中,它在跳转到ISR时由CPU自动保存。所以你必须改变它们所在的寄存器指针。

答案 1 :(得分:0)

如果您将需求从“立即”放宽到“如此之快以至于用户没有注意到”,您可以将if (button_pressed)放入图像绘制例程中的某个循环中。

如果您确实想立即中止图像绘制,可以通过重置MCU(例如,通过向WDT写入错误的密码)来完成。在应用程序初始化代码中,检查重置的原因之一是否是您自己的软件:

bool start_button = false;
for (;;) {
    int cause = SYSRSTIV;
    if (cause == SYSRSTIV_WDTKEY)
        start_button = true;
    if (cause == SYSRSTIV_NONE)
        break;
    // you might handle debugging of other reset causes here ...
}
if (!start_button)
    draw_images();
else
    actual_game();

(这假设您的代码从不会意外地写入错误的WDT密码,但即使发生这种情况,您也只是跳过介绍图像。)