PIC24Fにおける割込禁止/許可方法

PIC24Fにおける割込禁止/許可方法を挙げておく。

方法 具体的な操作 影響範囲
DISI命令 DISI命令を実行。禁止クロック数を定数で指定するため、見積もれないと使いにくい。 レベル6以下の全割込
割込有効化制御レジスタ IECレジスタの該当ビットをクリア。 該当割込要因のみ
割込優先レベル IPL<2:0>をIPCレジスタの該当レベルより上げる。 マスク可能全割込
割込優先度制御レジスタ IPCレジスタの該当レベルをIPL<2:0>より下げる。 該当割込要因のみ
割込ネスティング無効 NSTDISビットを0にし、かつ意図的に割込を発生させる。 マスク可能全割込
周辺モジュール 周辺モジュールの割込発生許可を無効にする。モジュールの仕様次第。 該当割込要因のみ



割込を全般的に発生させない簡単な方法は、DISI命令(レベル7は禁止できない)とIPL<2:0>の引き上げである。ただし、可変回数ループのように割込禁止クロック数を計算できないならDISI命令を使えず、確実な方法はIPL<2:0>の引き上げだけとなる。
IPL<2:0>を最上位の7へ引き上げる一般手順は以下のようになる(割込ネスト有り)。

push sr
mov.b #0xE0, w0
ior.b srl
戻すときは以下の通り。

pop sr
スタックに元のレベルを保存する必要があるため、このようなコードになる。

割込レベルの0〜3だけを使用するなら、引き上げるとき3命令→1命令に減らすことが出来る。スタックの消費も無い。

bset.b srl, #IPL2
IPL2をセットすると割込優先レベルは4〜7になる。それでもレベル0〜3だけを使用するのだから新たな割込が入ることはない(当然マスクできない割込を除く)。
戻すときは以下の通り。

bclr.b srl, #IPL2
割込レベルの0〜1だけ使用するというのは、割込ネスト無効と同じだ。

割込ネスティング無効による方法は、初期設定以外に何の操作も要らないという点で手軽である。「意図的に割込を発生させる」という点がネックに見えるが、逆にすべての処理を割込ハンドラ内で実行すると考えるとわかりやすい。
初期化完了後の通常処理(割り込みレベル0)を以下のようにする。

loop:
pwrsav #1 ; Idle
goto loop
これで割込が発生するまでCPUはアイドルしている。割込が発生するといきなり割り込みハンドラから実行が再開され、割込ハンドラが終了すると、通常処理で再度アイドルする。
例えば1秒毎にA/D変換で計測して、結果をUARTで送信するアプリなら、初期設定で1秒毎にタイマ割込を掛け、その割込ハンドラ内でA/D変換を開始する。A/D変換終了の割込ハンドラ内ではUARTに送信データを送る、という具合で完全なイベント・ドリブン型ソフトになる。もちろん通常処理で割込みから影響を受けない処理を実行しても良い。
ついでに割込発生までの消費電力を低減できる。その意味ではアイドルよりもスリープの方が有利だが、復帰に時間が掛かったり、クロックをどうするか、等の条件が関わってくるので、アイドルの方が気楽に使用できる。
更にA/D変換中にCPUが作動していると、消費電力により電源電圧が変動し変換誤差が発生しやすいため、この点でもアイドルするメリットがある。