2007年9月24日月曜日

タイマーとスリープモード (その1)

ワンチップマイコンを使っていると、NOPとその回数の計数によって作るループを良く使います。手軽ですしなにより直観的にループの回数(遅延時間)が分かりやすいのがメリットでしょう。ただし、遅延している時間のあいだ中 NOP を実行している訳なので消費電力の観点からもったいない気がします。そこで今回は内蔵のタイマーとスリープモードを組み合わせて遅延時間を作る wait ルーチンを組んで、NOP の空回しとで、どの程度消費電力に差が出るかを実験してみる事にしました。


;;; Wait Routine for 40us ;;;
;;; fosc = 10MHz, 400cycle loop ;;;
;;; 0.1usec * 2 * 200 = 40usec ;;;
WAIT40u:
LDI R19,200
W_LOOP40: ; Wait Loop
DEC R19 ; 1cycle
BRNE W_LOOP40 ; 1cycle
RET


上の例は AVR のアセンブラで マイコンから LCD へのコマンドとコマンドの送出間隔をコントロールするための wait ルーチンで、ここでは、10MHzで駆動している ATtiny2313 を 40usec 遅延させています。 上にも書きましたが、直観的に遅延時間が分かりやすいのが特徴です。 この wait ルーチンと 同じように NOP だけで作った100msec の wait ルーチンを組み合わせて 1/10秒ステップのストップウォッチもどきを作って消費電流を測定します。

電源電圧5V、繋がっている周辺回路は16行2列のLCD一つで、(基板上には他の回路も載っていますが、機能はオフしてあります) 消費電流は、10.0mA です。

こんどは、同じように 40usec の waitルーチンですが、遅延時間内は idle sleep の状態にしておきます。


;;; Timer-0 overflow interrupt ;;;
;;; exit sleep mode ;;;
Timer0Int:
reti

;;; Wait Routine for 40us, sleep ver. ;;;
;;; fosc = 10MHz ;;;
;;; 0.1usec * 8 * 50 = 40usec ;;;
;;; 1/8 prescale, 50cycle ;;;
WAIT40u:
ldi R19,0xCE ; 0xFF(256) - 0x32(50) = 0xCE(206)
out TCNT0,R19 ; set counter value : 50
ldi R19,0b00000010 ; prescaler : 1/8
out TCCR0B,R19 ; set timer0
sleep ; enter sleep mode
ret


wait ルーチンが呼ばれると TCNT0 にカウント回数を、TCCR0B にプリスケーラーの値をセットしてタイマールーチンに入ります。直後にsleepコマンドが実行され timer-0 の割り込み (Timer0Int) がかかるまで sleep モードにいます。 この一つ大枠のwaitルーチンで タイマーとsleepモードを組み合わせた 100msec waitループが組んであります。動作状況としては 100msec のうち ほぼ100usec だけ内部クロックが動作している事になります。この状態での消費電流は 5.9mA でした。約4mAの電流低減がはかれます。

これが正しいかどうか、マニュアルで確かめてみましょう。




動作周波数10MHz、電源電圧5Vの時のactive電流はおおよそ6mA、idle電流は2mAとなっているので差分としてはだいたい正しそうです。 絶対値として少し大きめに出ている原因の一つはLCDの消費電流がありますが、それでも少し大きすぎです。この件に関しては追実験が必要のようです。

このように、比較的待ち時間の長い waitループでは積極的に タイマーとsleepモードを組み合わせて利用すると消費電流の低減をはかれます。

次回はもう少しインターバルの長い条件 (1sec wait)では、どのような結果が出るか実験してみます。

0 件のコメント:

++ Myself ++

普通(?)のサラリーマン -- 生活のすきま時間にキーボードとはんだごてを持ち替えてプログラミングと電子工作してます