(6)割り込みの記述方法


MPLAB XCコンパイラで割り込み処理を記述する方法について説明します。
XC8のCコンパイラで割り込みを扱うときには次の2つの作業が必要です。
 −割り込みの許可
 −割り込み処理関数の作成


A) 割り込みの許可方法
  割り込みの許可には、3つの設定が必要です。
  @ 割り込みを使う周辺モジュールの割り込み許可
    これには周辺モジュールごとに用意されている「xxIEビット」のセット
    xxは周辺モジュールごとに決められている略号です。
    またこれらのビットはIRExレジスタに集められています。
  A 周辺一括割り込みの許可
    INTCONレジスタ内の「PEIEビット」のセット
      INTCONbits.PEIE = 1;
  B グローバル割り込みの許可
    INTCONレジスタ内の「GIEビット」のセット
      INTCONbits.GIE = 1;

 この作業が必要なのは割り込み処理回路が下図のようになっているためで
 各段のAND回路を有効化してやる必要があるためです。この3つの許可により
 最終段のAND出力がHighとなると、プログラム実行が強制的に4番地にジャンプ
 します。(PIC16の場合)
 つまりPIC16の場合には割り込みラインが1本しかないため、すべての割り込みが
 同じベクタ(4番地)にジャンプすることになります。




B) 関連レジスタ
 個々の周辺モジュールの割り込み制御用レジスタはPIC16の場合下図のように
 なっています。割り込み許可ビットはPIExレジスタに、割り込みフラグビットは
 PIRxレジスタに集められています。
 また周辺モジュールごとの略号も下記のように決まっています。この中でnは
 モジュールが複数実装されているもので1、2となります。




C) 割り込み処理関数の作成
  割り込み処理関数を作るには、関数の修飾子に「interrupt」を付加し、
  下記のフォーマットで関数を作ります。yyyyは関数名で任意の名前にできます。
  これでレジスタの退避、復旧ルーチンや、ジャンプテーブルは自動的にコンパイラが
  生成しますので、簡単な記述で割り込み処理ができます。
 void interrupt yyyy(void)
 {
    (割り込み関連処理)
    xxIF = 0;         //割り込みフラグクリア
 }
  この割り込み処理関数は、システムで一つしか作成できません。つまり割り込みベクタ
  が一つしかないためです。
  このため、一つの割り込み処理関数の中で、割り込みを区別する必要があります。
  これは次のような記述で行います。つまり割り込みフラグビットをチェックして行います。
  割り込みの優先順位はこのチェックする順番で決まることになります。
  elseifを使うと1回の割り込みで一つの処理しかしませんが、ここをifに変えると1回の
  割り込みで複数の割り込みを一緒に処理することができます。
 void interrupt ISR(void)
 {
   if(PIR1bits.TMR2IF == 1)     // タイマ2の割り込みの場合
   {
     (タイマ2の割り込み処理)
       ----
     PIR1bits.TMR2IF == 0;    // タイマ2割り込みフラグクリア
   }
   elseif(PIR3bits.TMR4IF == 1)  // タイマ4の割り込みの場合
   {
     (タイマ4の割り込み処理)
       ----
     PIR3bits.TMR4IF == 0;    // タイマ4割り込みフラグクリア
   }
 }


D) 実際の例
  PIC16F1ファミリでタイマ2とタイマ4を使った割り込み処理の実際の例です。
  メインの初期化部で割り込みを許可しています。
  割り込み処理ではLEDのポートに反転出力をしているだけです。