「割り込み」の基礎

【割り込みとは?】

割り込みとは、一体何なのでしょうか? ことばから想像できる
のは、とにかく列に割り込むとか、混んでいる中に割り込んで入る
とかいう情景が想像されます。
プログラムの世界での割り込みも全く同じ意味で使われています。
つまり、あるプログラムを実行中に、他のプログラムを実行させ
たい。これが割り込みという概念が生まれたきっかけです。

ではどんな時にそんな割り込みが必要となるのでしょうか?

・例えば、とても長い処理時間のかかる演算をしているときに
 何かキーを押して演算の仕方を修正したり、一旦止めたり
 したい。
・プリンタなどに印刷している間に、キーボードから次のデータ
 を入力したい。
・他の機器と通信でデータを受信しながら、前のデータのグラフ
 表示をしたい。
・モータを制御しながら、他の機器からのデータを受信したい。
・一定時間ごとにセンサをチェックしながら、バルブなどの
 制御をしたい。

以上のような例でわかるように、何かしながら別のことを同時
にしたい時に、割り込みが有効に活用されます。



【割り込み処理の流れ】

割り込みによって、プログラムがどのように実行されるかを図で
表現すると下図のような流れで表すことが出来ます。




つまり、Aの処理中に割り込み1が入ったら、それに対応するBと
いう処理を優先的に実行し、Bの処理が完了したら、Aの続きの
処理に戻るという流れで実行します。

さらにAの処理中に割り込み2が発生したら、とりあえず対応する
割込み処理Cを実行して、その中でDの処理を開始することを記憶
してAに戻り、Aの処理が完了したら、Dの処理を開始するという流
れにしたりします。

このような時に課題となるのは、Aに戻るとき前の状態と同じ状態
にして戻らなければ正常に継続処理が出来ないということです。

コンピュータ内部で状態とは何で、それをもとに戻すにはどうする
のでしょうか?

まず、コンピュータの状態はすべてレジスタに記憶されています。
そこでコンピュータ内部の状態を記憶しておくには、全てのレジ
スタの現在値を記憶し、保存しておけば良いことになります。

しかし、PICでは全てのレジスタを保存することは、読み出すことが
出来ないレジスタもあり、不可能です。
しかし、割り込み処理の作り方を下記の規則を守って作れば、
全てのレジスタを保存しなくても、数個のレジスタだけを保存すれば
正常に戻るようにすることが出来ます。

ではこの規則とは一体どんなものなのでしょうか?


【割り込み処理の制限規則】

割り込みから正常に戻るようにし、かつ割り込まれた処理を正常
に継続できる様にするためには、下記のことを守る必要があります。

(1)演算レジスタの状態を保存し復帰させる。
 PICでは、Wレジスタ、STATUSレジスタ、PCHLレジスタ
 メモリに保存する。
 つまり、割り込みが入った時点で即、上記レジスタをメモリ
 に保存しておき、割り込み処理から戻る時に、それらをメモリ
 からレジスタに復帰させる。
 また割り込み処理の中で上記3個のレジスタ以外を直接変更する
 時には、変更されることを他の処理が意識しており、変更され
 ても問題無いようになっていること。
 例えば、TRISレジスタの様な、入出力を変更するレジスタを
 変更されても、他の処理は問題無いようになっていること。
 
(2)割り込み処理の中でさらに割り込みを受け付ける(これを
 多重割り込みという)ことは禁止する。

(3)割り込み処理の中で、データメモリの内容(つまり変数)を
 変更する時は、その変数を使う処理は、すべて変更されること
 を意識していて、いつ変更されても問題無いように作られて
 いること。
 (普通に使っていれば自然にそうなっているはずです。)

(4)処理時間を意識しておき、いつ割り込みが入ってそちらに
 時間を割かれても問題無いようにしておくこと。
 どうしても高速にしなければならない処理や、正確な処理時間
 を必要とする処理の中では、割り込みは禁止しておく必要があ
 ります。
 また、割り込み処理自身も、余り長時間の処理時間がかから
 ないように作る必要があります。

(5)これは当然のことですが、サブルーチンへのCALL命令は必ず
 RETURNで戻っておくようにすることが必要です。
 特にPICの場合にはスタックポインターが読み書きできないので
 大きな問題にはならないのですが、スタックを正常に使うよう
 にするためには、CALLとRETURNは常にペアで使われている
 ことが必要です。そうしないと正常に戻ることが出来ないばかり
 でなくスタックを使い切ってしまい、スタックメモリオーバーフロー
 となって動作不能という状態になってしまいます。


【割り込みの要因】

では実際に割り込みの要因として用意されているものには
どんな物があるのでしょうか?

(1)入力の変化
 入出力ピンに入力されている信号が変化したとき割り込む。
 これは、例えばスイッチを押したとき、モータの回転を
 逆にするとか、いうような時のスイッチの接点の入力に
 使います。
 また連続パルスのカウントをするような場合にも使うこと
 が出来ますが、余り高速なパルスに使うことはできません。

(2)タイマーの周期毎の割り込み

 PICを含め大抵のマイコンにはタイマーが内蔵されています。
 このタイマーのカウントアップ終了により割り込みをかける
 ことで、一定の時間後、あるいは、定周期で割り込みを得る
 ことが出来ます。
 これは例えば、ある時間の遅れを持たせたいときなどに使い
 ます。

(3)A/D変換の終了

 内蔵A/D変換の変換終了により割り込むことで、一定時間の
 必要なA/D変換の間を他の処理に時間を回すことができるので
 時間を有効活用することが出来ます。


【割り込みが入る様にするには?】

まず、割り込み自身が受け付けられるようにするにはどうすれば
良いのでしょうか?
設定なり実行が必要な項目を列挙すると下記のようになります。

(1)4番地に割り込み処理プログラムへのジャンプ命令があること

(2)INTCONレジスタのGIEビットがONとなっており、割り込み全体
 が許可されていること。

(3)INTCONレジスタにある、割り込み要因毎の許可ビットが
 ONとなっていること。

(4)ハードウェアの接続がきちんとなされていること(当たり前)


【割込みの時の動作詳細】
  PICで割込みが発生した時の動作は下記の様な順序になります。

   ・割込みが発生すると以後の別の割込みを禁止するため
    INTCONレジスタのGIEビットをOFF
           ↓
   ・実行中の命令の次の命令のアドレスをスタックに保存
    (他のレジスタは保存されない)
           ↓
   ・強制的にプログラムカウンタに0004Hがセットされ
    4番地にジャンプする
           ↓
   ・割込み処理プログラムを開始。必要であればその直前
    のレジスタを保存します
           ↓
   ・割込みの要因を調べるため、INTCONレジスタの割込みフラグ
    を調べ、フラグが「1」の要因の処理を実行します。
    そしてそのフラグをBCF命令で「0クリア」しておきます。
           ↓
   ・複数の割込みフラグが「1」になっていれば全ての関連
    割込み処理を実行します。
           ↓
   ・割込み処理終了。直前に割込まれた時のレジスタを復帰
    させる。最後にRETFIE命令を実行する。
           ↓
   ・RETFIE命令の実行により、スタックに保存されていた割込み
    時のアドレスにジャンプし復帰する。同時に次の割込みを
    許可するためINTCONレジスタのGIEビットが再セットされる。


      目次へ