「天文屋のためのマイコン入門」タイマー割込みのプログラム
それでは、実際に割込みのプログラムを作って見ましょう。以前出したLEDが一秒間隔で点滅するプログラムですが、これを割込み仕様で記述してみます。
その前に、復習です。
1 タイマー0オーバーフロー割り込みは次の2行で初期化できる
BSF INTCON , 5 ;TMR0IE=1
BSF INTCON , 7 ;GE =1
(前回出した時は5のところが誤って2となっていました。ごめん)
2 割込み処理は4番地から記述する
これを踏まえてプログラムを掲載します。ただし、最初のシンボル定義の部分は前回と同じなので、省略しています。
上から説明していきます。
;秒数をカウントする
TIME_COUNT EQU 70h
(上の図では0f0hとなっていますが間違えです)
70h番地の汎用レジスタを秒数を保持する記憶領域として使用することとします。70hから7fh番地までの汎用レジスタはどのバンクからでもアクセスできるので、プログラム中で使う記憶領域はこの領域から選ぶと良いでしょう。この汎用レジスタにTIME_COUNTと名前をつけています。
次に、割込み処理部について説明します。
MOVLW -244
MOVWF TMR0 ;TMR0を再初期化
まず、割込み処理の一番最初でTMR0の再初期化を行っています。再び、TMR0に-244を代入することにより、1秒後に再び割込みが入るようにします。
INCF TIME_COUNT ;タイムカウントを増やす
次に、先ほどシンボルを定義したTIME_COUNTをインクリメントして秒数をカウントしています。
BTFSS TIME_COUNT,0;奇数ならスキップ
この一行は何をしているかというと、秒数が奇数か偶数の判別をしています。秒数が奇数ならLEDを点灯させて、偶数なら消灯させるためです。これによりLEDが点滅して見えます。奇数かどうかの判定は、一番下のビットで判断できます。一番下のビットが1なら奇数、0なら偶数です。
GOTO INT_SKIP1
BCF PORTA,4 ;LED消灯
GOTO INT_END
INT_SKIP1
BSF PORTA,4 ;LED点灯
INT_END
奇数ならLEDを点灯し、偶数なら消灯させる部分です。
次に、割込み処理の終了部分ですが、これが重要です。
BCF INTCON,2 ;重要! オーバーフローフラグクリア
オーバーフローフラグ、またはオーバーフロー割込み要求フラグとも言いますが、それをクリアしています。これは自動でクリアされないので、このようにプログラムでクリアしてやる必要があります。
これをクリアしないと、割込み処理から抜けた後、すぐまた割り込みが入ってしまいます。マイコンはタイマーがオーバーフローしたから割り込みを入れるのではありません。オーバーフローにより割込み要求フラグがセットされたから割込みが入るのです。マイコンは割込み要求フラグだけを見て、割り込みを入れているのです。ですから、このフラグは必ずクリアさせておきます。
最後に割込み処理から抜けるのですが、サブルーチンから戻るにはRETURN命令を使いました。割込み処理から抜けるには、
RETFIE ;割込みからのリターン
の命令を記述します。サブルーチンのRETURN命令とほぼ同じ動作をします。割込み処理の最後には必ずこれを記述します。
次に、初期化部の説明ですが、前半の部分は以前と同じなので、説明を省略します。
CLRF TIME_COUNT ;タイムカウント0クリア
秒数を0にクリアしています。
MOVLW -244
MOVWF TMR0 ;TMR0初期化
タイマーレジスタTMR0に-244を代入しています。オーバーフローするまで1秒に設定します。なぜ、244かは前回説明しました。
;タイマー0オーバーフロー割り込みの初期化
BSF INTCON , 5 ;TMR0IE=1
BSF INTCON , 7 ;GE =1
この部分は割込みの許可です。最初の命令でタイマー0オーバーフロー割込みを個別に許可しています。2番目の命令で、全割込み禁止を解除して、割り込みが発生できるようにしています。これ以後、タイマーがオーバーフロー次第、割込みが入ります。
最後にメイン処理部の説明ですが、
LOOP
GOTO LOOP
何もしてません、ただ無限ループを繰り返して、割込みが入るのを待っています。このプログラムは実質的には割込み処理がすべてです。
割込み処理の実際、いかがでしょうか? 実はこの割込み処理は不完全です。もう少し割込み処理について考えてみる必要があります。あとは次回に。
| 固定リンク
コメント