Hallo! Ich habe Mir eine Schaltung mit nem LCD aufgebaut, und den code aus dem LCD tut einigermaßen übernommen. Es funktioniert auch alles wunderbar... Doch nun solls ja weiter gehen, ich will eben nicht nur das wort "Test" ausgeben, sondern eventuell verschiedene zahlen die in den registern abgelegt sind. Dies können sowohl einstellige, als auch mehrstellige zahlen sein. Im Tut wurde ja schon erwähnt das es bei großen textausgaben nicht sinnvoll sei, wegen jedem Buchstaben ein "lcd_data" aufzurufen. Vielmehr ist das auch sehr schwer umzusetzen. Wie kann ich nun vorgehen wenn ich zb. einen Taster habe der pro tastendruck eine Zahl (sagen wir Null) inkrementiert. Der Wert soll bis sagen wir 999 hochgezählt werden und dann wieder bei null beginnen. Erste frage: Kann man die Zahlen binär hochzählen und dann jeweils durch 10 teilen und die Nachkommastelle dann in ASCII umwandeln und zum LCD senden? Oder hat jemand eine Idee wie es vernünftiger zu realisieren ist. Ich habe mir da noch nicht soviele Gedanken darüber gemacht. Zweite frage: Wie kann ich es umgehen bei jedem Zeichen die routine "lcd_data" aufzurufen? MfG Manuel
> Kann man die Zahlen binär hochzählen und dann jeweils durch 10 > teilen und die Nachkommastelle dann in ASCII umwandeln und zum LCD > senden? Kann man prinzipiell so machen, ist aber eher umständlich. Wenn Du in C programmierst, ist das recht einfach. In der stdlib.h gibts dafür fertige Funktionen (itoa z.B. erzeugt aus einer Binärzahl (Integer) einen ASCII-String, den man direkt ans LCD senden kann). Wenn Du AVR-GCC-C benutzt, dann schau mal in die Doku der AVR-libc, da ist das beschrieben. itoa(Wert, String, Basis) speichert im String "String" die ASCII-Zeichen für die Integer-Variable "Wert" ab, und zwar dargestellt mit der angegebenen Basis (z.B. Basis = 10 für Dezimal- und Basis = 16 für Hexadezimal-Darstellung). Beispiel: unsigned int zaehler = 65432; char string[6]; //.... itoa(zaehler, string, 10); Jetzt enthält string den ASCII-String "65432" mit abschließendem Nullterminator (deshalb auch ein 6er-Array für die max. 5 Stellen einer Integer-Variable). Den String kann man jetzt wie gewohnt ausgeben.
> Kann man die Zahlen binär hochzählen und dann jeweils durch 10 > teilen und die Nachkommastelle dann in ASCII umwandeln und zum LCD > senden? > Oder hat jemand eine Idee wie es vernünftiger zu realisieren ist. Genau so macht man das. Alternativ könnte man die Division durch 10 einsparen, wenn man nicht binär zählt, sondern in BCD. Also nach 0x09 kommt nicht 0x0A sondern 0x10 usw. Dann stellt jedes Nibble schon ein fertiges Digit dar. Man muss es nur noch extrahieren, den Code für '0' noch addieren und hat schon das Zeichen das zum LCD muss. > Wie kann ich es umgehen bei jedem Zeichen die routine "lcd_data" > aufzurufen? Gar nicht. Letztendlich muss immer für jedes Zeichen lcd_data aufgerufen werden, da ja das Zeichen zum LCD übertragen werden muss und genau das ist der Job von lcd_data. Was das Tut meint (und nie ausgeführt hat), ist wenn du einen längeren konstanten Text ausgeben willst. Dann macht man das nicht dadurch dass man händisch jedes Zeichen einzeln angibt. Stattdessen definiert man sich einen konstanten String und schreibt eine Funktion der man die Startaddresse dieses Strings übergibt. Die Funktion geht dann in einer Schleife durch die Bytes des Strings durch, lädt jeden einzelnen und schickt ihn per lcd_data zum LCD.
ich will ja nicht klugscheissen (wie es leider zu oft der fall hier ist), aber das ist imho nicht ganz korrekt: >>unsigned int zaehler = 65432; >>char string[6]; >>//.... >>itoa(zaehler, string, 10); >> >>Jetzt enthält string den ASCII-String "65432" mit abschließendem >>Nullterminator (deshalb auch ein 6er-Array für die max. 5 Stellen >>einer Integer-Variable). Den String kann man jetzt wie gewohnt >>ausgeben. ein string[5] reicht, da bei string[0] angefangen wird. also insgesamt 6 8bit felder, wobei string[6] der /0 entspricht (NULL). sorry, nicht böse sein, aber das musste klargestellt werden. pumpkin
@ johnny.m Vielen dank für den Tipp, aber meine C Kenntnise bewegen sich leider auf ziemlich niedrigem Niveau. Stattdessen programmiere ich lieber in Assembler wobei ich da auch nur die nötigsten Grundkenntnisse habe, und noch ein wenig das know how zu solchen problemen fehlt. @Karl Heinz Buchegger Also wenn ich nun die Zahl 17 habe (0b10001) die binär in ein register passt, brauche ich für die ausgabe 2 register da ich jede stelle einzeln als ASCII speichern muss? Existieren irgendwo codebeispiele um die Ausgebe eines ganzen Strings dynamisch zu erledigen? Ich habe bis jetzt leider noch nichts gefunden...
> pumpkin: > ein string[5] reicht Dein IMHO trügt dich. char string[5]; schafft ein Array für fünf char Elemente. Der Index des Arrays darf somit von 0 bis 4 laufen. '65432' enthält fünf einzelne Zeichen, das passt. Aber ein abschliessendes, unbedingt notwendiges Nullbyte passt nicht mehr rein. Das ist also ein klassischer Kandidat für einen Bufferoverflow.
ja manuel ich habe es so gemacht: 4 register: - register1: der wert der ausgegeben werden soll - 3 register: hunderter, zehner, einer nun prüfe ich ob der auszugebende wert über hundert leigt, wenn ja ziehe ich hundert ab und inkrementiere reister "hunderter". So lange bis der wert unter hundert liegt, dann mache ich mit zehner und einern das gleiche. der vorteil ist, dass man wenn man sich die ASCII-Tabelle des LCD-Controllers ansieht, sieht dass alle zahlen in einer reihe liegen, man muss also zu jedem register(hunderter,zehner,einer) nur noch 0b00110000 addieren und das register per lcd_data ans lcd zu senden. Fertig. Ich hoffe das hilft dir weiter. luxx
@stefan (alle anderen gucken bitte weg ; ) ): string[0]: 6 string[1]: 5 string[2]: 4 string[3]: 3 string[4]: 2 string[5]: NULL auszug C for dummies (öl ins feuer? g): "[...] char var[laenge]; laenge zeigt die anzahl der zeichen an, die der string enthalten kann. [...]" pumpkin
> laenge zeigt die anzahl der zeichen an, die der *string* > enthalten kann. Richtig. Und jetzt zähl mal in deinem Falschbeispiel ;-)
Nachdem der Thread ins C abgedriftet ist, Manuel aber in AVR-Assembler arbeiten will, möchte ich auf eine (unfertige) Routinensammlung verweisen, die all das macht, was Manuel sucht: http://www.mikrocontroller.net/forum/read-1-164017.html#164028 Mit "unfertig" meine ich, dass die Routinen bei Bedarf ergänzt, abgeändert oder aus Platzmangel gestrichen werden. ...
kränk, ich muss gestehen, du hast recht. seit wann gehört das NULL byte dazu? scheinbar schon immer. sorry, ich war zu sehr davon überzeugt dass ich recht habe. pumpkin
Ist wieder so ein typischer (Rein)Fall, den man leider allzu oft sieht. Bei der Deklaration wird die Anzahl der Elemente angegeben, beim Zugriff die laufende Nummer, und die Zählung beginnt nunmal bei Null...
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.