Forum: Mikrocontroller und Digitale Elektronik Dezimal -> ASCII konvertieren in AVR Assembler


von Anna F. (Gast)


Lesenswert?

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

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

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      ;

von Uwe Große-Wortmann (Gast)


Lesenswert?

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...

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

nicht $65 sondern dezimal 64 = $30
Ziffern 0 bis 9 = Ascii $30..$39

von Anna F. (Gast)


Lesenswert?

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

von TravelRec. (Gast)


Lesenswert?

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.

von Hannes L. (hannes)


Lesenswert?

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
Noch kein Account? Hier anmelden.