Witam Mam takie pytanko: w jaki sposob najprosciej i najszybciej w asemblerze zamienic liczbe 16bitowa na liczbe dziesietna? Mam wynik z przetwornika (2*8bitow) i chcialbym wyrzucic na wyswietlacz liczbe odpowiadajaca tej wartosci binarnej. Dzieki za pomoc Krzysiek
ATMega8 + asembler
May 06, 2004
11 Replies
Tutaj masz algorytm konwersji bin->spakowane bcd.
formatting link
wypakowaæ ka¿d± cyfrê, dodac kod ascii zera i wyrzuciæ na wy¶wietlacz.
oczywi¶cie je¶li mówimy o wy¶wietlaczu lcd.
Tak chodzi mi o wyswietlacz LCD
zaczalem robic wedlug tego pdfa :
.def tmp=r19 .def L1=r13 .def L2=r14 .def L3=r15 .def DanaLSB=r16 ;mlodszy bajt liczby ktora chce zamienic .def DanaMSB=r17 ;starszy bajt tej liczby .def count=r18
ldi count,0x10 clr r13 clr r14 clr r15
lop: LsL DanaLSB RoL DanaMSB RoL L1 RoL L2 RoL L3 dec count breq end
ale doszedlem dotad i nie za bardzo wiem co dalej.. gdybys mogl podpowiedziec bylbym wdzieczny
DZieki za pomoc Krzysiek
Nie wiem skad to mam ale moze pomoze ;-) Nie sprawdzalem czy dziala ale pewnie tak.
;-----------------------------------------------------------------------------; ; Universal decimal string conversion (8/16 bit unsigned) ; ; Register Variables: ; Call: var1:0 = 16 bit value to be converted ; len = String length ; tmp1:0 = <Don't care> (high register must be assigned) ; tmp2 = <Don't care>
; ; Result: var1:0 = <Unknown>
; len = <Not changed>
; tmp1:0 = <Unknown>
; tmp2 = 0 ; ; Size: 30 words ; Clock: depends on output routine ; Stack: 10 bytes max (+output routine) ; ; Examples: var1 len output ; 100 0 "100" ; 1234 0 "1234" ; 0 7 " 0" ; 100 5 " 100" ; 100 2 "100"
mk_decu8: clr var1 ;8 bit entry mk_decu16: ;16 bit entry clr tmp2 ;digit counter inc tmp2 ;---- decimal string generating loop clr tmp0 ;var1 /= 10; ldi tmp1,16 ; lsl var0 ; rol var1 ; rol tmp0 ; cpi tmp0,10 ; brcs PC+3 ; subi tmp0,10 ; inc var0 ; dec tmp1 ; brne PC-8 ;/ subi tmp0,-'0' ;Push the remander (a decimal digit) push tmp0 ;/ cp var0,tmp1 ;if(var =! 0) cpc var1,tmp1 ; continue digit loop; brne PC-16 ;/ cp tmp2,len ;Adjust string length (this can be removed for auto-length) brcc PC+5 ; inc tmp2 ; ldi var0,' ' ; push var0 ; rjmp PC-5 ;/ pop var0 ;Put decimal string rcall xmit ;<-- Put a char (var0) to memory, console or any display device dec tmp2 ; brne PC-3 ;/ ret
Pewnego dnia Krzy$ przemówił ludzkim głosem:
No to może zacznę od początku. W nocie masz opisany algorytm konwersji, ale nie musisz go sam implementować. Możesz ściągnąć gotową funkcję ze strony atmela, albo jeśli masz zainstalowane avrstudio to znajdziesz ją w pliku avr204.asm.
Konwersję wywołujesz tak:
ldi fbinL,low(12345) ; 12345 to przykładowa liczba ldi fbinH,high(12345) rcall Bin2BCD16 ; tu wywołujesz konwersję
teraz trzeba rozpakować liczby po konwersji, dodać do każdej kod ascii 0
Najpierw wysyłasz najstarszą cyfrę:
ldi temp,'0' ; add temp,tBCD2 rcall WyslijNaLCD ;
Potem 2 i 3 w kolejności:
mov temp,tBCD1 swap temp ; zamien polowy bajtow andi temp,$0f ; zostaw tylko połówkę subi temp,(-'0') ; dodaj kod ascii 0 rcall WyslijNaLCD mov temp,tBCD1 ; to samo dla młodszej tetrady andi temp,$0f subi temp,(-'0') rcall WyslijNaLCD
Dla cyfry 4 i 5 blok jest identyczny jak dla 2 i 3, musisz tylko zmienić tBCD1 na tBCD0.
Ale jezeli ja mam taka sytuacje ze odbieram z przetwornika wartosc 16bitowa jest ona zapisana jako dodeb1 - (MSB) i dodeb2 - (LSB) to jak mam uzyc tej funkcji?? wpisalem tak:
.include"avr204.asm" ; zalaczylem mu ten plik z tym ze zmienilem w nim .include "8515def.inc" na .include "m8def.inc" .... ldi fbinL,low(dodeb2) ; przy kompilacji wywala mi tu blad: "undefined variable referenced" ldi fbinH,high(dodeb1) ;przy kompilacji wywala mi tu blad: "undefined variable referenced" rcall Bin2BCD16 ;
ldi dana,'0' ; add dana,tBCD2 rcall dana_lcd
mov dana,tBCD1 swap dana ; zamien polowy bajtow andi dana,$0f ; zostaw tylko po³ówkê subi dana,(-'0') ; dodaj kod ascii 0 rcall dana_lcd mov dana,tBCD1 ; to samo dla m³odszej tetrady andi dana,$0f subi dana,(-'0') rcall dana_lcd ;wyslij na lcd
mov dana,tBCD0 swap dana ; zamien polowy bajtow andi dana,$0f ; zostaw tylko po³ówkê subi dana,(-'0') ; dodaj kod ascii 0 rcall dana_lcd mov dana,tBCD0 ; to samo dla m³odszej tetrady andi dana,$0f subi dana,(-'0') rcall dana_lcd ;wyslij na lcd
Co tu jest jeszcze zle?? Dzieki za pomoc Krzysiek
Pewnego dnia Krzy$ przemówił ludzkim głosem:
Ja bym wywalił low i high (bo to jest makro które dzieli liczbę ma młodszy i starszy bajt). A jak masz zadeklarowane dodeb1 i 2 ?
uruchom to w debugerze, wpisz jakieś wartości do dedeb i sprawdź czy działa.
Pewnego dnia Zbych przemówił ludzkim głosem:
i jeszcze jedno, jeśli dodeb to komórki pamięci, to użyj mov zamiast ldi.
Dodeb1 i dodeb2 sa to rejestry zdefiniowane: .def dodeb1=r21 .def dodeb2=r22
Hmm czyli jak to powinno wygladac, bo juz nie mam pomyslow??
Pewnego dnia Krzy$ przemówił ludzkim głosem:
mov fbinL,dodeb2 mov fbinH,dodeb1 rcall Bin2BCD16
Ok juz wszystko dziala Dzieki za pomoc! Krzysiek
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required