割込みの使い方


1.割込みとは?

  プログラムで使う「割込み」とはその名の通り通常のプログラムの
  実行中に割込んで別の処理をさせる時に使います。
  目的は、通常は繰り返しで何か実行していて、ある事象が発生したら
  直ぐその処理をさせたいというような時や、タイマの様な常に一定の
  タイミングを作りたい時に使います。

 (1)PICの割込み要因の種類
  PICで使える割込みには下記の4種類があります。
   ①ポートBのRB0/INTピンの入力による外部割込み
   ②ポートBのRB4からRB7までの入力変化時の割込み
   ③TMR0のタイマ/カウンタのオーバーフロー時の割込み
   ④データEEPROMへの書き込み終了時の割込み

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

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

2.割込みが使える様にするには?

 PICで割込みが入る様にするには下記の作業をしておくことが必要です。

 (1)INTCONレジスタのセット
  プログラムの最初にINTCONレジスタの条件をセットしておかな
  ければなりません。
  INTCONの中で必ずセットしなければならないのは、割込みを
  待つ種類の割込み許可ビットと全体割込み許可ビットです

  【INTCONレジスタの詳細】
   ビットNo ラベル   役 割
     0   RBIF   RB4~RB7の状態変化割込みフラグ
     1   INTF   RB0/INTの割込みフラグ
     2   T0IF   TMR0タイマ割込みフラグ
     3   RBIE   RB4~RB7の割込み許可ビット
     4   INTE   RB0/INTの割込み許可ビット
     5   T0IE   TMR0タイマの割込み許可ビット
     6   EEIE   データEEPROM書き込み完了割込み許可
     7   GIE    全体割込み許可ビット


 (2)割込み処理プログラムの準備
  次に必要なのは割込みが入った時実行させる割込み処理プログラム
  です。これは通常のプログラムと基本的には一緒なのですが
  必ず下記条件となっていなければなりません。

   ・開始番地は4番地からジャンプするようにする。
   ・INTCONレジスタの割込みフラグをクリアする。
   ・最後はRETFIEで終了する。
   ・必要な時には最初にレジスタを保存し、最後に復帰させて
    割込みが入った所に戻った時にレジスタを元に戻して正常に
    処理が継続するようにしておく必要があります。
    どんな状態で戻っても良い時にはこれは必要ありません。

    【例】WレジスタとSTATUSレジスタの待避と復旧

(0004)番地
    GOTO   PUSH    ;割込みジャンプ
    |
    |
PUSH  MOVWF  W_TEMP    ;Wレジスタ待避
    SWAPF  STATUS,W  ;STATUS取り出し
    MOVWF  ST_TEMP   ;STATUS待避
    |
    |(割込み処理)
     |
    SWAPF  ST_TEMP,W  ;STATUSを戻す
    MOVWF  STATUS   ;
    SWAPF  W_TEMP,F  ;Wレジスタを戻す
    SWAPF  W_TEMP,W
    RETFIE       ;割込み許可リターン

3.RB0/INT割込みの使い方

 これの動作は、RB0ポートの入力信号の立ち上がり(または立ち下がり)
 のエッジで割込みを発生します。
 使い方としては、外部からの信号で、ONかOFFかどちらか一方になった
 時だけ処理したいような時に使います。

   (1)立ち上がり/立ち下がりエッジの指定
   これはOPTIONレジスタのINTEDGビットで行います。
     INTEDG=0:立ち下がりエッジで割込み
     INTEDG=1:立ち上がりエッジで割込み
  (2)割込みの許可
    INTCONレジスタのINTEビットを「1」にして割込みを許可し
   ておきます。その後GIEビットを「1」にすれば割込み待ち
    となります。
  (3)割込んだらフラグのクリア
   割込み処理へジャンプしてきたら、INTCONレジスタのINTFフラグ
   をクリアして次の割込みに備えます。


4.PORTB割込みの使い方

 これの動作は、RB4~RB7のいずれかの入力に変化があるとその時点で
 割込みを発生します。
 使い方としては、スイッチで何らかの動作を変えるような時に使います。

  (1)入力モードの設定
   まず、PORTBのRB4~RB7を入力にします。
  (2)割込みの許可
   INTCONレジスタのRBIEビットを「1」にセットして割込みを許可
   しておきます。
  (3)割込んだらフラグのクリア
   割込み処理へジャンプしてきたら、INTCONレジスタのRBIFフラグ
   をクリアして次の割込みに備えます。


5.タイマ割込みの使い方

 タイマ割込みは、TMR0カウンタがFFから00になる時に発生します。
 この使い方は一定間隔ごとに割込ませるインターバルタイマや、
 正確なタイミング用のワンショットタイマとして使います。
 使い方の詳細は次章で説明しています。


6.データEEPROM割込みの使い方

 PICには64バイトのデータ用EEPROMが用意されており、電源が無く
 なっても消えることの無いメモリとして便利に使えます。
 しかし、このEEPROMは読み出しは非常に高速でプログラムで直接読み
 出しても問題無いのですが、書き込みは約10msecを必要とするため
 そのままでは待っている時間がもったいないことになります。
 そこで書き込みをスタートさせたら割込み待ちとし、その間に他の
 処理を実行することが出来ます。
 しかし、割込みでEEPROMを書き込むことはまず無いでしょう。
 まずループで書き終わるのを待っていても大丈夫なことがほとんど
 だと思います。

 (1)割込みを許可する
  INTCONレジスタのEEIEビットを「1」にセットして割込みを許可
  しておきます。
 (2)書き込みをスタートさせます。
  書き込みの手順は下記となります。そしてこの手順を終えたあと
  他の処理にジャンプしてもかまいません。

WR_EEPROM
   BCF    INTCON,GIE   ;割込み禁止
   MOVF    E_ADRS,W    ;アドレスデータ→EEADR
   MOVWF   EEADR      ;Address set
   MOVF    E_DATA,W    ;書き込むデータ→EEDATA
   MOVWF   EEDATA     ;Data set
   BSF    STATUS,RP0   ;Bank1に切替え
   BSF    EECON1,WREN   ;書き込み許可
   MOVLW   55H       ;
   MOVWF   EECON2     ;書き込み開始準備
   MOVLW   0AAH
   MOVWF   EECON2
   BSF    EECON1,WR    ;書込み開始
   BSF    INTCON,GIE   ;割込み許可
   GOTO    ???       ;他の処理へ

 (3)割込みフラグをクリアする
  割込みが入ってきたら、まず割込みフラグをクリアします。
  EEPROMの割込みフラグだけは、EECON1レジスタのEEIFビットですので
  Bank1に切替えてクリアする必要があります。
  その後は、次のアドレスに書き込むなり、終了するなりして割込み
  処理をRETFIEで完了します。


さて次はタイマーの使い方の説明です。


       目次ページへ