90S2313での外部入力割り込みに続いて、ATMEGA8でも外部入力割り込み SIG_INTERRUPT0, SIG_INTERRUPT1 を使った。

DSC00816.jpg

INT0、INT1への割り込みをSIG_INTERRUPT0、SIG_INTERRUPT1でそれぞれ受け取り、立ち上がりエッジ/立ち下がりエッジで2つのLEDを点灯/消灯させる。→ソースコード(AVR-GCC)動画(3MB)

90S2313は立ち上がり/立ち下がりのどちらかしか検出できなかったのでプログラムでなんとかしていたが、mega8は論理変換を検出(つまり両エッジ)できるので全然簡単になっている。というかそれ以外全部同じだったので一発で動いた。

データシートの翻訳版より

MCUCR(MCU制御レジスタ)の割り込み発生条件制御ビット表

■やり方

INT0を設定する関数を作った。

/* INT0設定 */
void interrupt0_init(void){
cbi(DDRD,PD2); // INT0入力設定
sbi(GICR,INT0); // INT0割り込み許可
sbi(GIFR,INT0); // INT0割り込み要求フラグON
/* 両エッジ検出 */
sbi(MCUCR,ISC00);
cbi(MCUCR,ISC01);
/* 立ち上がりエッジ検出
sbi(MCUCR,ISC01);
sbi(MCUCR,ISC00);
*/
/* 立ち下がりエッジ検出
sbi(MCUCR,ISC01);
cbi(MCUCR,ISC00);
*/
}

main()で呼び出して、すぐsei();して有効にしておく。

そして割り込み部分。

/* INT0 外部割り込み */
SIGNAL(SIG_INTERRUPT0){
if(bit_is_set(PIND,PD2)){ // 立ち上がりの時
LED1_SET(); // LED1点灯
}
else{ // 立ち下がりの時
LED1_CLR(); // LED1消灯
}
}

INT1の方も全く同様に書いてある。