まずはアセンブラから

さて、ここでは実際にプログラミングしてみましょう。 アセンブラによるプログラミングにはdevel/avr-binutils だけあれば十分です。 AVR用のアセンブラなどには、avr-というプレフィックスが つきますので、注意してください。

今回のプログラム作成に利用するコマンドをTable 1-2にまとめました。

Table 1-2. 今回利用するコマンド

コマンド名機能備考
avr-asアセンブラ命令はAVR Instruction Setを参照
avr-objcopyフォーマット変換Intel HEXフォーマットやMotorola S-recordへの変換
avr-objdumpオブジェクトファイルの情報表示逆アセンブラとして利用可能

今回の回路で利用するチップはAT90S1200Aです。 このチップにはクロック発振器が内蔵されています [1] ので、 電源(3-6V程度) [2] と抵抗、LEDがあればいわゆるKnight2000のような、 LEDを左右に点滅させる回路を構成することが可能です。 回路図をFigure 1-4に示します。

Figure 1-4. Knight2000風LED点滅を実現する回路の回路図

Figure 1-5. Knight2000風LED点滅を実現する回路の回路

プログラムをFigure 1-6に示します。 これを作成するためのMakefileFigure 1-7に示します。

Figure 1-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 1-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 1-7には、 make writeで これらのコマンドを実行するターゲットを登録してあります。

Notes

[1]

Aの付かないAT90S1200もクロックが内蔵されているのですが、 工場出荷時点では外部クロックを利用する設定になっています。 これの変更にはヒューズビットの書き換えが必要なため、 今回は、若干高価ですがAT90S1200Aをターゲットにしています。

[2]

電源電圧で内部クロックの周波数は変わりますので、 クロックを仮定してプログラムを作る場合は、 外部クロックを利用するべきです。