0

私が考えることができるすべてのソリューションには、完全に機能しない問題があるため、かなり困惑している問題に遭遇しました。私は MSP430FF529 でゲームに取り組んでおり、最初に電源を入れたときに、ループとサイクル遅延を使用して 2 つの画像が画面に無限に描画されます。ユーザーがスタートボタン(ポートの単純なハイエッジトリガー)を押すと、プロセスのどの部分に関係なく、プログラムがそれらの画面の描画をすぐに停止し、残りの実行を開始するようにしたいと思いますゲームを実行するコードの。

画像を画面に表示する関数を do while ループに入れることもできますが、描画中の現在の画像が移動する前に終了する必要があるため、非同期にはなりません。

私は break コマンドを使用しますが、それが ISR では機能せず、直接ループ内にある場合にのみ機能すると思います。

残りのプログラム全体をスタート ボタンを押すために使用する ISR に入れることで、基本的に画面描画が元に戻らないようにすることもできますが、それは本当に混乱し、コーディングが不十分であり、後で多くの問題を引き起こすことになります。

本質的には、ボタンが押されると、プログラムが実際のゲームであるプログラムの部分にすぐにジャンプし、それらの画像を画面に描画することを忘れるようにしたいと考えています。ルーチン内のコードが実行された後、現在起こっていたことに戻らない ISR を持つことは可能ですか? 基本的に、プログラムが前進し始めると (開始ボタンが押されます)、明示的に再度呼び出さない限り、画像を描画する関数に戻りたくありません。

私が考えることができる唯一のことは goto コマンドです。この特定の例では、実際にはそれほど悪くはないと思いますが、ほとんどの場合、貧弱な解決策であるため、習慣になることを恐れて使用を避けたいと思います. ただし、ISR で goto を使用すると実際にスタックが台無しになると感じているため、それも機能しない可能性があります。

何か案は?任意の提案をいただければ幸いです。

4

2 に答える 2

1

必要なのは基本的に「コンテキストスイッチ」です。ISRから戻ったときに復元されるプログラムカウンターポインターとスタックポインターを変更し、通常のISRリターンを実行して、割り込みマスクがクリアされ、スタックが復元されるなどする必要があります。質問へのコメントに記載されているように、これには、手動のアセンブリ コードが必要になる可能性があります。

私は MSP430 に精通していませんが、他のアーキテクチャでは、これはカーネル スタックまたは割り込みコンテキスト スタック (または、一部のマイクロコントローラーでは単に「スタック」) に保存されたレジスタの構造であるか、またはいくつかの特別な場所にある可能性があります。登録し、ISR にジャンプするときに CPU によって自動的に保存されます。したがって、これらのレジスタ ポインタを変更する必要があります。

于 2016-01-19T23:19:34.093 に答える
0

要件を「すぐに」から「ユーザーが気付かないほど速く」に緩和する場合はif (button_pressed)、画像描画ルーチンのループに入れることができます。


画像描画をすぐに中止したい場合は、MCU をリセットすることで中止できます (たとえば、WDT に間違ったパスワードを書き込むなど)。アプリケーションの初期化コードで、リセットの原因の 1 つが独自のソフトウェアにあるかどうかを確認します。

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 パスワードを書き込むことは決してないことを前提としていますが、たとえそれが起こったとしても、イントロ イメージをスキップしているだけです。)

于 2016-01-20T07:59:23.750 に答える