アナログコンパレータで必要となるレジスタは前回も使用した ACSR レジスタ。今回は sleep 命令を使うので MCUCR レジスタの設定も必要になる。
ldi temp, 0b01001000 ; ||||||||________ACIS0: Analog Comparator Interrupt Mode Select ; |||||||_________ACIS1: Analog Comparator Interrupt Mode Select ; |||||| 立ち下がり、立ち上がりのどちらでも出力するように00設定 ; ||||||__________予約ビットなので設定不要 ; |||||___________ACIE: Analog Comparator Interrupt Enable ; |||| アナログコンパレータ許可ビット 今回は1をセットして許可 ; ||||____________ACI: Analog Comparator Interrupt Flag ; |||_____________ACO: Analog Comparator Output ; || コンパレータ出力がここにセットされる ; ||______________ACBG: Analog Comparator Bandgap Select ; | 今回は内部基準電圧(1.22V±0.05V)を使う ; |_______________ACD: Analog Comparator Disable ; このビットをセットするとアナログコンパレータ禁止となる out ACSR, tempPB1 の入力電圧が比較基準電圧を境に上下する都度、アナログコンパレータ遷移割り込みが発生する。この割り込みを使い、 ACSR レジスタの bit5 の出力に基づいて LED の点滅を制御すればいい。
スリープ動作にはアイドル動作と A/D 変換ノイズ低減動作と最も消費電流の少ないパワーダウン動作がある。この中でアイドル動作が今回の割り込みで使える。消費電流はさほど減らないが、今回のような用途では使った方がいいだろう。
ではその設定をみてみよう。
ldi temp, 0b00100000 ; | ||________SM0: ; | |_________SM1: 両方を00にセットしてアイドル動作に設定 ; |_____________SE: 1 = Sleep Enable out MCUCR, temp ;スリープ許可と意外と簡単である。コンパレータ出力に変化があるとスリープモードから目覚めて割り込み処理が実行される。
sleep 命令を使わないときと使ったときとでどの程度消費電流に差が出るかを調べてみた。電源電圧約 3V で LED 消灯時、 sleep 命令を使わないときで約 3mA だった消費電流は 2mA 以下になった。
ところでアナログ量を扱う今回のようなプログラムでは AVRstudio でのシミュレーションはうまくいかない。 I/O ウィンドウを開き、割り込みフラグを直接変化させて割り込みを発生させる方法でデバッグすることになる。
基準電圧に対して PB1 の電圧が低くなったときにコンパレータ出力である ACO ビットがセットされる。そこで I/O ウィンドウの Analog Comparator の ACO ビットにチェックを入れた。
またシミュレータで sleep 命令を実行しても実際にスリープモードのアイドル動作になったかどうかを確認できない。これは sleep 命令を使わないプログラムと sleep 命令を使ったプログラムをそれぞれ AVR に書き込んで実際にテストし、消費電流の違いからその動作を確認した。