Pollin LCD Zeilen einstellen, aber wie?

Gast #497041
Lesenswert?

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
Gast #497050
Lesenswert?

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
Gast #497077
Lesenswert?

@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
Gast #497096
Lesenswert?

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
Gast #497101
Lesenswert?

@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

Gast #497137
Lesenswert?

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
#497167
Lesenswert?

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

Gast #497169
Lesenswert?

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
Gast #497197
Lesenswert?

@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
Gast #497206
Lesenswert?

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
#497216
Lesenswert?

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.
)
Gast #497278
Lesenswert?

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
Gast #497348
Lesenswert?

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
Gast #497378
Lesenswert?

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
Gast #497397
Lesenswert?

@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

Gast #497414
Lesenswert?

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
Gast #497789
Lesenswert?

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
Gast #497795
Lesenswert?

@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
#497820
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren