【複数割込み】
PICの内蔵モジュールの大部分が動作完了通知のための割込み要因を
持っていますので、当然複数の割込みを使うことがあります。
CCSのC言語でこの複数割込みの場合はどう記述すれば良いのでしょうか?
まず、PICの割込み要因の全体を見てみましょう。ミッドレンジの代表である
PIC16F87xシリーズの場合の割込み要因と優先順位の関係は下図のように
なっています。
この図から判るように、タイマ0(T0IF)、外部割込み(INTE)、状態変化割込み(RBIF)
の3つが基本の割込みになっていてそれぞれの許可/禁止とグローバル許可禁止
(GIE)で制御されています。
残りの割込み要因はそれぞれの許可・禁止に加えて周辺一括の許可禁止(PEIE)
の制御が必要になっています。
しかしCCSのコンパイラではこれらの許可禁止を一括面倒を見てくれますので
プログラムを記述する上では気にする必要はありません。
【記述方法】
実際のコーディング方法は、通常の割込み処理の記述方法と全く同じで、
複数の割込み処理関数を、#INT_xxx プリプロセッサを組にして記述すれば
良いようになっています。
そしてenable_interrupts(xxx); で割込みを許可すれば、PEIEビットの処理も
自動的に追加されますので気にしなくても良いようになっています。
つまり 下記のような形式にすればよいことになります。
;***** xxxの割込み処理関数
#INT_xxx //xxxの割込み処理の開始指定
xxx_isr(){ //xxxの割込み処理関数
-------
}
(この間に他の関数があっても構わない)
;**** yyyの割込み処理関数
#INT_yyy
yyy_isr() {
-------
}
main() { //メイン関数
-----
-----
enable_interrupts(xxx); //xxxの割り込み許可
enable_interrupts(yyy); //yyyの割込み許可
-----
enable_interrupts(GLOBAL); //GLOBAL割り込み許可
-----
-----
}
【実際の例】
複数割込み処理記述の実例です。
例題は2桁のセグメント発光ダイオードに、00から99までの数値を1秒間隔で
カウントアップしながら表示するというものです。
この例ではタイマ0とタイマ1の2つの割り込みを受け付け、それぞれの処理を
しています。
タイマ0の割込み処理では、2桁のセグメント発光ダイオードのダイナミック点灯
制御を行っていて、割込み毎に桁を切り替えては数値の点灯出力をしています。
タイマ0の周期はメインのところでプリスケーラを64でフルカウントで実行して
いますから、割り込みは約64×256×0.2μsec=3.3msec 周期で入る
ことになり、この時間が1桁の点灯時間ということになります。
タイマ1の割込みは約100msec周期で入るようにset_timer1(0x0BDC);と設定
しています。
そしてこの割込みの回数をカウントし、10回目毎に2桁の数値numberを+1し、
100になったら00に戻すという処理をしています。
ここで設定した数値が、タイマ0で表示出力できるようにnumberをグローバル
変数としています。
下記が初期設定と割り込み処理関数部分です。
下記はメイン関数部分ですが、ここでは初期化処理でタイマ0とタイマ1の
設定とスタートをしてから割り込みを許可し、メインループ内では何もせず
ただ割り込みを待っているだけです。