2016-01-19 27 views
0

我遇到了一個問題,我寧願因此而陷入困境,因爲我能想到的每個解決方案都有一個問題,使其無法正常工作。我正在開發一款MSP430FF529上的遊戲,當第一次啓動時,兩個圖像通過循環和循環延遲無限次地吸引到屏幕上。我想要這樣做,以便當用戶按下開始按鈕(一個簡單的高邊沿觸發器)時,程序立即停止繪製這些畫面,無論該進程的哪一部分進入,並開始執行其餘部分運行遊戲的代碼。通過interupt或類似的異步退出循環(MSP430/C)

我可以把屏幕上的圖像放在一個do while循環中,但它不會是異步的,因爲當前的圖像在移動之前必須完成。

我會使用break命令,但我認爲這不適用於ISR並且只有當它直接在循環中。

我可以把程序的整個其餘部分放在ISR中,我使用開始按鈕按下,這樣屏幕繪圖本質上永遠不會返回,但那真的是混亂,編碼不好,並且會在以後引發很多問題。

本質上,我想這樣做,當按鈕被按下時,程序將立即跳轉到實際遊戲的程序部分,並忘記在屏幕上繪製這些圖像。在執行例程中的代碼之後,是否有可能以某種方式使ISR不能返回到當前發生的狀態?基本上,一旦程序開始向前移動(按下開始按鈕),我不想回到繪製圖像的功能,除非我明確地再次調用它。

我能想到的唯一的東西就是goto命令,我覺得在這個特定的實例中實際上並不算太壞,儘管我想避免使用它,因爲它害怕它變成一個習慣,因爲它是一個窮人解決方案在大多數情況但是,這可能不起作用,因爲我有一種感覺,在ISR中使用goto會使堆棧變得非常糟糕。

任何想法?任何建議表示讚賞。

+0

你可以使用某種RTOS。將遊戲線程設置爲比渲染線程更高的優先級,但將其懸掛在信號量上。在中斷處理程序中設置信號量並將處理程序退出到調度程序。一旦中斷結束,就會切換到遊戲。 –

+0

這個問題太廣泛了,沒有一個好的答案。當然,你可以使用匯編程序跳到你想要的地方,但這超出了C語言。 C甚至沒有一個硬件中斷的概念,用於自由停頓的環境。或者,您可以在主代碼中通過您測試的中斷處理程序設置一個標誌。注意:機械按鈕會彈跳。您必須採取措施來防止單次按鍵檢測多個脈衝。 – Olaf

+0

'goto'只能在單個函數中使用。一般來說,在代碼中瘋狂跳躍是一種糟糕的風格。請放心,如果不是瞬間的話,它最終會在以後造成麻煩。 – Olaf

回答

1

你想要什麼基本上是一個「上下文切換」。你應該修改程序計數器指針和堆棧指針,當你從ISR返回時它們將被恢復,然後執行正常的ISR返回,以便中斷屏蔽被清除,堆棧被恢復等等。正如在你的問題的註釋中指出的那樣,這可能需要一些手動彙編代碼。

我對MSP430並不熟悉,但在其他體系結構中,這是在內核堆棧或中斷上下文堆棧上保存的寄存器結構中(或者也許只是某些微控制器上的「堆棧」),或者它可能在一些特殊的寄存器中,當它跳轉到你的ISR時它會被CPU自動保存。所以你必須改變這些寄存器指針。

+0

我有一種感覺,它可能需要一些組裝。我會仔細看看的。感謝您的意見。 – oblivioncth

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,但即使出現這種情況,你是隻跳過介紹圖像。)

+0

哇,第二個選項是一個有趣的解決方案,我可以給一個鏡頭。我目前正在嘗試通過在介紹繪圖的每個部分中使用一對條件語句來嘗試您所說的第一個選項,但遇到中斷問題。一旦main完成,我就沒有任何中斷髮生,我運行「_BIS_SR(LPM4_bits + GIE);」以啓用低功耗模式和中斷,但由於我需要這個中斷髮生在main完成之前和低功耗模式被激活之前,我只是試着「_BIS_SR(GIE);」以前。 (查看下一條評論) – oblivioncth

+0

雖然這樣做程序仍然在調試器中運行,但屏幕上沒有顯示任何內容,因此看起來它會以某種方式混淆PORT I/O。不知道爲什麼。 – oblivioncth