Hallo, ich möchte in meinem AVR Assembler Programm eine Dezimalzahl (bis 255, als Byte abgespeichert) auf meinem Display ausgeben. Dazu muss ich die Zahl erst als ASCII-Wert haben. Wie konvertiere ich das? Ich habe schon einige Einträge hier im Forum gelesen zu ähnlichen Problemen, eine Antwort und eine konkrete Routine zur Umwandlung (Sourcecode) habe ich allerdings nicht gefunden. Vielen Dank! Anna
Ich meine, das habe ich hier schon mal reingestellt, ist für 16Bit , also 2 Byte. Da die Wandlung von rechts nach links erfolgen muß, aber die Ausgabe von links nach rechts, wird auf dem Stack zwischengespeichert: ;*********************************************************************** ** ;* subroutine: convert 16bit-word -> decimal -> ASCII -> output ;*********************************************************************** ** DecOut: rcall Div10 ; get "ones" digit ori Temp1,$30 ; convert to ASCII push Temp1 ; and save it rcall Div10 ; get "tens" digit ori Temp1,$30 ; convert to ASCII push Temp1 ; and save it rcall Div10 ; get "hundreds" digit ori Temp1,$30 ; convert to ASCII push Temp1 ; and save it rcall Div10 ; get "thousands" digit tst Temp1 ; omit leading zero breq DecOu1 ; ori Temp1,$30 ; convert to ASCII rcall Serout ; print thousands DecOu1: pop Temp1 ; fetch hundreds rcall Serout ; and print it pop Temp1 ; fetch tens rcall Serout ; and print it pop Temp1 ; fetch ones rcall Serout ; and print it ret ; ;*********************************************************************** ** ;* subroutine: divide 16bit word in TempH/TempL by 10, ;* results: quotient in TempH/TempL, remainder in Temp1 = decimal digit ;* taken from "Trampert, AVR-RISC-Mikrocontroller" ;* Franzis-Verlag www.franzis.de ISBN 3772354742 pg. 327 ;*********************************************************************** ** Div10: push Cnt ; clr Temp1 ; lsl TempL ; input word is shifted out to the left rol TempH ; filled up with zeroes from the right rol Temp1 ; lsl TempL ; rol TempH ; most significant 3 bits are always < 10 rol Temp1 ; so just shift out and in via Cy 3 times lsl TempL ; rol TempH ; rol Temp1 ; ldi Cnt,13 ; start loop for next 13 bits Div10a: lsl TempL ; rol TempH ; rol Temp1 ; subi Temp1,10 ; remainder >10 ? -> subtract 10 brlo Div10b ; was <10, LSB of output word = 0 inc TempL ; LSB of output word = 1 rjmp Div10c Div10b: subi Temp1,-10 ; back to old value <10 Div10c: dec Cnt ; next bit brne Div10a ; pop Cnt ; ret ;
theoretisch geht das so: du pickst dir mit div und mod die einzelnen Stellen raus, und addierst dann jeweils $65 dazu, weil die Zahlen im ASCII-Code um diesen Betrag nach hinten verschoben sind, den Fernschreibern sei Dank...
nicht $65 sondern dezimal 64 = $30 Ziffern 0 bis 9 = Ascii $30..$39
Hallo! Vielen Dank für die schnellen Antworten! @Christoph: Ich werde die Routine mal ausprobieren. Daraus eine 8-Bit -> ASCII Konvertierung zu machen, sollte ja nicht so das Problem sein. Vielen Dank! @Uwe: div und mod gibt es doch im Assembler gar nicht, oder? Diese Routinen müsste ich ja dann auch erst einmal extra selbst schreiben. Anna
Mit einer 3-Digit-Zerlegung mittels Schleifen und einfacher Subtraktion zu je 100, 10 und 1 (also Division durch entsprechende Anzahl Subtrraktionen) plus einer entsprechenden Addition der $30 geht das Ganze noch viel codesparender, gerade wenn´s nur ein Byte ist.
Oder so: http://www.mikrocontroller.net/forum/read-1-324465.html#324832 (2 Mausklicks entfernt...) ...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.