H8/3052Fには、様々なハードウエアが組み込まれている。この中で、割り込みを発生する周辺装置(デバイスという)は、以下のように複数ある。
CPUは、これらの周辺デバイスが発生する割り込みを識別して、それぞれに合った処理(割り込みハンドラ)を行う必要がある。このために、それぞれの割り込みに対して、処理する割り込みハンドラを対応付けする必要がある。これを行うのが、割り込みベクタと呼ばれる表で、メモリの特定のアドレスに、割り込みベクタを配置している。(セクションのCVECTBLで、0xFE110から始まる256Byteの領域で、monitor.hの VectorTable配列として定義している。)
この場合、ベクタ番号は配列の添字に相当する。
| ベクタ番号 | アドレス | 種類 | 説明 |
| 0 | FFE110 | リセット | 電源投入/リセット入力時 |
| 1 | FFE114 | 予約 | |
| 2 | FFE118 | 予約 | |
| 3 | FFE11C | 予約 | |
| 4 | FFE120 | 予約 | |
| 5 | FFE124 | 予約 | |
| 6 | FFE128 | 予約 | |
| 7 | FFE12C | NMI | マスク不能割り込み(緊急時に利用) |
| 8 | FFE130 | TRAP0 | トラップ命令により発生 |
| 9 | FFE134 | TRAP1 | 〃 |
| 10 | FFE138 | TRAP2 | 〃 |
| 11 | FFE13C | TRAP3 | 〃 |
| 12 | FFE140 | IRQ0 | 外部割り込み |
| 13 | FFE144 | IRQ1 | 〃 |
| 14 | FFE148 | IRQ2 | 〃 |
| 15 | FFE14C | IRQ3 | 〃 |
| 16 | FFE150 | IRQ4 | 〃 |
| 17 | FFE154 | IRQ5 | 〃 |
| 18 | FFE158 | 予約 | |
| 19 | FFE15C | 予約 | |
| 20 | FFE160 | WOVI | ウォッチドッグ(番犬)タイマ。システムの誤動作検出に使用 |
| 21 | FFE164 | CMI | リフレッシュコントローラ(DRAM接続時に使用) |
| 22 | FFE168 | 予約 | |
| 23 | FFE16C | 予約 | |
| 24 | FFE170 | IMIA0 | ITUチャネル0 (コンペアマッチ/インプットキャプチャA0) |
| 25 | FFE174 | IMIB0 | ITUチャネル0 (コンペアマッチ/インプットキャプチャB0) |
| 26 | FFE178 | OVI0 | ITUチャネル0 (オーバフロー0) |
| 27 | FFE17C | 予約 | |
| 28 | FFE180 | IMIA1 | ITUチャネル1 (コンペアマッチ/インプットキャプチャA1) |
| 29 | FFE184 | IMIB1 | ITUチャネル1 (コンペアマッチ/インプットキャプチャB1) |
| 30 | FFE188 | OVI1 | ITUチャネル1 (オーバフロー1) |
| 31 | FFE18C | 予約 | |
| 32 | FFE190 | IMIA2 | ITUチャネル2 (コンペアマッチ/インプットキャプチャA2) |
| 33 | FFE194 | IMIB2 | ITUチャネル2 (コンペアマッチ/インプットキャプチャB2) |
| 34 | FFE198 | OVI2 | ITUチャネル2 (オーバフロー2) |
| 35 | FFE19C | 予約 | |
| 36 | FFE1A0 | IMIA3 | ITUチャネル3 (コンペアマッチ/インプットキャプチャA3) |
| 37 | FFE1A4 | IMIB3 | ITUチャネル3 (コンペアマッチ/インプットキャプチャB3) |
| 38 | FFE1A8 | OVI3 | ITUチャネル3 (オーバフロー3) |
| 39 | FFE1AC | 予約 | |
| 40 | FFE1B0 | IMIA4 | ITUチャネル4 (コンペアマッチ/インプットキャプチャA4) |
| 41 | FFE1B4 | IMIB4 | ITUチャネル4 (コンペアマッチ/インプットキャプチャB4) |
| 42 | FFE1B8 | OVI4 | ITUチャネル4 (オーバフロー4) |
| 43 | FFE1BC | 予約 | |
| 44 | FFE1C0 | DEND0A | DMAC |
| 45 | FFE1C4 | DEND0B | 〃 |
| 46 | FFE1C8 | DEND1A | 〃 |
| 47 | FFE1CC | DEND1B | 〃 |
| 48 | FFE1D0 | 予約 | |
| 49 | FFE1D4 | 予約 | |
| 50 | FFE1D8 | 予約 | |
| 51 | FFE1DC | 予約 | |
| 52 | FFE1E0 | ERI0 | SCI0 受信エラー0 |
| 53 | FFE1E4 | RXI0 | SCI0 受信データ・フル0 |
| 54 | FFE1E8 | TXI0 | SCI0 送信データエンプティ0 |
| 55 | FFE1EC | TEI0 | SCI0 送信終了0 |
| 56 | FFE1F0 | ERI1 | SCI1 受信エラー1 |
| 57 | FFE1F4 | RXI1 | SCI1 受信データ・フル1 |
| 58 | FFE1F8 | TXI1 | SCI1 送信データエンプティ1 |
| 59 | FFE1FC | TEI1 | SCI1 送信終了1 |
| 60 | FFE200 | ADI | AD変換終了 |
H8/3052Fの割り込みベクタ
■実際のプログラミング
(1)割り込みハンドラの定義
割り込みハンドラというと、特別な関数のように聞こえるかもしれないが、書き方は通常の関数と同じ。ただ、関数の宣言の前に
| #pragma interrupt(割り込みハンドラの関数名) |
を記述しておくこと。
(2)割り込みハンドラをベクタテーブルに登録
monitor.hに定義されているベクタテーブルに、割り込みハンドラの関数名を記述する。
(3)割り込みマスクと優先順位に関する設定を行う。
SYSCRのI ビットを制御するには、
| set_imask_ccr(1); // SYSCRのI ビットを1に設定し、全割り込みを不許可にする。 |
もしくは、
| set_imask_ccr(0); // SYSCRのI ビットを0に設定し、全割り込みを許可する。 |
とする。
【注意】
set_imask_ccr関数を呼び出すには、monitor.hの先頭付近に
| #include <machine.h> |
を入れておくこと。... でないと、コンパイルエラーが発生する。
以下のように示すように、IERの各ビットが、IRQの信号線に対応している。(IRQxEが、IRQx信号線に対応)
| bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| IRQ名 | IRQ5E | IRQ4E | IRQ3E | IRQ2E | IRQ1E | IRQ0E | ||
| 初期値 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
IRQxEの値を1にすれば、該当するIRQx信号線による割り込みが有効になる。
以下は、外部割り込み信号線(IRQ0)にイベント(信号の立下り:エッジトリガ)が発生した時に、割り込みハンドラirq0_handlerを呼び出すプログラムの例。
main関数と割り込みハンドラの記述、およびベクタテーブルへの割り込みハンドラの登録例を示したもの。
(割り込みに関連する記述を赤字で示した。)
※ 外部割り込み信号線と、マイコンボード上の端子との関係は、回路図を参照のこと。
|
#include "monitor.h" #define PB_DDR (*(volatile unsigned char *)0xFFFFD4) #define PA_DDR (*(volatile unsigned char *)0xFFFFD1) #define ISCR (*(volatile unsigned char *)0xFFFFF4) |
割り込みハンドラとmain関数の記述例
|
#define printf ((int (*)(const char *,...))0x00002b52) #pragma section VECTBL void PowerON_Reset(); void irq0_handler();
// 割り込みハンドラのプロトタイプ宣言 typedef void (*fp)(void); const fp VectorTable[] = //
ベクタテーブルの定義 int main(void); __entry void PowerON_Reset(void) |
monitor.hの内容とベクタテーブルの定義
多重割り込み
H8/3052Fの割り込み処理では、割り込みハンドラ内部では、デフォルトで他の割り込みは禁止されている。(set_imask_ccr(1)の状態)従って、割り込みハンドラの処理中に、その他の割り込みイベントが発生しても、割り込みハンドラが新たに起動されることは無い。(つまり、多重割り込み禁止の状態)
現実のプログラミングでは、ある割り込みハンドラ(例えばIRQ0)実行時に、他の割り込み処理(例えばIRQ1)を受け付けたい場合も存在する。(つまり、割り込み処理実行中に、他の割り込み処理を受け付ける事。同じ割り込みでも良い)こういうのを多重割り込みと呼ぶ。
多重割り込みを受け付けるには、割り込みハンドラ内で、
| set_imask_ccr(0) |
を実行すればよい。
多重割り込みとリエントラント