Hallo, stehe aktuell vor folgendem Problem und zwar habe ich 16bit Werte, welche ich direkt auf einem LCD in dezimaler Schreibweise ausgeben möchte. Welche Möglichkeiten hab ich denn? Zuerst umwandeln von Dual nach BCD und dann in ASCII oder gibts noch einfachere Methoden? danke einstweilen, Peter
Das wird schon die einzige Möglichkeit sein. Hier mein Assemblertext dazu: ;*********************************************************************** ** ;* subroutine: convert 16bit-word -> decimal -> ASCII -> plot HPGL ;*********************************************************************** ** 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 ;
Beispiel in C: unsigned int Wert = 12453; unsigned char s[6]; unsigned char n, x = 0; unsigned int vergleichswert = 10000; while (vergleichswert>0) { n = 0; while (Wert>vergleichswert) { Wert -= vergleichswert; n++; } if ((n>0) || (x>0)) { s[x]= '0'+n; x++; } vergleichswert %= 10; } Das gilt natürlich nur für positive ganze Zahlen. Dann gibt es als einfache Methoden noch "atoi", "sprintf", "printf"...
Für etwaige Fehler wird keine Haftung übernommen (dafür gibt es Haftcreme...)
>Das wird schon die einzige Möglichkeit sein. >Nein. Das "Nein" stimmt schon im Zusammenhang mit "einzige".
@Micha > > Nein. > Sehr sehr informativ. Es war die direkte Antwort auf die Frage. Ist das falsch? Der Fragesteller hat ja die Lösung des Problems bereits genannt. Ausserdem gibts zu dem Thema tonnenweise Threads, einfach mal BCD als Sortierbegriff eingeben. MfG Falk
man kann das natürlich auch als Tabelle in ein Eprom brennen oder eine Diodenmatrx löten oder ein CPLD/FPGA damit beschäftigen. Leider fehlt in deiner Frage die Angabe, welcher Prozessor, welche Programmiersprache.
Hier hat einer einen "dirty math trick" um die Division durch 10 zu beschleunigen: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=37150&postdays=0&postorder=asc leider funktioniert die Methode nicht hundertprozentig, eine interessante Diskussionsrunde. Weitere AVR-Routinen hier: http://avr-asm.tripod.com/index.html
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.