Moinsen! Nun habe ich eine init welche richtigt läuft und auch eine kleine fprint geschrieben. Sie kann noch nichts besonders! Wenn ich einen langen Text oder das abc schreibe bleiben Buchenstaben weg und in der nächsten Zeile geht es irgendwann weiter. z.B.: ....blup und bla ... 12345 ijklmn pqrstuvwxyz Wo das Leerzeichen ist zwischen n und p ist ein Zeilenwechsel von Controller des LCD! Soweit habe ich es ja begriffen, doch wie andere ich es von 39 auf 27 Zeichen in jeder der 4 Zeilen??? Pollin LCD WD-C2704M-1HNN 4 Zeilen x 27 Zeichen Text mit einem HD44780 Controller mfg Taz
Hallo, garnicht. Du mußt Dich bei der Ausgabe darum kümmern, am Ende einer Zeile die Anfangsadresse der nächsten gewünschten Zeile zu setzen. Das Display hat 80 Zeichen Ram (das Pollin dürfte 2 Kontroller haben?), die Zuordnung der Adressen zur Darstellung sollte in der Display-Beschreibung zu finden sein. Sonst eben ausprobieren, an welcher Adresse Zeile 2 beginnt usw. Gruß aus Berlin Michael
Hi Michael! Dann wäre es sicherlich einfacher eine printf() Funktion an zu passen und mit ihr die Ausgabe auf den Port zu machen?! Ich proge in C unter µVision3 von Keil auf eine AT89C51CC03 im 8-Bit Modus. mfg Taz
@Michael Thom >Dann wäre es sicherlich einfacher eine printf() Funktion an zu passen >und mit ihr die Ausgabe auf den Port zu machen?! Naja, wenn du das volle Programm brauchst (Floating Point etc.) dann ja. MfG Falk
Hi Falk, im Forum hier stehen eine Menge Beiträge zu prinf(). Da muss ich nur sehen das ich den Code auf mein µC und in C gut übertrage. Dann sollte es doch schon gehen, oder sehe ich das verkehrt? mfg Taz
@Michael Thom >im Forum hier stehen eine Menge Beiträge zu prinf(). Da muss ich nur >sehen das ich den Code auf mein µC und in C gut übertrage. Dann sollte >es doch schon gehen, oder sehe ich das verkehrt? Jain. Das printf für dein LCD hat zwei Aufgaben a) Den Formatstring parsen(analysieren) un dementsprechend einen String generieren. b) Die Ausgabe der einzelnen Chars des String in LCD koordinieren, was auf grund er nichtlinearen Adresszuordung nicht so ganz einfach ist. Ersteres gibt es schon fertig, nimm einfach sprintf. Zweiteres musst du selber machen. MFG Falk
Danke Falk, mit sprintf kann ich super einen string ausgeben. Werde einfach zwei print-Funktion schreiben für das obere und unter Display! Aber ich habe mal eine Frage zu folgenden Programmcode: va_list ap; va_start(ap, pText); vprintf(text, ptext, ap); va_end Wenn ich mir das anschauen, vermute ich das die Platzhalter mit den Variablen gefüllt werden! Also wo %d steht wird der Wert von int c = 3 reingeschrieben. Ist aber nur eine Vermutung, darum wollte ich gerne lieber nachfragen und ob ich es mit sprintf auch so handhaben muss? mfg Taz
> darum wollte ich gerne lieber nachfragen > und ob ich es mit sprintf auch so handhaben muss? Ja. Der einzige Unterschied zwischen printf und sprintf liegt darin, dass printf das Ergebnis (den String) in die I/O Kanäle schiebt, während sprintf das Ergebnis in einen character Buffer stellt. Intern werden von sprintf, printf, fprintf normalerweise sogar die gleichen Funktionen benutzt um den String zu formatieren.
Hi! Also mit folgender Funktion bekomme ich auf den LCD die Ausgabe: [Hier bin ich! 256 0 ] Zeile 1 int f1print (unsigned char text[], ...) { int i; int lenght; char temp[39]; va_list ap; lenght = 0; lenght = strlen(text); va_start(ap,text); sprintf(temp,text,ap); va_end(ap); for (i=0;i<lenght;i++) { write_data(temp[i], 1); } return 0; } Ich habe in meiner main die f1print folgender maßen aufgerufen: f1print("Hier bin ich! %d %f", i, i); Wobei int i = 5 ist. Wieso klappt die Ausgabe nicht richtig? Taz
Hey! Ein \r, \t und \n funtzt auch nicht bei mir! Habe ich was entscheidenes vergessen oben in meiner Funktion? Grüße Taz
@Michael Thom
>Ein \r, \t und \n funtzt auch nicht bei mir!
Kann ja auch gar nicht. Dein LCD ist "dumm", es kann nur Zeichen
darstellen. Es weiss nicht, dass es bei
\r an den Zeilenanfang
\n in die nächste Zeile springen soll.
Das musst du "per Hand" machen.
MFG
Falk
Michael Thom wrote: > > f1print("Hier bin ich! %d %f", i, i); > > Wobei int i = 5 ist. > > Wieso klappt die Ausgabe nicht richtig? Weil i immer noch ein int ist. %f wird für float oder double benutzt.
Hi, darauf hätte ich auch selbst kommen können. Habe wohl zu hohe Erwartungen an mein µC und LCD. Doch warum klappt das nicht mit der Formatausgabe: f1print("Hier bin ich! %d %f", i, i); Wobei int i = 5 ist und raus kommt => Hier bin ich! 256 0 muss ich dass auch per Hand nachtragen? mfg Taz
okay mit %f kommt was verkehrtes raus, aber bei %d sollte zumindest 5 stehen und nicht 256. Grüße Taz
Nein. sollte es nicht. Deine Format Argumente passen nicht zu den tatsächlich übergebenen Argumenten. Ab da kann alles mögliche passieren. (Was wahrscheinlich passiert ist: Die Argumente werden von rechts nach links auf den Stack gelegt. Und zwar 2 * 2 Bytes. Beim Auswerten hat sich der %f gleich mal 4 Bytes vom Stack geholt, sodass der %d sich irgendwas vom Stack holen musste. Zufällig war das halt 256. )
Habe es schon abgeändert: dir = 5; f1print("Hier bin ich! %d", dir); und Ausgabe: Hier bin ich! 256+
achso, int dir; und habe mal die zeilen geändert: double dir = 5; f1print("Hier bin ich! %f", dir); und Ausgabe: Hier bin ich! 0.0 ??? Werden die Argumente nicht übergeben?
Wenn ich die sprintf(temp, "lenght: %d", len); // len = 22 und an mein write-data () übergebe kommt die Anzeige korekt raus! irgendwie scheinen meine Argument nicht richtig eigebaut zu werden habe ich da einen Fehler begangen? int f1print (unsigned char *text, ...) { int i; int len; char temp[39]; va_list ap; len = 0; len = strlen(temp); va_start(ap,text); sprintf(temp,text,ap); va_end(ap); // Test für eine Ausgabe //sprintf(temp, "lenght: %d", len); // Funktion ist völlig konrekt ausgegeben worden! for (i=0;i<len;i++) { write_data(temp[i], 1); } return 0; } lg Taz
Ich habe den Code jetzt soweit geändernt, dass er wie folgt aussieht: int f1print (char *text, ...) { int i; int len; char temp[39]; va_list ap; len = 0; len = strlen(temp); va_start(ap,text); sprintf(temp,text,ap); va_end(ap); // Test für eine Ausgabe //sprintf(temp, "lenght: %d", len); // Funktion ist völlig konrekt ausgegeben worden! for (i=0;i<len;i++) { write_data(temp[i], 1); } return 0; } Aber dennoch kommt immer noch : Hier bin ich! 256 Und das obwohl wo 256 steht nur eine 5 sein sollte! Hat jemand eine Idee warum? mfg Taz
Schau mal hier: Beitrag "lib für Pollin LCD (WINTEK2704)" da hatte ich mal eine Bibliothek für dieses Display veröffentlicht. Selbige kümmert sich auch um das etwas eigenartige Zeilengehüpfe. Gruß Stefan
Habe ich mir angesehen! Die Funktion puts gibt aber nur eine Zeichenfolge aus! Ich möchte nachher aber schreiben können "f1print("Position: %d:", dir);" , mit beliebig vielen Variablen! Und wenn ich mir den Code anschaue kann dieser das nicht, oder liege ich da fehl? Gruß Taz
Ich hab schon lange nichts mehr mit "variadischen Funktionen" gemacht. Das ist auch das Stichwort, mit dem du im Google was finden solltest: "variadische Funktionen"
@Michael Thom > va_start(ap,text); > sprintf(temp,text,ap); > va_end(ap); Was machen die Funktionen va_start und va_end? So wie ich es sehe, ist deine Funktion nicht dazu geeignet, die Zeilenstuerung zu übernehmen. Dazu brauchst du (globale) Variablen für Zeile und Spalte. Nach jedem ausgegebenen Zeichen msst du prüfen, ob du einen Zeilensprung machen musst oder nicht. Das sehe ich bei dir überhaupt nicht. MfG Falk
also, wenn ich das richtig verstanden habe von Karl heinz Buchegger. Hat er mir zugestimmt das bei diesem ablauf die variablen mit ihren jetzigen Wert den sie besitzen in den String integrit werden. ("hey %d", i) // i=5 => "hey 5" TAz
Da habe ich was vergessen in der befehlskette, denke ich! Werde mal weiter suche! Grüße Taz
Axo, die Anregung es so zu progen habe ich von: Beitrag "Re: printf-Funktion für Displayausgabe schreiben" Es schien mir eigentlich eine einfache saubere Lösung zu sein.
Dann lies noch mal genau. Der benutzt vsprintf und nicht sprintf.
Moin! Ja, dachte es würde auch mit sprintf gehen. Wahrscheinlich habe ich zu lange vor dem Bildschirm gehangen und war blind um nach links und rechts zu blicken. Ob es noch andere Möglichkeiten gibt! Habe es jetzt einfacher gemacht! int f1print (char *text, double x, double y); { .... sprintf(temp,text, x,y); .... } Mit unterschiedlichen Variablen wärs mir lieber. Doch vielleicht habe ich später dafür noch Zeit! Wenn ich den gesamten Code ausdrucke und optimiere! Erstmal sollte alles laufen nach meiner Vorgabe, dann kann man immer noch mehr daraus machen Ich danke euch an der Kritik und Hilfe die man mir zukommen liest, sie hat geholfen!!! Grüße Taz
@Michael Thom >Habe es jetzt einfacher gemacht! >Mit unterschiedlichen Variablen wärs mir lieber. Doch vielleicht habe Das kann man auf zwei Wegen lösen. a) Einfach sprintf und die Ausgabe aufs LCD getrennt lassen, dann kannst du alle Schikanen von sprintf nutzen. b) Professionell, verwende eine variable Parameterliste, das ist aber ein wenig kniffelig. Ich weiss nicht, wie das jetzt im Detail funktioniert. >Erstmal sollte alles laufen nach meiner Vorgabe, dann kann man immer >noch mehr daraus machen Dann schreib erstmal ne Funktion, die die Zeilenverwaltung mancht. MfG Falk
Falk wrote: > b) Professionell, verwende eine variable Parameterliste, das ist aber > ein wenig kniffelig. Ich weiss nicht, wie das jetzt im Detail > funktioniert. Hab das schon lange nicht mehr gemacht. Aber der Schlüssel sind die v-Funktionen. In diesem Fall vsprintf. Hier gibts ja einen Denkfehler (den ich auch wieder lange Zeit gemacht habe). In dieser Spezialfunktion f1Print liegt ja keine beliebig lange Argumentliste mehr vor. f1Print braucht eine xxprintf Funktion die genau 3 Argumente nimmt: * Einen Pointer auf den Ergebnisbuffer * Einen Pointer auf den Formatstring * Einen Pointer auf die Argumentliste Das alles liegt in f1Print vor und die Funktion die diese 3 Argumente nimmt, heist nun mal vsprintf() sprintf will ja ganz was anderes * Einen Pointer auf den Ergebnisbuffer * Einen Pointer auf den Formatstring * beliebig viele weitere Argumente "beliebig viele weitere Argumente" ist aber nicht dasselbe wie einen "Pointer auf die Argumentliste". Wenn man so will kann man auch sagen: sprintf erwartet die Argumente nach wie vor auf dem Stack, während vsprintf sie schon in eine "Listenstruktur" verpackt haben möchte (es ist meist keine echte Liste). Durch den va_list/va_start Mambo Zambo wird genau diese Transformation gemacht. Fehler fallen hier so gut wie nicht auf, da sprintf aufgrund des ... im Prototypen alles frisst. Es kommt halt nicht das richtige raus, wenn man Glück hat schmiert das Teil ab ansonsten sucht man sich im Fehlerfall dumm und dämlich.
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.