AVRは、Atmel社(http://www.atmel.com/)が、 作成している8bit RISC Flash Microcontrolerです。 プログラム用には1000回の書き込み保証のあるフラッシュメモリが搭載され、 データ用に10万回の書き込み保証のあるEEPROMが内蔵されています。 32本の8ビット汎用レジスタを持ち、 入出力に利用可能なパラレルポートがチップによって 3本から48本の範囲で用意されています。 このポートは5VでLEDを直接点灯できる能力があるものです。 チップによってはA-Dコンバータも用意されていますので、 かなり高度な処理が可能ということが分かって頂けると思います。 また、基本的にプログラムはシリーズ全てで互換性があります [1] ので、 コストやプログラムの規模に見合ったチップを利用することができます。 各チップの機能概要については http://www.atmel.com/atmel/products/prod199.htmを 参照してください。
AVRのためのプログラムライタにはいろいろなものがあります。 代表的なものは以下の通りです。
秋葉原の秋月電子通商 (http://www.akizuki.ne.jp/) の、Windows用の開発キット (Figure 1)。 定価8950円。 12V駆動。 シリアルポート経由の書き込みを行う。 書き込みを行うためにAVRを使っており、 このプログラム自身はAtmelのサイトなどから入手可能 [2]。 また、FreeBSDやLinuxで利用できるライタとしては akiavr (http://members.jcom.home.ne.jp/pnms/akiavr.html) があります。
Atmelの純正キット。 若干高価。
パラレルからの出力を直接書き込むもの。 DOSコマンドが提供されており、Windowsでも利用可能。 回路は一番簡単。 給電もパラレルを利用するが、ノートパソコンなどで不具合が 起きる可能性があり。
avrprog(後述)が仮定している回路。 Brian Dean氏によるものは一つ前の項目と同じもの。 パラレルを利用しており比較的簡単な回路。 1000円程度で製作可能。 給電はパラレルを利用するが、ノートパソコンなどで不具合が 起きる可能性があり。 この場合、5Vの外部電源を供給する必要がある。
最近になってFreeBSD portsに、devel/avr*という 開発環境が入りました。 devel/avrprogはライター用のプログラムで、 簡単な回路を作成することで、 パラレルポートからプログラムの書き込みや消去が可能になります。 また、devel/avr-binutilsをつかうことで、 アセンブラのプログラムやIntel HEXフォーマットへの変換が可能です。 devel/avr-gccとdevel/avr-libcを 利用することで、 C言語での開発も可能になっています。
今回は、AVRを題材にして、 アセンブラでプログラムを作成することを目標にします。 この時、できるだけお手軽に遊んでみることを目標にしますので、 portsなどあるものは使ってしまいます。
クロス開発環境の製作に興味のある方は、 内川さんの記事の方も是非参照してください。
AVRの情報としては、最近出版された教科書[1]が、 まずあげられます。 CPU毎の特徴や命令一覧も含まれていますし、 応用回路もたくさん含まれていますので、是非手元に置いてください。
もう少し前の記事としてはトランジスタ技術の特集[2] があります。 こちらは命令などが一覧できる表でまとまっており、 大体の命令の内容が分かっている場合には便利でしょう。 また、PICも特集に含まれていますので、 両方に興味がある人が概要をつかむにはよいでしょう。
Web上のリソースとしては、 まずはAtmel社(http://www.atmel.com/)のページが 大変参考になります。 PDFなどの形で仕様などを手にいれることができます。 2001年12月末現在の構成では、トップページから[Flash Microcontroller]、 [AVR 8-Bit RISC]でAVR関連の情報のページにたどり着けます。 [DataSheets]で仕様書が、 [Application Notes]にはAVRを用いた応用回路の説明が手に入ります [3]。 応用回路にはかなり面白いものも含まれていますので、 いちど覗いてみてください。 これらのドキュメントのウチ、仕様書などの一部の日本語訳は レディオテクニカ(http://homepage1.nifty.com/radio_tech/)から たどれるリンクで入手可能です。
日本語としてまとまったWebページとしては まろりさんの「AVRに関するページ」 (http://ww2.tiki.ne.jp/~maro/AVR/)が 仕様などの詳細をわかりやすくまとめてあり、良いでしょう。 今回説明しなかった、avr-libcを使ったプログラミングについても まとまっています。 devel/avr-gccに関しては更に、 http://www.enteract.com/~rneswold/avr/chexample.htmlの ドキュメントも一読をお勧めします [4]。
FreeBSDに特化した情報は、 avrprogに関しては http://www.bsdhome.com/avrprog/を参照してください。 あとは、各ツールのマニュアルや付属ドキュメントを参照してください。
avrprogが仮定している回路は、前述の http://www.bsdhome.com/avrprog/で見ることができます。 また、devel/avrprogをインストールすることで、 /usr/local/share/doc/avrprog/avrprog.pdfにも、 いわゆる「Tony Friebel氏の回路」(Figure 2)がインストールされます。 ZIFソケットを使わなければ、両者とも1000円もあれば作成できますので、 自分で部品を買って来て作成することをお勧めします。
「Tony Friebel氏の回路」で、6ピンの謎のジャンパーがあるのですが、 これはIN-SYSTEM-PROGRAMMER用のものなので、 ライターとしての用途だけには必要ありません。
どちらの回路を作っても、avrprogは対応していますので、 好きな方を作ればいいでしょう。 私は、回路図があると言う理由で「Tony Friebel氏の回路」を作成しました。
両者の回路とも、パラレルポートから電源を取る形になっていますが、 ノートパソコンの一部ではこれが不可能な場合があります。 この場合、外付の電源(5V)を用意してやる必要があります。 手元ではアルカリ乾電池4本(6V)の電源でも動作しました。
ライター用のソフトウエアavrprogは、 パラレルポートを利用して、書き込みを行うプログラムです。 プログラムの書き込みに必要な結線はそれほど多くないため、 シンプルにしようと思えばとことんシンプルに作成することも可能です。
avrprogでは、 設定ファイル/usr/local/etc/avrprog.confに 結線などの情報を書くことで、自分で設計した回路での利用も可能です。 デフォルトは前述のページの最もシンプルな回路になっていますが、 Tony Friebelの回路もコマンドラインオプションで指定可能ですし、 デフォルトの変更のために設定ファイルを変更することも可能です。
詳細な情報はman avrprogを参照してください。 コマンドラインオプションをTable 1にまとめておきます。
Table 1. avrprogのコマンドラインオプション
オプション | 値 | 意味 | 備考 |
---|---|---|---|
-p | 1200(AT90S1200)| 2313(AT90S2313)| 2333(AT90S2333)| 4433(AT90S4433)| 4434(AT90S4434)| 8515(AT90S8515)| 8535(AT90S8535)| 103(ATMEGA103) | CPUモデル指定 | 指定必須 |
-c | bsd(default)|dt006|alf | ライターID | avrprog.confを参照 |
-C | 設定ファイル名 | 標準とは異なる設定ファイルを指定する | |
-e | チップの内容を消去 | プログラム書き込み前には必須 | |
-f | i [a] |s [b] |r [c] |a [d] | 転送フォーマット | |
-F | デバイスシグネチャを無視して処理 | ||
-i | filename | 転送するファイルを指定 | |
-m | eeprom|flash | 書き込むプログラムエリアを指定 | |
-n | 書き込まない(デバッグ用) | ||
-o | filename | 結果を出力するファイル指定 | |
-P | パラレルポートのデバイスファイル名 | デフォルトの/dev/ppi0以外のポートを指定 | |
-t | ターミナルモードへ | 詳しいコマンドはhelpやman avrprogを参照 | |
Notes: a. Intel HEX フォーマット b. Motorola S-record c. rawバイナリ(リトルエンジアン) d. 自動検出(デフォルト) |
パラレルポート/dev/ppi0のパーミッションがユーザが 利用可能になっていないと、もちろんavrprogは動作できません。 また、lpdがパラレルを握っていないようにすることも 注意してください。 標準ではパーミッションが
crw------- 1 root wheel 82, 0 6/22 2000 /dev/ppi0となっていますので、グループのrw権限をつけてwheelに自分を登録するか、 オーナやグループを変更するか、 sudo経由で実行することになるでしょう。
注意する点は、プログラムを書き込む前に
-e
を利用して消去を行っておく必要があることです。
さて、ここでは実際にプログラミングしてみましょう。 アセンブラによるプログラミングにはdevel/avr-binutils だけあれば十分です。 AVR用のアセンブラなどには、avr-というプレフィックスが つきますので、注意してください。
今回のプログラム作成に利用するコマンドをTable 2にまとめました。
Table 2. 今回利用するコマンド
コマンド名 | 機能 | 備考 |
---|---|---|
avr-as | アセンブラ | 命令はAVR Instruction Setを参照 |
avr-objcopy | フォーマット変換 | Intel HEXフォーマットやMotorola S-recordへの変換 |
avr-objdump | オブジェクトファイルの情報表示 | 逆アセンブラとして利用可能 |
今回の回路で利用するチップはAT90S1200Aです。 このチップにはクロック発振器が内蔵されています [5] ので、 電源(3-6V程度) [6] と抵抗、LEDがあればいわゆるKnight2000のような、 LEDを左右に点滅させる回路を構成することが可能です。 回路図をFigure 4に示します。
プログラムをFigure 6に示します。 これを作成するためのMakefileを Figure 7に示します。
Figure 6. LEDを点滅させる回路(Knight2000風):led.s
/* 定数の定義 */ .equ DDRB, 0x17 /* PortB 入出力指定レジスタ */ .equ PORTB, 0x18 /* PortB データ用レジスタ */ .equ LOOP, 100 /* タイマ用空ループ回数:3Vで適当な値 */ /* 割り込みベクトルの初期化 */ rjmp reset reti reti reti /* r18: 一時変数 */ /* r19: LEDの点灯方向 右=-1(LSB方向) , 左=1(MSB方向) */ reset: /* PortB を全て出力モードとして設定 */ ldi r18,0xff out DDRB,r18 ldi r18,0x01 /* ここ以降r18は出力データとして使う */ ldi r19,0x01 /* 左(MSB)方向への移動から開始 */ /*** メインループ ***/ top_loop: out PORTB,r18 /* 方向を確認して分岐 */ tst r19 brmi left /* マイナスならばleft:へ */ right: ror r18 /* キャリーフラグを含めた右rotate */ rjmp common left: rol r18 /* キャリーフラグを含めた左rotate */ rjmp common common: rcall timer /* 出力が0になったら方向を変える */ tst r18 brne top_loop /* ゼロでない限りはtop_loop:へ */ neg r19 rjmp top_loop /*** タイマーサブルーチン ***/ timer: ldi r16,LOOP loop: nop nop dec r16 brne loop ret
Figure 7. led.sを作成するためのMakefile
# Variables TARGET_CPU=at90s1200 HEX_FORMAT=ihex TARGET=led.hex # Common rules .SUFFIXES: .hex .o .s all: $(TARGET) write:: avrprog -p 1200 -c alf -e avrprog -p 1200 -c alf -i led.hex .o.hex: $(.IMPSRC) avr-objcopy -O $(HEX_FORMAT) $(.IMPSRC) $(.TARGET) .s.o: $(.IMPSRC) avr-as -mmcu=$(TARGET_CPU) -o $(.TARGET) $(.IMPSRC) clean: rm -f *.o *.hex *~
書き込みは、以下のような手順で行います。
> avrprog -p 1200 -c alf -e avrprog: AVR device initialized and ready to accept instructions avrprog: Device signature = 0x1e9001 avrprog: erasing chip avrprog: done. avrprog done. Thank you. > avrprog -p 1200 -c alf -i led.hex avrprog: AVR device initialized and ready to accept instructions avrprog: Device signature = 0x1e9001 avrprog: reading input file "led.hex" avrprog: input file led.hex auto detected as Intel Hex avrprog: writing flash: 48 0xe1 avrprog: 52 bytes of flash written avrprog: verifying flash memory against led.hex: avrprog: reading on-chip flash data: 48 0xe1 avrprog: verifying ... avrprog: 52 bytes of flash verified avrprog done. Thank you.ちなみに、Figure 7には、 make writeで これらのコマンドを実行するターゲットを登録してあります。
今回は基板の作成からアセンブラを使ったプログラミングまでを説明しました。 楽しみのためにアセンブラを使ったのは10数年ぶり [7] なんですが、 結果が目に見えるので非常に楽しかったです。
libcを使ったプログラミングまで書けなかったことが残念です。 いずれ、稿を改めて書きたいと思います。 他にもAVRに関して取り上げて欲しい事などがありましたら、 編集部まで御連絡ください。
今回の記事を書くにあたって、 奈良工業高等専門学校からくり同好会の藤田さんには さまざまな情報を提供頂き、査読していただきました [8]。 devel/avrprogの制作者でありMAINTAINERのBrian Dean氏と devel/avr-*MAINTAINERのJoerg Wunsch氏には 有用な情報提供を頂きました。 また、Tony Friebel氏は回路のオリジナル作者で、 この回路図はJoerg Wunsch氏によって描かれています。 ここに、感謝させて頂きます。
Special thanks to:
Brian Dean, he programmed avrtools,
Joerg Wunsch, he is the MAINTAINER for devel/avr-* and draw the schematic circuit of Tony Friebel's circuit ,
and Tony Friebel, he made original Tony Friebel's circuit.
[1] | もちろん、存在しない入出力に対する操作は意味を持ちませんし、 それに対応している命令は用意されていませんので、 完全に互換性があるわけではありません。 |
[2] | ただし、このプログラムを書き込むためには、 先にライタが必要になります。 |
[3] | [Software]にはWindows用のSoftwareなどもありますが、 必要ないでしょう(^-^;) |
[4] | 2002年1月8日現在で、avr-libc付属のドキュメントよりも こちらの方が新しいので、こちらを参照しましょう。 インストール部分に誤りがあるそうですが、 portsを使うのならば関係ありません;-) |
[5] | Aの付かないAT90S1200もクロックが内蔵されているのですが、 工場出荷時点では外部クロックを利用する設定になっています。 これの変更にはヒューズビットの書き換えが必要なため、 今回は、若干高価ですがAT90S1200Aをターゲットにしています。 |
[6] | 電源電圧で内部クロックの周波数は変わりますので、 クロックを仮定してプログラムを作る場合は、 外部クロックを利用するべきです。 |
[7] | PC-9801vm21でVRAMを反転させて遊んで以来… |
[8] | また、遊びましょう;-) |