So-net無料ブログ作成
検索選択

データの最後を判定 [AVR]

フラッシュROMにデータを置いて読むでは変数をインクリメントしていって
あらかじめわかっているデータの長さになれば最後だと判断してました。

データの長さがわかっているならzレジスタの指すアドレス
データの最後のアドレスを比較して同じなら最後だと判定すれば
よいと思ったのですが、方法がわからずモヤモヤしていました。

そこで発見したのがこのサイト
とても勉強になります。そしてなんといってもコードが美しい!!(と初心者の私にもわかるほど)
その中のLessonA0でまさに
データの最後のアドレス比較をしていました。なるほど!そうやるのか!

まずはこの様にデータの後にラベルをつける
データの個数は偶数個
LEDDATA: .db データ...
LEDDATAEND:

これまで同様にzレジスタにデータの先頭アドレスセット
ldi zl,low(LEDDATA<<1)
ldi zh,high(LEDDATA<<1)
ldi r16,low(LEDDATA)

読み出し方も同じ
lpm r18, z+

判定はデータの最後のラベルの下位と上位アドレスを上でやったのと
同じ方法でビットシフトしてzl,zhと比較しします。
同じならデータの最後を読んだと判定しています。

cpi zl, low(LEDDATAEND<<1) ; 下位アドレス比較
brne somewhere ; どこかへジャンプ
cpi zh, high(LEDDATAEND<<1) ; 上位アドレス比較
brne somewhere ; どこかへジャンプ
ここまできたら終わり


これにより、カウンタ用のレジスタを使わなくて済みますが、
これはスペース(レジスタ)と時間(判定のための4行分の処理時間)のトレードオフです。
このご時勢にスペースたくさんあるのでケチケチすべきではありません(たぶん)。

それよりも何がうれしいかは、データの長さを変えてもコードが同じになること
だと思います。あと可読性もよい気がします。

"フラッシュROMにデータを置いて読む"を書き直したら次のようになりました。

.include "m168def.inc"
                                
.org 	0x0000		jmp	reset 	;各種リセット

reset:		ldi	r16, low(ramend)
			out	spl, r16
			ldi	r16, high(ramend)
			out	sph, r16

			ldi r16, 0x00
			out ddrd, r16	; d input
			ldi r16, 0xff
			out ddrb, r16	; b output
			out portb, r16

main:		ldi	zl,low(LEDDATA<<1)
			ldi	zh,high(LEDDATA<<1)

main1:		lpm	r18, z+

main2:		rcall delay1ms
			in	r16,pind
			cpi	r16,0b1111_1110
			brne main2
			out	portb,r18
main3:		rcall delay1ms
			in	r16,pind
			cpi	r16,0b1111_1111
			brne main3

			; check more data left
			cpi zl, low(LEDDATAEND<<1)
			brne main1
			cpi zh, high(LEDDATAEND<<1)
			brne main1
			rjmp main

LEDDATA:	.db 0x00,0x01
			.db 0x02,0x04
			.db 0x08,0x10
			.db 0x20,0x40
			.db 0x80,0xFF
LEDDATAEND:

delay1ms:	push r16
			in r16,sreg
			push r16
			push r17
;			100000-10=99990
			ldi r17,198
delay2:		ldi r16,100
delay1:		dec r16
			nop
			cpi r16,0
			brne delay1
			dec r17
			cpi r17,0
			brne delay2
;			999990-(100*5+4)*198=198
			ldi r16,46
delay3:		dec r16
			cpi r16,0
			brne delay3
;			198-46*4=14
			nop
			nop
			nop
			pop r17
			pop r16
			out sreg,r16
			pop r16
			ret

nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:パソコン・インターネット

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この記事のトラックバックURL:

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。