目次>9章 PIC18F1320編 > 優先/非優先割込みを使う

優先/非優先割込みを使う

更新日2009.1.25

PIC18では、割込みに2つの優先順位を付ける事が可能です。
今回の実験では、非優先割り込み処理中に優先割り込みが動作する事を確認します。

優先/非優先割込みは、時計などでTMR0割込みは正確に動作させつつ、スイッチでの割込みで設定処理を行うような場合に有効です。

実験回路

今回の実験回路は前回と同じです。
スイッチ周りには簡易チャタリングキャンセル回路を組みます。

680Ωの抵抗2本は、300Ω〜1KΩ程度の範囲であれば何でもOKです。

優先・非優先割込みとは

PIC18では、優先割込みと非優先割込みの2つのレベルの割込みがサポートされました。
この2レベルの割込みが何故必要か見て行きましょう。

割込みの基本
割込みの基本的な動作を下図で説明します。
図の水色は通常処理、灰色は割込み要因、黄色は割込み処理です。

例えば、TMR0割込みだけを有効にすると以下のような動作になります。


(1)TMR0レジスタがオーバフローすると
(2)TMR0割込みが発生し、通常処理が中断されて割込み処理が起動される
(3)割込み処理から復帰(RETFIE命令実行)すると、中断された通常処理が再開される

2つの割込みを使うとどうなるか
では、2つの割込みを使うとどうなるでしょう。
この例は、TMR0割込みPORTBピン変化割込みを使っています。
PIC16のように優先割込みが無い場合、またはPIC18で優先割込みを使わない時の動作です。
割込み事象の発生タイミングにもよりますが、以下のような動作もあり得ます。


(1)PORTBのピン状態が変化すると
(2)PORTBピン変化割込みが発生し、通常処理が中断されて割込み処理が起動される
(3)割込み処理中にTMR0レジスタがオーバフローすると、実行中の割込みが完了するまでTMR0割込みは保留される
(4)ピン変化割込み処理が終わって割込みから復帰すると、保留されていたTMR0割込みが実行される
(5)割込み処理から復帰すると、中断された通常処理が再開される

このように、割込み事象発生からその割込み処理が起動されるまでに遅延が発生する事があります。
周波数カウンタや時計などでTMR0割込みを使っていると、上のようなタイミングで誤差が発生することがあります。
この遅延を考慮してプログラムを作る事も可能ですが、多くの割込みを使うと対応しきれないケースも出てきます。

割込み遅延を抑止する優先割込み
PIC18では、2つのレベルの割込みが用意され、このようなケースに対応できるようになっています。
上の例で、TMR0割込みだけは遅延なく処理したいとすると、TMR0割込みを優先割込みとし、ピン変化割込みを非優先割込みに設定します。
このようにすると、先ほどと同じタイミングで割込み事象が発生しても、TMR0割込みは遅延無く処理されます。


(1)PORTBのピン状態が変化すると
(2)PORTBピン変化割込みが発生し、通常処理が中断されて非優先割込み処理が起動される
(3)非優先割込み処理中にTMR0レジスタがオーバフローすると
(4)実行中の非優先割込み(ピン変化割込み)処理が中断されて優先割込み(TMR0割込み)が起動される
(5)TMR0割込み処理が終わって割込みから復帰すると、中断されたピン変化割込み処理が再開される
(6)ピン変化割込み処理が終わって復帰すると、中断された通常処理が再開される

このように割込みに優先順位を付ける事で、非優先割込み処理中でも優先割込みは遅延無く実行する事が可能です。


優先割込み・非優先割込みのプログラム構造

(1)割込みベクタ

優先・非優先割込みを使う場合の割込みベクタは以下のようになっています。

(2)割込み処理の基本形

優先・非優先割込みを使う場合のプログラムの基本形は以下のようになります。

;****************************************************
        ORG    0x0000           ;リセットベクタ
        GOTO   Main             ;メイン処理へ

;****************************************************
        ORG    0x0008           ;高優先割り込みベクタ
        BRA    HighInt          ;高優先割り込み処理へ

;****************************************************
        ORG    0x0018           ;低優先割り込みベクタ
        MOVFF  STATUS,STATUS_S  ;save STATUS
        MOVFF  WREG,WREG_S      ;save WREG
        MOVFF  BSR,BSR_S        ;save BSR

        ; 低優先割り込み処理を記述

        MOVFF  BSR_S,BSR        ;restore BSR
        MOVFF  WREG_S,WREG      ;restore WREG
        MOVFF  STATUS_S,STATUS  ;restore STATUS
        RETFIE

;****************************************************
HighInt
        ; 高優先割り込み処理を記述

        RETFIE FAST

;****************************************************
Main
        ; メイン処理


優先割込みで使うレジスタ

TMR0割込みとPORTBピン変化割込みで使うレジスタについて説明します。

RCON
Bit7Bit6Bit5Bit4Bit3Bit2Bit1Bit0
IPEN--RITOPDPORBOR
10011100

優先割込みで使うビットは、IPENのみです。その他のビットは変更しないか、表の3行目のようにしておきます。

IPEN優先割込み機能有効ビット
1:優先割込み機能有効(優先割込み・非優先割込みを使える)
0:優先割込み機能無効(PIC16互換で割込みモードは1種類)

INTCON2
Bit7Bit6Bit5Bit4Bit3Bit2Bit1Bit0
RBPUINTEDG0INTEDG1INTEDG2-TMR0IP-RBIP

TMR0IPTMR0割込み優先・非優先選択ビット
1:優先割込みとする
0:非優先割込みとする
RBIPピン変化割込み優先・非優先選択ビット
1:優先割込みとする
0:非優先割込みとする

INTCON
Bit7Bit6Bit5Bit4Bit3Bit2Bit1Bit0
GIEHGIELTMR0IEINT0IERBIETMR0IFINT0IFRBIF

INTCONのビット6,7は優先割込みを使う場合(IPEN=1)と使わない場合で意味が異なります。
その他のビットは違いは有りません。
使わないビットは0にしておきます。

GIEH全優先割込み禁止ビット
1:全優先割込み許可(個々の割込み有効・無効ビットに従う)
0:全ての優先割込み禁止
GIEL全非優先割込み禁止ビット
1:全非優先割込み許可(個々の割込み有効・無効ビットに従う)
0:全ての非優先割込み禁止
TMR0IETMR0割込み有効・無効ビット
1:TMR0割込み有効
0:TMR0割込み無効(禁止)
RBIEピン変化割込み有効・無効ビット
1:ピン変化割込み有効
0:ピン変化割込み無効(禁止)
TMR0IFTMR0オーバフロー発生フラグ
1:TMR0オーバフローが発生した(割込み処理でクリアが必要)
0:TMR0オーバフローは発生していない
RBIFRB4−7ピン状態変化フラグ
1:ピン状態が変化した(割込み処理でクリアが必要)
0:ピン状態は変化していない


プログラムで動作を確認

それでは、この動作をプログラムで確認して見ましょう。

プログラムの仕様は以下の通りです。
TMR0割込みを優先割込みとし、ピン変化割込みを非優先割込みとする
TMR0割込み周期は約1.7秒とし、割り込み毎にRB0をON/OFFさせる
ピン変化割込みでは、RB1をONにしてRB0がOFFになるのを待ち、RB1をOFFにして復帰する
割込み処理は極力短く、短時間で復帰するように作る事が基本ですが、今回は割込み処理中の割込みを確認するために敢えてこのようにしています。


先ほどと同じ図でこの動作を表すと以下のようになります。

プログラムはこちらです。


PIC18の勧め(Vol.8)

その10. 優先割り込みモードを使えば、遅延無く割込み処理を実行できる
PIC18では、優先・非優先割込みの2つの割込みレベルがサポートされ、非優先割込み処理中でも優先割込みを遅延無く処理できます。