割り込み処理

PICCにおける割り込み処理は、PICそのものの割り込み機構の単純さをそのまま反映しており、PICの割り込み処理をアセンブラで記述したことがある方であれば、非常に簡単に記述することが出来ます。また、PICのアセンブラの経験がなくても、単純な仕組みなので、ある程度の使いこなしはすぐに出来るようになると思われます。割り込み処理をプログラムするためには以下に示す処理方法について知る必要があります。

  1. ある事象に関連して割り込みを発生させる方法
  2. 割り込みが発生したときに適切な処理を行う方法

1.に関しては、PICに内蔵されている周辺装置の設定を操作し、ある事象が発生したら割り込みが発生するように、設定します。通常は、プログラムの初期化ルーチンでそのような処理を行います。2.に関しては、割り込みサービスルーチン(ISR)と呼ばれる処理ルーチン(C言語では関数)を用意し、発生した割り込みに対して、適切な対応処理が行えるようにします。

PICでの割り込みの原因となる割り込み要因は、タイマー、入出力ポートの変化、シリアル通信機能の入出力完了などPICに内蔵されている周辺装置と関連して多数あります。近代的なプロセッサでは、割り込み要因ごとにISRを指定できるようになっているものが多いのですが、PICでは、全ての割り込み要因に対して、ただひとつのISRで対応する仕組みとなっています。PICCでのISRの記述は、このPICの基本的な仕組みにそのまま対応し、ISRを1つだけ作成することが出来る様になっています。割り込み要因により、ISRで処理すべき内容は変わりますが、割り込み要因の特定とそれに対応した処理は、この唯一のISRに記述することになります。

PICCでは、ISRは関数として記述しますが、通常の関数と違って、関数名の前にinterruptキーワードを付与します。ISRの関数名は特に規定はありませんので、適当な名前をつけます。interruptキーワードを付与できる関数(したがってISR)は、1つのプログラム中に1つだけ作成することが出来ます。ISRは、他の関数中から明示的に呼ばれるものではないので、引数はなく、また返す値もありません。したがって、関数の型および引数は、voidとなります。(実は、引数も関数型もそれ以外が書けてしまいますが、トラブルの元になるのでやめるべきです。)

ISRの中では、一般的に以下のような処理を記述する必要があります。

  1. 割り込みが起きた際に実行されていたプログラムの実行状態を保存し、ISRの処理後に元に戻せるようにする処理
  2. 割り込み要因(割り込みが発生した理由)の特定と解除
  3. 割り込み要因に対応した処理

1.の実行状態の保存と復帰の処理は、アセンブラでプログラミングする場合には、明示的に記述する必要がありますが、PICCでは、自動的にその処理コードを作成してくれるので、プログラマは全く意識する必要はありません。 したがって、ISRを作成する際には、2,3のみに注力すればよいことになります。

ISRの記述例を以下に示します。

これは、Timer0による割り込みを対象として記述したISRの例です。T0IE,T0IFにより割り込み要因の特定を行った上で、該当の割り込み要因の解除を行い、割り込み要因に対応した処理を記述します。Timer0以外にも、シリアル通信や、I/Oポートの変化などによる割り込みを処理するためには、それぞれの周辺機器でT0IE,T0IFに相当するフラグを利用して割り込み要因の特定と解除を行った上で、対応する処理を行う記述を追加していくことになります。

このISRが呼ばれるためには、割り込みを発生させるための初期化処理が必要になります。Timer0での割り込みの有効化処理の例を以下に示します。