「天文屋のためのマイコン入門」割り込みを掘り下げる
実際に割り込みプログラムを組んで見ましたが、いかがだったでしょうか。インターバルシャッターのプログラムも、モータードライブのプログラムもタイマー割り込みをベースとしたプログラムになります。
今日は割り込み処理について、深く考察してみみます。
まず、サブルーチンとの比較をしてみます。割り込み処理はサブルーチンと似ています。違いはCALL命令がないことです。サブルーチンはCALL命令でプログラム中に意図的に記述しないと呼ばれませんが、割り込み処理はハードウェアにより自動的に呼ばれます。
サブルーチンはCALL命令により、戻り番地が保存され、RETURN命令により、その戻り番地に復帰します。割り込み処理も同じような機構が必要です。そうでないと、やはり元の場所に復帰できません。実は、割り込み処理も、割り込みが発生するとハードにより、戻り番地が保存されます。しかもこの保存先は、サブルーチンと共通です。
とういうことは、サブルーチンのネスト呼び出しは8段までという制約は、割り込み処理も含まれます。たとえばサブルーチン実行中はネストレベル1とします。ここで別のサブルーチンを呼ぶとネストレベルは2になります。ここで割り込みが発生するとネストレベルは3になります。
サブルーチンも割り込み処理も同じ場所に戻り番地が保存されるなら、割り込み処理もRETURN命令で戻れるはずです。なぜ割り込み処理は専用のRETFIE命令を使うのでしょうか。実は、割り込み処理には独得の決まりがあります。これについてはこれから説明します。
ところで、割り込み処理中に、別の割り込みが発生するでしょうか。たとえばタイマー割り込みでも割り込み処理に時間がかかると、次のオーバーフローが発生して、割り込み処理中にまた割り込みが発生する懸念があります。
また、違う種類の割り込みを同時に許可している場合もあります。
この答えはノーです。割り込み処理中に別の割り込みは発生しません。正確にいうと、発生を禁止しています。
INTCONレジスタのGIEビットを思い出してください。このビットを0にすると、全ての割り込みが禁止されます。実は割込みが発生すると、このビットが自動でクリアされ、割り込みが禁止されます。
GIEビットを0にすることにより割り込みを禁止しているので、割り込み処理の中でGIEビットを1にセットすれば割り込みは発生します。これを多重割り込みといいます。ただ多重割り込みを許可すると、後で説明する資源の競合という面倒な問題が起こるので、普通はGEビットは0のままにして多重割り込み禁止にします。
さて、割り込み処理ではGIEビットが自動で0にクリアされ、割り込みが禁止されますが、このままでは、永久に割り込みが禁止され2回目の割り込みが発生しなくなります。ですから割り込み処理から戻る前にGIEビットを1に戻して再度割り込み許可状態にする必要があります。しかし、RETFIE命令はこの処理を自動でやってくれます。ここがサブルーチンのRETURN命令とちがうところです。
つまり、
RETFIF
||
BSF INTCON,7
RETURN
ということができます。試しに前回のプログラムを上記のように変えてやってみてください。ちゃんと動くはずです。
ここでひとつ注意があります。割り込み処理の中で禁止しているのは実際の割り込みがであって、割り込み要求まで禁止しているわけではありません。どうゆうことかというと、割り込み禁止状態であっても、タイマーがオーバーフローすれば、タイマーオーバーフロービットは1にセットされます。
この場合、割り込み処理から抜けた瞬間、つまりRETFIF命令直後にすぐさま次の割り込みが発生します。だから、割り込み禁止状態であっても、割り込み要求が無視されるわけではありません。 待たされるのです。
もっとも、この待たされている間に、また割り込み要求がでれば、つまり3番目の割り込みは、本当に無視されます。病院の待合室の椅子は一席までということです。
さて、今日は割り込みについてちょっと掘り下げてみましたが、次回さらに検討してみます。割り込みは奥が深いです。いますぐ必要な知識ではありませんが、いつかきっと役立ちます。
| 固定リンク
コメント