PIC18F452 の 割込み

高位、低位の割込み

PIC18F452は割込み優先機能があり
  高位割込みベクタは 000008h
  低位割込みベクタは 000018h となります。
割込みの優先機能を使わない場合の割込みベクタは高位割込みベクタと同じ000008hです。

割込みに優先機能を持たせるか、PIC16Fxxタイプのような優先機能の無い方法にするかは RCON レジスタの bit7で決められます。
RCON の IPEN(bit7)=1 なら優先機能有効、IPEN(bit7)=0 なら優先機能無しになります。

Fast Resister Stack

割込みプログラムに入るとき Wレジスタや STATUSレジスタ、 BSRレジスタの値を保存し、割込みプログラムが終わったらそれらのレジスタの値を元に戻す処理(コンテキストの保存)が必要です。

PIC18F452では高位の優先割込みや優先機能を使わない割込みにおいて、Fast Resister Stack というものが使えます。これは陰のレジスタです。

このスタック、ユーザは読書きできず、CALL 命令の呼出先に FAST を付けると割込みがおこなわれるとき Wレジスタや STATUSレジスタ、BSRレジスタの値(コンテキスト)を保存します。割込みプログラムの終りに RETURN FAST 命令を実行させると退避された値は元のレジスタに復帰します。

下記に優先順位を付けない参考プログラムを示します。
ORG 000000h ; リセットベクタ
GOTO START
ORG 000008h ; 高位割込ベクタ
GOTO ISR
−−−−
−−−−
BCF RCON, IPEN ; 優先順位を付けない割込
MOVLW B'10110000' ; TMR0, INT0 割込可、RB7--4割込なし
MOVWF INTCON
MOVLW B'00000101' ; RBプルアップ、TMR0は高位割込
MOVWF INTCON2
MOVLW B'11011000' ; INT1,INT2 割込高位、割込可
MOVWF INTCON3
−−−−
−−−−
ISR ; 割込サブルーチン
CALL SUB1, FAST ; STATUS, W, BSR のレジスタを退避して
; 割込プログラム SUB1をコールする
RETFIE FAST ; GIE(GIEHかGIEL)をセットして次の割込可
; とする  STATUS, W, BSR の値を復帰させ
; 割込プログラムを終る
SUB1 −−−− ; ここに割込プログラムを入れる
−−−−
−−−−
RETURN ; SUB1の終わり
ところでこの FAST って一体何なのでしょうか?
MPLAB のPIC18F452用インクルードファイル P18F452.INC では

FAST    EQU 1     と定義しています。  つまり FAST = 1 です。

PIC18F452 のインストラクションでは

CALL  k, FAST → CALL  k,1 は W, STATUS, BSR レジスタの値をシャドウレジスタに退避(保存)してサブルーチンをコールするインストラクションです。

RETURN FAST → RETURN 1 はシャドウレジスタに退避したレジスタの値を元に復帰させてサブルーチンから抜けるインストラクションです。

RETFIE FAST → RETFIE 1 は割込み GIE/GIEH をセットし、シャドウレジスタに退避したレジスタの値を元に復帰させて割込みから抜けるインストラクションです。

各インストラクションとも FASTとか 1をつけなければシャドウレジスタへコンテキストの退避や復帰操作は行われません。

割込みから戻るとき次の割込みが行えるように INTCON レジスタのGIEビット(優先順位をつけたときは GIEH かGIEL)をセットしなければなりません。

     RETURN FAST
     RETFIE
とすると別途 GEI(GIEH)をセットしなければ次の割込みができません。

     RETURN
     RETFIE FAST
なら GEI(GIEH)はセットされるので次の割込みができます。
どちらにするかプログラムに応じて使い分ければよいのでしょう。

割込みプログラムを作って試してみましたが次のようにしても動作しました。

ISR
     CALL    SUB,FAST
SUB
     ---------(割込みルーチン)
     ---------
     RETFIE FAST(またはRETURN FAST)

のようにしても OK です。 最後を RETURN FAST  とした場合は
その前に BSF INTCON, GIEを入れないと次の割り込みがおこなわれません。



優先順位高位と低位の割込み

優先順位をつけた割込みプログラムをテストしてみました。
割込みに関するプログラム部分を書き出しました。
CBLOCK 0000h
-------
W_TEMP ; コンテキスト退避用レジスタ
BSR_TEMP
PCLATH_TEMP
STATUS_TEMP
-------
ENDC
ORG 000008h ; 高位割込ベクタ
GOTO ISR ; 高位割込プログラムへ
ORG 000018h ; 低位割込ベクタ
GOTO ISR_L ; 低位割込プログラムへ
-------
-------
BSF RCON, IPEN ; 高位、低位の優先順位を付けた割込み
MOVLW B'11110000' ; TMR0, INT0 割込可
MOVWF INTCON
MOVLW B'00000100' ; TMR0は高位割込
MOVWF INTCON2
MOVLW B'00011000' ; INT1, INT2 は低位割込、 割込可
MOVWF INTCON3
-------
-------
ISR ; 高位割込サブルーチン
CALL SUB1, FAST ; STATUS, W, BSR などコンテキストの
; 退避をおこなう
; 割込みプログラム SUB1をコールする
SUB1 ------- ; ここに高位割込プログラムを入れる
-------
-------
RETFIE FAST ; GIEHをセットして次の割込可とする
; コンテキストを復帰させ
; 高位割込プログラムを終る
ISR_L ; 低位割込みサブルーチン
MOVWF W_TEMP, W ; コンテキストの退避
MOVFF BSR,BSR_TEMP
MOVFF PCLATH,PCLATH_TEMP
MOVFF STATUS,STATUS_TEMP
------- ; ここに低位割込みプログラムを入れる
-------
-------
; コンテキストの復帰
MOVFF PCLATH_TEMP, PCLATH
MOVFF BSR_TEMP, BSR
MOVF W_TEMP, W
MOVFF STATUS_TEMP, STATUS
BSF INTCON,GIEL ; GIEL=1 次も割込可にする
RETFIE ; 低位割込みサブルーチンの終わり
高位、低位の順位をつけた割込みをプログラムすると、低位割込み中に高位割込みがおこなえます。たとえば、高位割込みでTMR0により7セグメントLEDをダイナミック点灯するばあい、低位割込み中でもLEDの点灯ができます。ただし高位と低位の割込みで同じプログラムルーチンを使用すると衝突が起きてプログラムはフリーズすることがあります。

2005.1.30 改訂
                PIC 目次へ             トップページへ戻る