割り込みプログラミング
H8プログラムの構造で説明したように、4E実験のプログラムでは殆どの処理を割り込み処理で行う。割り込み処理の結果はグローバル変数に反映される。main()プログラムは割り込みに対する初期設定、グローバル変数を参照してのループ処理だけを行っている。
割り込み処理が殆どの処理をおこなう。
ここでは割り込み処理プログラムについて説明する。
なお、HEWを使用すると、intprg.cというファイルが自動作成され、すべての割り込み処理をこのファイル内に記述するようになる。ただしベクター番号0の割り込み(リセット割り込み)は特殊であるため、resetprg.cというファイルとして作成される。
1. 割り込みとは
実行中の処理を、割り込みイベント(例外処理要因)によって中断し、割り込み処理プログラムを実行し、この処理を終了したあとで、前の処理を再開する機能。
2. 割り込みの種類
2.1 マスク可能かどうかで分類
種類 | |
---|---|
NMI | Non-Maskable-Interrupt. マスク不可能な割り込み。 CCRのIビットが1でも割り込みが発生する。 最も優先度が高い割り込みで、データ入出力には使用されず、停電検出などに使用する。 |
NON-NMI | マスク可能な割り込み(CCRのIビットで割り込みをマスクできる割り込み)。 CCRのIビットを”1”とすると割り込みを発生させない、”0”とすると割り込みが発生する。 |
2.2 割り込みの種類・ベクタテーブル
割り込みは、下表のように発生元(要因元)で分類される。また割り込み優先順位は、この表の順番になっている。リセット端子からの割り込み優先順位が一番高い。
割り込み要因と割り込み処理関数の対応をテーブルにしたものが
「割り込みテーブル」であり、テーブルでの順番が「ベクトル番号」である。H8の割り込み優先順位は、たまたまベクトル番号の順番になっている。
ベクタテーブルには処理関数へのアドレスが4バイトで記入されている。割り込みが発生するとこのアドレスがPCにセットされて割り込み処理関数が実行される。
発生元 | 例外処理要因 | ベクトル番号 |
---|---|---|
リセット端子 | リセット | 0 |
システム予約 | 1〜6 | |
外部割込み端子 | NMI | 7 |
CPU | トラップ命令 #0 | 8 |
トラップ命令 #1 | 9 | |
トラップ命令 #2 | 10 | |
トラップ命令 #3 | 11 | |
アドレス・ブレーク | ブレーク条件成立 | 12 |
CPU | スレープ命令の実行による直接遷移 | 13 |
外部割込み端子 | IRQ0 | 14 |
IRQ1 | 15 | |
IRQ2 | 16 | |
IRQ3 | 17 | |
WKP(ウエイクアップ) | 18 | |
タイマーA | オーバーフロー | 19 |
システム予約 | 20 | |
タイマーW | インプット・キャプチャA/コンペア・マッチA | 21 |
インプット・キャプチャB/コンペア・マッチB | ||
インプット・キャプチャC/コンペア・マッチC | ||
インプット・キャプチャD/コンペア・マッチD | ||
オーバーフロー | ||
タイマーV | コンペア・マッチA | 22 |
コンペア・マッチB | ||
オーバーフロー | ||
SCI3 | 受信データフル | 23 |
送信データエンプテイ | ||
送信終了 | ||
受信エラー | ||
IIC2 | 送信データエンプテイ、送信終了 | 24 |
受信データフル | ||
アービトレーションロスト/オーバーランエラー | ||
NACK検出、停止条件検出 | ||
ADコンバータ | AD変換終了 | 25 |
3. CPUの割り込み動作
3.1 割り込みの開始
割り込みとなるイベントが発生したとき、CPUは以下の動作を行う。
@この発生元での割り込みが、許可されているかチェック。
周辺機器割り込みでは、要因に対応した割り込み許可ビットと割り込みフラグが”1’であること。
ACCRの割り込みマスクビット(Iビット)が’0”である(割り込みが許可されている)かチェック。
(注)NMI割り込みではこのチェックは無い。
以上のチェックをパスしたとき、割り込みが発生する。
BPCの値とCCRの値をスタックに退避する。
CCCRの割り込みマスクビット(Iビット)をセット。
CPUは、割り込みを実行中は、多重の割り込みを受け付けないようにしている。
DベクトルアドレスをPCの値にセットして、割り込みプログラムを実行。
(正確には、ベクトルアドレス32ビットを読み、下位の20ビットがアドレスとして使用されPCにセットされる)。
3.2 割り込み処理
割り込み処理プログラムが実行される。
このプログラムは、終了するとき、RTE命令(アッセンブラのRTE命令)を発行する。
3.3 割り込みの終了
CPUがRTE命令を受信したとき、以下の動作を行う。
@スタックに退避していたPCの値、CCRの値を復元
A元の処理を再開する。
これで割り込み処理は終了して、元のプログラムに復帰する。
(注意)上記の動作3.1と3.2は、プログラムではなく、CPU本体機能の動作として実行される。
4. 割り込みに対応するプログラム
2つの部分(割り込みに対する準備・受付設定、割り込みに対する応答)から構成される。
4.1 割り込みに対する準備・受付設定
(1)ベクターテーブルの確保
Hi8マイコンではH’0000からH’0033まではベクターテーブルてあるとして始めから確保されている。
(2)割り込み処理関数の定義
割り込みテーブルに、割り込み処理関数へのアドレスと記入し、割り込み処理関数の実体を定義する。
HEWでは以下のように記述する。
#pragma interrupt irq0(vect=12) void irq0(void); |
#pragmaはCコンパイラへの指示をするもの。irq0という関数が割り込み関数であることを示す。vect=12は、これが割り込みベクトル12であることを示す。 void irq0(void);は、割り込み処理関数のプロトライプ宣言 |
void irq0(void){ } | 割り込み処理関数本体の記述。 |
割り込み処理関数は、割り込みが発生したときに処理する関数。
これはvoid型の関数でありリターン値は無い。
main()プログラムとは別に記述する。
したがってフローチャートでは、独立した入力と出力をもったチャートになる。
(3)ベクターテーブルへの割り込み処理関数アドレスの登録
上記のソースコードをコンパイル、リンクすると、リンクのときにアドレスがテーブルに登録される。
(4)割り込み受付設定
これはmain()プログラム、また割り込み処理プログラムが次ぎの割り込みを受け付けるために設定する。
@CCRのIビットをセット(割り込み禁止モード)する。
これは、以下のAの設定が、割り込み禁止モードでおこなう必要があるためである。
(注意)
CCRのビットを操作するには、特別な関数 set_imask_ccr() を使用する。
またこの関数を使用するには、#include <machine.h> として、machine.hファイルをインクルードする。
A発生元の割り込みを受け付けるための各種設定をする。
この設定は、割り込み発生元によって、設定するレジスタが異なる。
最後に、割り込み要因に対する割り込みフラグをクリアする。
この設定詳細は、5.割り込み対応レジスタ を参照。
BCCRのIビットをリセットする(割り込み許可モード)する。
HEWを使用すると、上記の(1)、(2)、(3)はコメント付コードで自動作成される。
生かしたい部分のコメントを外すだけでよい。(4)の部分は実際にプログラミング(コーデイング)する必要がある。
4.2 割り込みに対する応答
割り込み処理関数に記述する。
@前処理
必要に応じて、汎用レジスタを退避する。
A割り込み処理
B後処理
割り込みフラグをクリアする。
割り込みビットを”0”にして割り込み可能とする
これで割り込みを再び受付けするようになる。
汎用レジスタの復元をする。
HEWを使用したとき、割り込みに関する4.1の(1)、(2)、(3)の外枠が自動作成される。開発者は、main()関数で割り込み受付設定を記述し、intprog.c内で割り込みに対す応答を記述するだけで、割り込みを使用することができる。
main()関数の例
intprog.cの例
5.割り込み対応レジスタ及びビット
5.1 IRQ端子割り込み
レジスタとビット | 内容 |
---|---|
コンデションコードレジスタ(CCR) 割り込みマスクビット(I) |
全体割り込み許可設定 =1 割り込み要求をマスク =0 割り込み要求のマスク解除(割り込み可能) |
ポート1・ポートモードレジスタ(PMR1) P14/IRQ0機能選択ビット(IRQ0) P15/IRQ1機能選択ビット(IRQ1) P16/IRQ2機能選択ビット(IRQ2) P17/IRQ3機能選択ビット(IRQ3) |
端子を割り込み端子として設定するか、汎用入出力ポートとするか、ポートの機能選択するレジスタ =0 汎用入出力ポート =1 IRQ0,1,2,3割り込み入力端子 |
割り込みエッジセレクトレジスタ(IEGR1) IRQ0エッジセレクトビット(IEG0) IRQ1エッジセレクトビット(IEG1) IRQ2エッジセレクトビット(IEG2) IRQ3エッジセレクトビット(IEG3) |
割り込み信号の立ち上がり、立下りの指定 =0 立下りエッジ検出 =1 立ち上がりエッジ検出 |
割り込みイネーブルレジスタ(IENR1) IRQ0割込要求イネーブルビット(IEN0) IRQ1割込要求イネーブルビット(IEN1) IRQ2割込要求イネーブルビット(IEN2) IRQ3割込要求イネーブルビット(IEN3) |
外部端子を割り込み可能設定 =1 割り込み要求イネーブル =0 デセーブル |
割り込みフラグレジスタ(IRR1) IRQ0割込み要求フラグビット(IRRI0) IRQ1割込み要求フラグビット(IRRI1) IRQ2割込み要求フラグビット(IRRI2) IRQ3割込み要求フラグビット(IRRI3) |
外部端子割り込みフラグ セット条件: IRQ0〜3端子が割り込み入力に指定され、指定のエッジを検出したとき。 クリア条件: ’0’を書き込んだとき。 |
5.2 NMI端子割り込み
レジスタとビット | 内容 |
---|---|
割り込みエッジセレクトレジスタ(IEGR1) NMIエッジセレクトビット(NMIEG) |
割り込み信号の立ち上がり、立下りの指定 =0 立下りエッジ検出 =1 立ち上がりエッジ検出 |
5.3 TimerA割り込み
TimerAは8ビットのカウンタでオーバフローしたとき(255から0に変化したとき)割り込みが発生する。
レジスタとビット | 内容 |
---|---|
コンデションコードレジスタ(CCR) 割り込みマスクビット(I) |
全体割り込み許可設定 =1 割り込み要求をマスク =0 割り込み要求のマスク解除(割り込み可能) |
プリスケーラ(PSS) | システムクロックを入力とする13ビットカウンタ。入力クロック設定 |
タイマモードレジスタ(TMA) インターナルクロックセレクとビット0 (TMA0) インターナルクロックセレクトビット1 (TMA1) インターナルクロックセレクトビット2 (TMA2) インターナルクロックセレクトビット3 (TMA3) |
プリスケーラの選択、入力クロックの選択 下の表を参照。 |
イマモードレジスタ(TMA) インターナルクロックセレクトビット3 (TMA3) |
タイマAの動作モード選択 =0 プリスケーラS = プリスケーラW |
割り込みイネーブルレジスタ(IENR1) タイマA割り込みイネーブルビット (IENTA) |
タイマ割り込み許可設定 =1 タイマAオーバフロー割り込みイネーブル =0 デセーブル |
割り込みフラグレジスタ(IRR1) タイマA割り込み要求フラグビット (IRRTA) |
割り込みフラグ セット条件: IRQ0〜3端子が割り込み入力に指定され、指定のエッジを検出したとき。 クリア条件: ’0’を書き込んだとき。 |
タイマカウンタ(TCA) | 8ビットタイマカウンタ、割り込み周期の設定 |
入力クロックの選択
Φはシステムクロック。3664Fでは16MHz。
インターナル・クロックセレクトビットTCA | TCA入力クロックの選択 | |||
---|---|---|---|---|
TMA3 | TMA2 | TMA1 | TMA0 | |
0 | 0 | 0 | 0 | Φ/8192をカウント |
0 | 0 | 0 | 1 | Φ/4096をカウント |
0 | 0 | 1 | 0 | Φ/2048をカウント |
0 | 0 | 1 | 1 | Φ/512をカウント |
0 | 1 | 0 | 0 | Φ/256をカウント |
0 | 1 | 0 | 1 | Φ/128をカウント |
0 | 1 | 1 | 0 | Φ/32をカウント |
0 | 1 | 1 | 1 | Φ/8をカウント |
5.4 TimerW割り込み
TimerWは16ビットのカウンタで、オーバフローしたとき、コンペアマッチちたとき、割り込みが発生する。
レジスタとビット | 内容 |
---|---|
コンデションコードレジスタ(CCR) 割り込みマスクビット(I) |
全体割り込み許可設定 =1 割り込み要求をマスク =0 割り込み要求のマスク解除(割り込み可能) |
タイマモードレジスタW(TMRW) カウンタスタートビット(CTS) |
カウンタスタート指定 =0 TCNTカウンタ動作停止 =1 TCNTカウンタ動作実施 |
タイマモードレジスタW(TMRW) PWMモードBビット(PWMB) FTIOB端子 PWMモードCビット(PWMC) FTIOC端子 PWMモードDビット(PWMD) FTIOD端子 |
タイマの出力モード選択 =0 通常のアウトプット・コンペア出力 =1 PWM出力 |
タイマモードレジスタW(TMRW) クロックセレクト0ビット(CKS0) クロックセレクト1ビット(CKS1) クロックセレクト2ビット(CKS2) |
TCNTの入力クロック設定(プリスケール) 下の表を参照。 |
タイマコントロールレジスタ(TCRW) タイマ出力レベル・セットAビット(TOA) FTIOA端子 タイマ出力レベル・セットBビット(TOB) FTIOB端子 タイマ出力レベル・セットCビット(TOC) FTIOC端子 タイマ出力レベル・セットDビット(TOD) FTIOB端子 |
コンペアマッチ前の出力値選択 =0 出力値0 =1 出力値1 |
タイマカウンタ(TCNT) | 16ビットカウンタ |
ジェネラルレジスタA(GRA) | PWM出力の周期設定 |
ジェネラルレジスタB(GRB) | FTIOB端子PWM波形のH幅を決める |
ジェネラルレジスタC(GRC) | FTIOC端子PWM波形のH幅を決める |
ジェネラルレジスタD(GRD) | FTIOD端子PWM波形のH幅を決める |
タイマインタラプトイネーブルレジスタW (TIERW) イネーブルAビット(IMIEA) イネーブルBビット(IMIEB) イネーブルCビット(IMIEC) イネーブルDビット(IMIED) オーバフローイネーブルビット(OVIE) |
コンペアマッチ割り込みイネーブル設定 =1 割り込みイネーブル =0 デセーブル |
タイマステータスレジスタW(TSRW) フラグA(IMFA) フラグB(IMFB) フラグC(IMFC) フラグD(IMFD) オーバフローフラグ(OVF) |
割り込みフラグ セット条件: IGRDA〜GRDがアウトプットコンペアレジスタとして機能し、TCNTと一致したとき。 クリア条件: ’0’を書き込んだとき |
タイマステータスレジスタW(TSRW) オーバフローフラグ(OVF) |
タイマーオーバーフロー割り込みフラグ セット条件: TCNTがH'FFFFからH'0000オーバフローしたとき。 クリア条件: ’0’を書き込んだとき |
クロックセレクトビット(CKS)とタイマカウンタ(TCNT)の入力クロック選択
クロックセレクトビット | TCNT入力クロックの選択 | |||
---|---|---|---|---|
CKS2 | CKS1 | CKS1 | クロック源 | 内容 |
0 | 0 | 0 | 内部クロック | Φをカウント |
0 | 0 | 1 | Φ/2をカウント | |
0 | 1 | 0 | Φ/4をカウント | |
0 | 1 | 1 | Φ/8をカウント | |
1 | * (任意) |
* (任意) |
外部イベント (FTCI) |
立ち上がりエッジをカウント |
5.5 AD変換終了割り込み
AD変換が終了したとき割り込みが発生する。
レジスタとビット | 内容 |
---|---|
コンデションコードレジスタ(CCR) 割り込みマスクビット(I) |
全体割り込み許可設定 =1 割り込み要求をマスク =0 割り込み要求のマスク解除(割り込み可能) |
ADコントロール/ステータスレジスタ (ADCSR) ADエンドフラグビット(ADF) |
ADエンドフラグ セット条件: AD変換終了のとき クリア条件: ’0’を書き込んだとき |
ADコントロール/ステータスレジスタ (ADCSR) ADインタプトイネーブルビット(ADIE) |
AD変換終了割り込み可能設定、 =0 禁止 =1 許可 |
ADコントロール/ステータスレジスタ (ADCSR) ADスタートフラグビット(ADST) |
AD変換スター =0 停止 =1 開始ト |
ADコントロール/ステータスレジスタ (ADCSR) スキャンモードビット(ADS) |
スキャンモード =0 単一モード =1 スキャンモード |
ADコントロール/ステータスレジスタ (ADCSR) クロックセレクトビット(CKS) |
AD変換時間の設定 =0 134ステート =1 70ステート |
ADコントロール/ステータスレジスタ (ADCSR) チャンネルセレクト0ビット(CH0) チャンネルセレクト1ビット(CH1) チャンネルセレクト2ビット(CH2) |
アナログ入力チャンネルの設定 下の表を参照。 |
ADコントロールレジスタ(ADCR) トリガーイネーブル(TRGE) |
外部トリガ可能かどうかの設定 =0 禁止 =1 許可 |
ADデータレジスタA(ADDRA) | 10ビットのAD変換データを格納 |
ADデータレジスタB(ADDRB) | 10ビットのAD変換データを格納 |
ADデータレジスタC(ADDRC) | 10ビットのAD変換データを格納 |
ADデータレジスタD(ADDRD) | 10ビットのAD変換データを格納 |
セレクトビットとアナログ入力チャネルの対応
セレクトビット | アナログ入力チャネル | |||
---|---|---|---|---|
CK2 | CK1 | CK0 | 単一モード時 (SCAN=0) |
スキャンモード時 (SCAN=1) |
0 | 0 | 0 | AN0 | AN0 |
0 | 0 | 1 | AN1 | AN0〜AN1 |
0 | 1 | 0 | AN2 | AN0〜AN2 |
0 | 1 | 1 | AN3 | AN0〜AN3 |
1 | 0 | 0 | AN4 | AN4 |
1 | 0 | 1 | AN5 | AN4〜AN5 |
1 | 1 | 0 | AN6 | AN4〜AN6 |
1 | 1 | 1 | AN7 | AN4〜AN7 |
6. 補足
6.1 多重割り込み
H8/300 Tinyシリーズでは、NMI割り込み以外では多重割り込みは無い。
6.2 割り込みの優先度
NMIだけは多重割り込みができる。IRQ0割込み実行中に、これより優先度が高いNMI割り込みが発生すると、IRQ0の割り込み処理は中断され、NMI割り込みが実行される。 NMI割り込み処理が終了するとIRQ0の割り込みが再開される。
一般の割り込みでは、2つ同時の割り込みが発生したら、優先度の高い割り込みから処理される。