AVRマイコン アセンブリ言語入門 ― 外部割込み
前回、割込み動作の説明をやったついでに、外部割込みの説明をします。
- 外部割込みってなんだよ?
たいていのマイコンは、外部割込み端子ピンを持っています。
AVRmega48/88/168/328シリーズだと、INT0, INT1 の2本の端子があり、ピン4,5番端子がそれにあたります。
このピンに、外部から変化をあたえると、割込み動作をさせることが出来ます。
例えば、外部割込み端子にスイッチをつないでおくと、スイッチ入力に使えます。
- 外部割込みってどうやって使うの?
AVRマイコンの各機能を使うには、それぞれの設定レジスタに値を設定するんでしたね。
外部割込みには、2つの設定内容(レジスタ)があります。
- 外部割込み条件の設定
- 外部割込みの許可を設定
1の外部割込み条件とは、外部割込み端子をどういう状態にすれば割込みを発生させるかを設定します。
「どういう状態」には4種類あり、以下になります。
1.端子をLowにする
2.端子に変化を与えた時(Low→High,またはHigh→Low)
3.端子をHigh→Lowにする下降エッジで発生
4.端子をLow→Highにする上昇エッジで発生
2の許可の設定は、そのままの意味で、外部割込みの使用を許可するための設定です。
設定レジスタの一覧を下に示します。
はい、外部割込みの設定はたったこれだけです。
簡単ですね。
では、ちょっと簡単なプログラムをつくってみます。
つくるのは、外部割込み端子0をHigh→Lowにすると、PortBのビット0端子に接続したLEDが反転する、というものにします。
上の表から、
EICRAレジスタのISC01,ISC00ビットを '10' へ、
EIMSKレジスタのINT0ビットを '1' へ
セットすればいいことがわかりますね。
で、プログラムが以下になります。
/* * EINT1.asm * * Created: 2015/12/12 20:24:42 * Author: Takachiho */ .include "m168pdef.inc" ;************************************************ ; 各種定義 ;************************************************ ;-------------------- ; 汎用レジスタ ;-------------------- .def STACK = R16 ;汎用レジスタR16に'STACK'という名前をつける ;-------------------- ; 割り込みベクタ定義 ;-------------------- .CSEG RJMP MAIN .ORG 0x0002 ;外部割込み0発生で RJMP EINT0 ;ラベルEINT0へジャンプする。 ;************************************************ ; 割り込みルーチン 外部割込み0 ;************************************************ EINT0: ;------- ステータスレジスタの内容を退避 -------- IN STACK, SREG ;------- LED ON/OFF を切り替え ------------------ IN R17, PORTB ;PortBの内容をR17へコピーする LDI R18, 0x01 ;R18へ値0x01 = 0b00000001を代入 EOR R17, R18 ;R17とR18の排他的ORの結果をR17へ OUT PORTB, R17 ;R17の結果をPortBへ代入する ;8bitタイマの時と同じ処理 ;------- ステータスレジスタの内容を復帰 -------- OUT SREG, STACK RETI ;************************************************ ; メイン・ルーチン (MAIN) ;************************************************ MAIN: ;------- 全割り込み禁止 ------------------------- CLI ;------- PORT 設定 ----------------------------- LDI R17, 0b11111111 ;ポートBは全て出力に設定 OUT DDRB, R17 LDI R17, 0b00000001 ;bit0以外すべて'0'出力 OUT PORTB, R17 LDI R17, 0b11111111 ;ポートCは全て出力に設定 OUT DDRC, R17 LDI R17, 0b00000000 ;すべて'0'出力 OUT PORTC, R17 LDI R17, 0b11111011 ;PD2(INT0 pin)を入力に設定 OUT DDRD, R17 LDI R17, 0b00000100 ;PD2はプルアップ設定 OUT PORTD, R17 ;------- 外部割込み0レジスタ設定 --------------- ;------- 外部割込み条件 設定 ------- LDI R17, 0b00000010 ;下降エッジで割込み指定 STS EICRA, R17 ;------- 割込み許可 設定 ------- SBI EIMSK, INT0 ;INT0ビットを'1'へ ;------- 全割り込み許可 ----------------------- SEI MAIN01: RJMP MAIN01
こまかいことを言うと、スイッチのチャタリング処理をちゃんとしないときれいに反転しないのですが、割込みが働いているのは良くわかります。