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)では、どのような結果が出るか実験してみます。

2007年9月11日火曜日

USBasp (改)をつくりました




Linuxで使えるライター(フラッシュへの書き込み)が欲しかったので作ってみました。以前はELMさんのところのCOMポート制御ISPアダプタを使っていましたが、AVRSP が DOS/Win しかサポートしておらず、Linux と Win で開発と書き込みの環境が分かれてしまうのが、つらくなってしまいました。 AVRDUDE がCOMポート制御ISPアダプタの書き込みソフトとして使えるという情報があり実験してみましたが、残念ながらこちらでは上手く動きませんでした。しばらくしたら追実験をしてみる予定です。で、USBasp ですが、部品点数も少なく書き込みスピードも早くて申し分ないものです、、、と書きたかったのですが、手を入れたい部分もあります。現在ファームの変更と追加ハードの実験をしています。
参考サイトはこちら↓
http://elm-chan.org/index_j.html (えるむ - Electronic Lives Mfg.)
http://yuki-lab.jp/ (ゆきの研究室)
http://www.fischl.de/usbasp/ (fischl.de - USBasp - USB programmer for Atmel AVR controllers)

2007年9月7日金曜日

スクラッチからAVR-GCC構築中 on Linux (その3)

解決しました、avr-gccの構築問題。

いずれもFedraCore4(kernel 2.6.x) & gcc4.x(4.0.0)ベース

1) gcc4.xを使う場合
binutils-2.17 / gcc-4.0.4 / avr-libc-1.4.6 を使えば普通にコンパイルできます。gcc-4.1.x以上を使うとコンパイルに失敗するのでいまのところ4.0.4止まり(4.0.xの最新版)。このavr-gccでATtiny2313もATmega48もコンパイル可能です。

2) gcc3.xを使う場合
binutils-2.17 / gcc-3.4.6 / avr-libc-1.4.6 を利用する場合、gccに利用デバイスを追加するpatchが必要です。"真似して足す"のが簡単なので、gcc-3.4.6/gcc/config/avr/ の下にある avr.c avr.h t-avr に gcc-4.0.4あたりのソースを参考にしながら利用したいデバイスを追加します。binutils / avr-libc はこのバージョンではこのままATtiny2313もatmega48も利用可能です。gccをコンパイルしたのち、必ずavr-libcもコンパイルし直します。所望のデバイスが利用可能かどうかは、avr-gccをインストールしたディレクトリ(/usr/local/avr-gcc3/avr/lib, うちの場合)下に、リンカがリンクするオブジェクトファイルが存在するかどうかを調べます。たとえば、ATtiny2313の場合は、crttn2313.o が、ATmega48の場合はこの階層のさらにひとつ下 avr4/ に crtm48.o が正しくコンパイルさせていれば存在します。

で、gcc-3.xとgcc-4.xを比べた結果ですが、やはりgcc-4.xの方が5%程度おおきく仕上ります。下の比較はUSBaspのソースをatmega48でコンパイルしたものです。
10200 9月 6 23:18 main.hex_3.4.6
10683 9月 7 07:52 main.hex-4.0.4

2007年9月6日木曜日

スクラッチからAVR-GCC構築中 on Linux (その2)

前回、binutil / gcc-core / avr-libc の使っているバージョンを書くのを忘れてしまいました。各々 binutils-2.18 / gcc-core-3.4.6 / avr-libc-1.4.6 です。これらの組合せでavr-gccをFC4の上に構築できますが、ATtiny2313がサポートされていないのは前回書いた通りで、原因はgcc-core-3.x以前のavr.cにはATtiny2313が定義されていないためです。gcc-core-4.x以降ではその部分は以下のようになってます。

(gcc-4.2.1の場合)
static const struct mcu_type_s avr_mcu_types[] = {
/* Classic, <= 8K. */
{ "avr2", ARCH_AVR2, NULL },
{ "at90s2313", ARCH_AVR2, "__AVR_AT90S2313__" },

-- snip --

/* Classic + MOVW, <= 8K. */
{ "avr25", ARCH_AVR25, NULL },
{ "attiny13", ARCH_AVR25, "__AVR_ATtiny13__" },
{ "attiny2313", ARCH_AVR25, "__AVR_ATtiny2313__" },


ほかにも

/* List of all known AVR MCU types - if updated, it has to be kept
in sync in several places (FIXME: is there a better way?):
- here
- avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
- t-avr (MULTILIB_MATCHES)
- gas/config/tc-avr.c
- avr-libc */

と書かれているので、このあたりの変更が必要のようです。パッチを探しているのですがmcuの追加だけのパッチは今のところ見つかっていないのでリスク覚悟で"手直し"かもしれません。WinAVRのgcc-3.xバージョンでもATtiny2313はサポートされていないのだろうか? ネット検索してもそんな話題がひっかからないのでおそらくサポートされているんでしょう。

gcc-3.4.6とgcc-4.0.4でavr-gccを作ってみたので、ATtiny2313ではありませんがATmega8でコンパイルして違いを比較してみました。ものは、USBaspのソースです。出来上がりは、

10155 9月 4 05:32 main.hex_3.4.6
10638 9月 6 06:06 main.hex_4.0.4

位の差が出ました。ATtiny2313のようにROM容量の少ないデバイスには5%の差が大きくのしかかる状況も出て来るかも知れません。さて、この先どうしましょう、、、悩ましいところです。

2007年9月5日水曜日

DS18B20-PAR と DS2417





ダラスマキシム社が出している1-wireのDigital ThermometerとTime Chipです。ATtiny2313のファームをアセンブラで書いている最中です。
参考サイトはこちら↓。
http://frank.bol.ucla.edu/index.htm

スクラッチからAVR-GCC構築中 on Linux

現在スクラッチからAVR-GCCをLinux(Fedra Core 4)で構築中です。一通りbinutil / gcc-core / avr-lib などのコンパイルが終了しました。 が、問題発生。主力のATtiny2313がavr-gccでコンパイルできません。unknown deviceと言われてしまいます。 現在原因調査中。 今のところ分かっているのはどうやらgcc-coreに使えるデバイスを増やすパッチを当ててコンパイルする必要があるらしい、事です。

電子工作あれこれ

ハードウェア、ソフトウェアについてチマチマと書き貯めていこうと思っています。
最近の自分的流行はAtmel AVRを使っての"いろんなモノ"作りです。
工作の過程で知り得た知識なども残していきます。

++ Myself ++

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