最近アセンブリの勉強をはじめまして、ちまちまとやっとるワケです。はい。
あ、そうそう、
アセンブリ:言語の名前
アセンブラ:コンパイルするやつ
アセンブル:コンパイルすること
らしいです。
で、試しに書いてみたそーす。
そーす
1.include "m64def.inc"
2.def unset = R16
3.def set = R17
4.def led = R18
5.CSEG
6 ldi unset,0x00
7 ldi set,0xFF
8 out DDRA,unset
9 out DDRD,set
10 out PORTA,set
11 out PORTD,unset
12LOOP:
13 in led,PINA
14 lsl led
15 com led
16 out PORTD,led
17 jmp LOOP
18
みたいな感じです。あっ、左の数字は行数です。
ちなみに環境構築はこちら(top)「のぅわべたぁ」様、こちら(top)「AVR使用記-kuman」様を参考にさせて頂きました。
上のソースの回路は、マイコンはATmega64、PINAにはスイッチを負論理で接続、PORTDにはLEDを接続しています。動作としてはPORTAに接続された負論理スイッチが押されたら1bitシフトしてbit反転してLEDに出力するっつーやつです。こんな説明で分かるのかなぁ(爆)
もうちょい真面目に解説すると、
1行目:ATmega64の定義ファイル取り込み
2行目:R16レジスタの名前をunsetに設定。
3行目:R17レジスタの名前をsetに設定。
4行目:R18レジスタの名前をledに設定。
2~4行目はプログラムかじったことのある人なら分かると思いますが、define、つまり設定とか言いつつただの置換です。
5行目:.CSEG
AVRプログラムはこの「.CSEG」の行から始まります。
6行目:ldiという命令で0x00という定数をunsetと設定した(?)レジスタ = R16レジスタに代入。
7行目:同じく0xFFという定数をsetと設定したレジスタ = R17レジスタに代入。
8行目:DDRAレジスタにunsetの中身(=0x00)を代入。
9行目:DDRDレジスタにsetの中身(=0xFF)を代入。
10行目:PORTAレジスタにsetの中身(=0xFF)を代入。
11行目:PORTDレジスタにunsetの中身(=0x00)を代入。
6~11行目でなぜDDRやPORTのレジスタに定数を直接代入しないかというと、「できないから」なんです。
で、6、7行目の代入と8~11行目の代入で別の命令を使っていますが、後述します。
12行目:LOOP:
ここでは「ラベル」を設定しています。C言語のgoto文をご存知なら、分かると思いますが、あれと一緒と考えて大丈夫だと思います。17行目の記述と関係してくるので、詳しくはそっちで。。。
13行目:PINAレジスタの中身をledと設定したレジスタ(=R18レジスタ)に代入。
14行目:lsl命令でledレジスタを1bit左にシフトしたものを求め、ledレジスタに再び代入。
15行目:com命令でledレジスタの1の補数(=bit反転したもの)を求め、ledレジスタに代入。
16行目:PORTDレジスタにledレジスタの中身を代入。
13~16行目がこのプログラムのメインです。ここで「負論理接続のスイッチが押されたら1bitシフトして反転したものを出力」しています。
17行目:jmp LOOP LOOPラベルのある部分(12行目)まで移動してプログラム続行(無限ループ)
ちなみに、手軽にアセンブルできるようにmakeファイル書いたんでついでに載せときます。
こっちの説明はめんどいんで割愛で。
1PROJECT=test
2#--------
3all:
4 avra $(PROJECT).asm
5
6clean:
7 rm $(PROJECT).cof $(PROJECT).eep.hex $(PROJECT).hex $(PROJECT).obj
8
9flash:
10 avrdude -p m64 -c avrispmkII -P usb -e
11 avrdude -p m64 -c avrispmkII -P usb -U flash:w:$(PROJECT).hex -F
12
13.PHONY: all clean
でわでわ
0 件のコメント:
コメントを投稿