Forum: Mikrocontroller und Digitale Elektronik LCD per SPI ansteuern- Problem mit zu vielen char


von Sebastian (Gast)


Angehängte Dateien:

Lesenswert?

hallo zusammen,

ich habe ein PICDem Explorer Board von Microchip mit dem Pic 18F87J11 
und bin zur Zeit dabei, mal nur den Programmteil zu schreiben und zu 
testen, der das LCD ansteuert. Dans ganze geschieht auf dem Boar mittels 
SPI.

Funktioniert grundsätzlich auch, allerdings hab ich folgendes Problem: 
sobald ich mehr als 5 texte als char deklariere, gibt das LCD nur noch 
senkrechte Striche aus.
Kommentiere ich einen char aus, funktioniert alles wieder und es steht 
mein Text "Error NO SD-Card" drauf.

Ich habe schon in Büchern und über google nachgeschaut, habe in der 
Linkerdatei die gpr zusammengelegt, weil ich dachte ich bräuchte mehr 
Speicherplatz, aber nichts davon hat mein Problem auch nur ansatzweise 
gelöst.

Ihr seid meine letzte Rettung :-)
Danke schon mal für jeden Rat und jede Hilfe,

Sebastian

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

In was für einer Programmiersprache sind Programme geschrieben, wenn der 
Dateiname "LCD-testporgramm.doc" lautet?

Korrigiere das.

von Sebastian (Gast)


Lesenswert?

das ist in C geschrieben, ich hab es nur in ein word-Dokument eigefügt, 
um die Deklarationen und den Code in einer Datei zu haben.
Wenn ich die originalen c-Dateien hochladen soll, dann kann ich das erst 
morgen machen

von Frank K. (fchk)


Lesenswert?

Dein RAM ist voll. Ein PIC18 hat nicht so viel davon, und Du 
verschwendest es auch noch mit initialisierten Variablen, die beim 
Programmstart aus dem Flash ins RAM geladen werden.

Lies zunächst mal
http://de.wikipedia.org/wiki/Harvard-Architektur

Wenn Du das verstanden hast, schau mal in der Compilerdokumentation 
nach, was es mit dem Schlüsselwort rom auf sich hat. Falls Du die noch 
nicht gefunden hast ... im Installationsverzeichnis des C18-Compilers 
gibts ein doc Unterverzeichnis. Da darfst Du ruhig mal reinschauen. 
Lesen bildet.

fchk

von Sebastian (Gast)


Angehängte Dateien:

Lesenswert?

dass Lesen bildet ist mir durchaus bewusst. Ich habe ja auch schon was 
gelesen und dies ist mein erstes eigenes Projekt, sorry dass ich da 
nicht 100% Bescheid weiß über alles...
trotzdem danke für die Tipps, gemeinsam sind wir stark ;-)

Ich habe jetzt mal die beiden originalen Dateien (.c und .h hochgeladen)

von Christian K. (Firma: Atelier Klippel) (mamalala)


Lesenswert?

"clear" hast Du definiert als:
1
char clear[] = {" "};

In der aktuellen Ausgaberoutine hast Du aber:
1
for (i=0;i<16;i++)
2
{
3
    d_write(*(clear+i));
4
    //  Delay10KTCYx(5);
5
}

Ändere das in:
1
for (i=0;i<16;i++)
2
{
3
    d_write(' ');
4
    //  Delay10KTCYx(5);
5
}

Dann sollte das gehen, falls dein Fehler bei der Ausgabe einer Leerzeile 
war.

In der .h fehlt am Ende das #endif um den Block abzuschließen.
Warum hast Du mal "const char ..." und mal "char ..."?
Deine Ausgaberoutine ist auch nicht so das tolle. Du hast für jeden 
String effektiv eine andere Routine, wegen der unterschiedlichen Längen. 
Mache dir eine Routine die ganz allgemein Strings ausgibt, und lege 
die Stings dann auch normal an, so das die am Ende das C-übliche 
0-Zeichen haben (\0). So kannst Du dann jeden beliebigen String über 
eine einzelne Funktion ausgeben.

Grüße,

Chris

von Sebastian (Gast)


Lesenswert?

hallo Chris,

danke für deine Hilfe :-)

Mit der Routine und den unterschieldichen Längen das ist in der Tat 
nicht so toll, bisher kam ich aber auf keine andere Lösung, weil ich zum 
ersten mal ein LCD über SPI ansteuere und es einfach nicht hinbekommen 
habe, da strings so ruaszuschreiben, dass die Länge der Routine egal bzw 
variabel bleibt.

Hättest du da einen Ansatz für mich? Danke schon mal!

Die Clear-Funktion ist sowieso müll, das soll das Display leeren, bevor 
ein neuer Text ausgegeben wird. Geht sicher auch eleganter, nur wie hab 
ich bisher auch nicht herausgefunden.

von Christian K. (Firma: Atelier Klippel) (mamalala)


Lesenswert?

Achja,

und generell ist es besser wenn Du feste Strings in den Flash legst 
anstelle des RAM.

So eine Ausgaberoutine könnte z.B. so aussehen:
1
void lcd_write_string_rom(unsigned char x, unsigned char y, static const rom char *ldata)
2
{
3
    lcd_set_cursor(x, y);
4
    
5
    while(*ldata)
6
    {
7
        lcd_write_data(*ldata++);
8
    }
9
}

Wobei dann ein String so definiert wird:
1
rom const char rom error_0[] = "Fehlermeldung";

Die Ausgaberoutine wird dann z.B. so aufgerufen:
1
lcd_write_string_rom(0, 0, error_0);

...oder so ähnlich, habs grad aus dem Kopf heraus geschrieben, kann also 
noch ein Fehler drin sein ;)

Je nach Compiler-Einstellungen und/oder verfügbarem Flash-Speicher kann 
es auch sein das die Strings als "const rom far ...." definiert werden 
müssen.

Grüße,

Chris

von Sebastian (Gast)


Angehängte Dateien:

Lesenswert?

hab die .h auch geändert. einmal habe ich das #endif eingefügt und 
außerdem speichere ich meine strings nun im rom. somit kann ich viel 
mehr Texte definieren als vorher und es laufen alle.

von Sebastian (Gast)


Lesenswert?

deine anderen Tips werde ich gleich mal ausporbieren.
Vilen, vielen Dank, du bist mir echt eine große Hilfe, Chris! :-)

von Christian K. (Firma: Atelier Klippel) (mamalala)


Lesenswert?

Nimm die Größenangaben aus den String-Definitionen auch noch raus. Lass 
den Compiler sein Ding machen, und normale C-Strings anlegen.

Also nicht:
1
rom const char rom hallo[5] = "Hallo";

Sondern:
1
rom const char rom hallo[] = "Hallo";

Die letztere Variante ergibt, in einzelne Zeichen zerlegt, den String:

'H', 'a', 'l', 'l', 'o', '\0'

Das letzte Zeichen ist also 0 (Wertmäßig). So kann die Ausgaberoutine 
herausfinden wann der String zu Ende ist.

Grüße,

Chris

von Sebastian (Gast)


Angehängte Dateien:

Lesenswert?

die Längen habe ich schon rausgenommen.

Habe jetzt mal meine main geändert und wollte deine Ausgaberoutine 
verwenden, jedoch meckert er noch rum er habe keine Definition für die
lcd_write_data. Wo habe ich da noch einen Fehler drin?
(hab die aktuelle, fehlerhafte main angehängt)

von Christian K. (Firma: Atelier Klippel) (mamalala)


Lesenswert?

Natürlich musst Du selber die passenden Funktionen erstellen die 
Daten/Instruktionen etc. zu dem Display schicken. Ich habe hier keinen 
Copy&Paste-Fähigen Code gepostet. Da musst Du selber ran ;)

Das wäre das, was bei deinem alten Code die d_write() Funktion war. Also 
einfach das
1
lcd_write_data(*ldata++);

abändern in
1
d_write(*ldata++);

Ebenso die lcd_set_cursor() aus meinem Beispiel. Die hast Du ja 
garnicht. Da musst Du dann also selber eine passende Funktion schreiben 
die den Cursor auf die gewünschte Zeile und Spalte setzt.

Grüße,

Chris

von Sebastian (Gast)


Lesenswert?

okay jetzt verstehe ich das.

Ich erwarte auch keine copy&paste fähigen Sachen, das ist wie gesagt 
mein erstes Projekt und da muss ich viel experimentieren ;-)
Aber du hast mir echt schon viel weitergeholfen, danke! :-)

Gruß
Sebastian

von Christian K. (Firma: Atelier Klippel) (mamalala)


Lesenswert?

Ja, das habe ich mir schon gedacht das Du was lernen willst. Daher ja 
auch nix "fertiges" von mir ;)

Was die lcd_write_string_rom() im Kern macht:

Der auszugebnde String wird als Pointer (Zeiger) auf eben diesen im 
Flash übergeben. Das Konstrukt *ldata enthält dann das Char auf das 
dieser Pointer zeigt. Solange auszugebende Zeichen da sind, ist dieser 
Char ja ungleich 0.

Das Konstrukt *ldata++ holt ebenfalls das Zeichen auf den der Pointer 
zeigt, allerdings erhöht/inkrementiert er den Zeiger anschliessend um 1. 
Bei der nächsten Abfrage von *ldata erhält man also das nächste Zeichen 
im String.

Somit wird dann auch klar was das while(*ldata) macht: Solange das 
aktuelle Zeichen, auf den der Pointer zeigt, ungleich 0 ist wird ein 
Zeichen ausgegeben, z.B. mittels d_write(*ldata++);

Da diese Ausgabe zuerst das aktuelle Zeichen holt, und danach den 
Pointer erhöht, ist beim nächsten Schleifendurchlauf der Test 
while(*ldata) ein Zeichen weiter. Ist nun das Ende des Strings erreicht 
ist der Wert von *ldata ja 0, und die Schleife ist beendet, es erfolgt 
keine Ausgabe mehr.


Grüße,

Chris

von Sebastian (Gast)


Lesenswert?

also, ich habe es lauffähig.
Was ich jetzt nicht drin habe ist eine genau Cursorposition, ich hab nur 
ne Routine LCDLine_1() und LCDLine_2() wo ich Zeile 1 oder 2 wähle und 
da an den Anfang springe. Dann folgt die Routine, die den string 
rausschreibt.

Momentan hab ich in der main nix anders als das Rausschreiben drin, 
daher "blinkt" der Text, was ich mit dem ziemlich langen Delay fast zum 
stillstand bekommen habe.
Aber das löst sich dann von alleine, denn in dem Programm, was ich 
schreiben werde, wird die Routine zum Schreiben ans LCD nur in einer 
if-Schleife aufgerufen und danach laufen zig andere Sachen in der main 
weiter.
Von daher, kann ich das im Moment mal so lassen.

DANKE für die Hilfe, Chris :-)

Gruß
Sebastian

von Christian K. (Firma: Atelier Klippel) (mamalala)


Lesenswert?

Ja, Super!

So, noch ein paar Tips. Packe die ganze Funktionen für die LCD 
Behandlung in eine extra .c Datei. Die ganezn Funktions-Definitionen 
dafür, die Du derzeit noch ganz oben in der main hast, in eine dazu 
passende .h Datei. Z.B. sowas wie lcd.c und lcd.h

lcd.h wird dann sowohl in der lcd.c als auch in der main.c inkludiert. 
Bzgl. der Strings solltest Du die anders organisieren. Wenn Du lediglich 
einsprachige Texte brauchst, dann kannst Du das auch direkt im 
Funkltionsaufruf machen, also z.B.:
1
lcd_write_string_rom(0, 0, "Hallo!");

Normalerweise ist der Compiler schlau genug, wenn man es ihm sagt, für 
identische Strings bei Funktionsaufrufen den String auch nur einmal im 
Flash abzulegen.

Wenn Du die Strings extern haben willst, dann ist eine .h dafür alleine 
nicht gut geeignet. Diese kannst Du dann nämlich nur einmal einbinden. 
Sobald Du in einer weiteren .c Datei auf die Strings zugreifen willst, 
geht das so nicht mehr. Stattdessen muss in der .h stehen:
1
extern rom const char rom hallo[];

Und dann in einer extra .c Datei dafür:
1
rom const char rom hallo[] = "Hallo";

Somit wird der String erstmal nur bekannt gemacht durch die .h, die dann 
auch in mehreren .c Dateien inkludiert sein kann, während die 
eigentliche Definition/Zuweisung dann nur einmal in der extra .c 
erfolgt.

Wenn Du das ganze dann schon mal so angelegt hast, also die Strings in 
einer Kombination aus .h und .c hast, dann kann man darauf nämlich 
weiter aufbauen und das ganze dann Multilingual machen. Ist zwar dann 
nochmal ein wenig mehr Aufwand, erlaubt aber mehrere Sprachen ohne das 
dafür der eigentliche Code von dem aus man Strings ausgeben will (z.B. 
eine Fehlermeldung in einer Unterfunktion) jemals wieder ändern muss, 
selbst wenn man neue Sprachen hinzufügt .... ;)

Grüße,

Chris

von Karl H. (kbuchegg)


Lesenswert?

> Momentan hab ich in der main nix anders als das Rausschreiben
> drin, daher "blinkt" der Text,

Der Text 'blinkt', weil du immer wieder das LCD löscht. Und zwar als 
ganzes. Das ist etwas, was du dir abgewöhnen musst.

Die 'richtige' Vorgehensweise ist es, soviel wie möglich durch 
Überschreiben zu machen! D.h. du änderst immer nur den Text, den du auch 
tatsächlich ändern willst. Und das machst du so, dass du nach 
Möglichkeit den neuen Text gleich über den alten drüberschreibst. Dazu 
ist es auch erforderlich, die Texte zu identifizieren, die sich nie 
ändern. DIe werden dann nämlich nur ein einziges Mal ausgegeben und 
bleiben dann am LCD (das LCD wird ja nicht mehr als Ganzes gelöscht)

Möchtest du zb mit deinem LCD eine gemessene Spannung vom ADC ausgeben, 
dann hat das zb so einen Bildaufbau

   +---------------------------------------+
   | Wert vom ADC:    0000                 |
   | Spannung:        +2.34 V              |
   +---------------------------------------+

Die Texte "Wert vom ADC:", bzw. "Spannung:" bzw "V" ändern sich nie. Die 
werden daher nur ein einziges Mal aufs LCD ausgegeben, zb wenn der 
Benutzer einen Menüpunkt "Spannungsmessung" anwählt. Ändern tun sich nur 
die Zahlenwerte, wobei du dir Zahlenausgabefunktionen machst, die beim 
Überschreiben darunterliegenden Text gleich mitlöscht. Denn wenn deine 
LCD Anzeige von


   +---------------------------------------+
   | Wert vom ADC:     124                 |

auf

   +---------------------------------------+
   | Wert vom ADC:      98                 |

wechselt, muss ja irgendein Mechanismus dafür sorgen, dass die '1' 
verschwindet (mit einem Leerzeichen überschrieben wird). Komplettes LCD 
löschen ist ja tabu.

Und dann flackert da auch nichts mehr.

von Sebastian (Gast)


Lesenswert?

@Chris: das umzubauen in eine lcd.c und eine lcd.h habe ich bereits in 
Arbeit. Multilingual muss es nicht werden, den Aufwand kann ich mir 
sparen ;-)

@Karl Heinz: danke für den Tip, werde das noch ändern. Es stimmt, dass 
ich immer das ganze LCD lösche, weil meine Kenntnise bisher nicht dazu 
gereicht haben, nur bestimmte Stellen zu löschen.
Um das zu realisieren komme ich um eine genauere Cursorposition statt 
nur meine LCDLine_1 und LCDLine_2 nicht drum herum, oder? weil dazu bin 
ich auf dem Gebiet auch noch nicht schlau genug^^

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:

> @Karl Heinz: danke für den Tip, werde das noch ändern. Es stimmt, dass
> ich immer das ganze LCD lösche, weil meine Kenntnise bisher nicht dazu
> gereicht haben, nur bestimmte Stellen zu löschen.

Löschen ist ein großes Wort :-)
In Wirklichkeit ist es nur überschreiben mit Leerzeichen.

> Um das zu realisieren komme ich um eine genauere Cursorposition statt
> nur meine LCDLine_1 und LCDLine_2 nicht drum herum, oder?

Exakt.
So was brauchst du aber sowieso

von Sebastian (Gast)


Lesenswert?

so, noch mal ne kurze Rückmeldung:
das mit der Cursorposition habe ich nun hinbekommen. Hab meine 
vorhandenen Unterfunktionen LDCLine_1 und LCDLine_2 erweitert zu 
LCDLine_1(x) und LCDLIne_2(x) wobei x für die Stelle steht, an der der 
Text ausgegeben werden soll.
das funktioniert dann jetzt :-)

Was ich auch abgestellt bekommen habe, ist das "blinken".

Jetzt stellt sich mir nur noch eine einzige Frage: angenommen in Zeile 2 
wurde zuletzt der Error ausgegeben "No SD-Card" und das soll jetzt 
überschrieben werden mit "warte...", wie löse ich dann, dass die 
fehlenden Zeichen (das rd) mit Leerzeichen überschrieben werden?

von Sebastian (Gast)


Lesenswert?

muss mich nochmal zu Wort melden:
also beim Überschreiben habe ich tatsächlich das Problem, dass das "ard" 
von Card stehenbleibt. Wie bekomme ich das weg? Einfach den neuen Text 
um paar Leerzeichen länger machen?

Und dann noch mal zu dem blinken: das ist wieder da, weil als ich die 
LCDInit() rausgenommen habe, ging gar nix mehr. In der Init steht das 
aber drin mit dem Clear, d.h. er löscht immer zu beginn der main das 
LCD, vermutlich daher das blinken.
Macht es jetzt was aus, wenn ich einfach in der LCDInit den Befehl des 
clear rausnehme?

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:
> muss mich nochmal zu Wort melden:
> also beim Überschreiben habe ich tatsächlich das Problem, dass das "ard"
> von Card stehenbleibt. Wie bekomme ich das weg? Einfach den neuen Text
> um paar Leerzeichen länger machen?

:-)
Ist dir diese Lösung zu einfach?
:-)

Sieh es so:
Du schreibst nicht den Text "XYZ" an eine bestimmte Position, sondern in 
erster Linie hast du am LCD einen Bereich von x Zeichen für eine Ausgabe 
reserviert. Dieses x ist deine massgebliche Größe. Machst du alle Texte, 
die du in diesen Bereich ausgibst gleich lang, dann gibt es keine 
Probleme.

In diesem Sinne sind dann die Texte
"No SD-Card"
"warte...  "
"Fertig    "
"Fehler    "
"->        "
"  ->      "
"    ->    "
"      ->  "
"        ->"

geeignete Texte, um in diesem Bereich mit 10 reservierten 
Ausgabepositionen ausgegeben zu werden. Der Einfachheit halber kann man 
die Texte einfach gleich lang machen. Wenn es viele sind, lohnt es sich 
möglicherweise auch, eine spezielle Ausgabefunktion zu machen, die einen 
Text ausgibt und nach der Ausgabe noch Leerzeichen nachschiebt, wenn der 
Text zu kurz war. Lohnt aber erst, wenn man signifikant viele derartige 
Texte hat, die dann auch alle nicht gleich lang sind.



PS:  "No SD_Card"  "warte...  "
Warum einmal Englisch und einmal Deutsch? Das zeugt nicht von 
Professionalität. Entscheide dich für eine Sprache und bleibe dabei. Es 
gibt im deutschen Sprachraum schon genügend 
Möchtegern-Englisch-Wichtigmacher. Reih dich nicht freiwillig in diese 
Riege ein.

von Sebastian (Gast)


Lesenswert?

wenn das eine lösung ist, die nicht als Pfusch gilt, wäre mir das nicht 
zu einfach. Nur dachte ich, dass es eigentlich ja nicht sein kann, wenn 
ich die Strings variabel habe in der Länge, dass ich dann künstlich auf 
das, was ich maximal an Länge rausschreibe mit Leerzeichen füllen muss?

Ich dachte, ob ich vielleict, bevor der eigentliche Text erscheint, ich 
die jeweilige Zeile einmal mit Leerzeichen fülle und DANN meinen Text 
rausschreibe?

von Karl H. (kbuchegg)


Lesenswert?

Du merkst schon:
GUI Konzepte beginnen damit, dass man sich auf der Ausgabefläche
Bereiche definiert, in denen bestimmte Informationen angezeigt werden.
Damit beginnt alles. Hat man erst mal diese Bereiche definiert, dann
kümmert man sich um die nächste Fragestellung: Wie kommen meine Ausgaben
in diesen Bereich und was kann mir da alles passieren.

Aber: So erhält man konsistente 'Oberflächen', die nicht
zusammengewürfelt aussehen und bei denen man ständig die relevanten
Informationen an der Ausgabe optisch suchen muss.

von Sebastian (Gast)


Lesenswert?

"Warum einmal Englisch und einmal Deutsch? Das zeugt nicht von
Professionalität. Entscheide dich für eine Sprache und bleibe dabei. Es
gibt im deutschen Sprachraum schon genügend
Möchtegern-Englisch-Wichtigmacher. Reih dich nicht freiwillig in diese
Riege ein."

das sind nur Beispieltexte. Die endgültigen Strings werden natürlich 
einsprachig. Bisher gehts mir nur darum, irgendwelche belanglosen, aber 
nicht ganz realitätsfernen Texte zum Test auszugeben.
Was ich genau schreiben möchte, definiere ich dann, wenn der Rest läuft.

Aber das mit den Strings gleich lang machen leuchtet mir ein und genügt 
für meine Zwecke auch.
ich werde vielleicht 5 Fehlermeldungen haben, die ich immer in Zeile 2 
ausgeben werde. Da kann ich die durchaus alle auf die gleiche Länge 
bringen.

Danke für deine Hilfe :-)

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:

> Ich dachte, ob ich vielleict, bevor der eigentliche Text erscheint, ich
> die jeweilige Zeile einmal mit Leerzeichen fülle und DANN meinen Text
> rausschreibe?

Das ist eine schlechte Lösung.
Was du nach Möglichkeit immer vermeiden willst, ist ein Zwischenzustand, 
in dem nichts sichtbar ist. Das führt zu flackern bzw. flimmern.

Wenn du die Texte nicht aufpimpen willst, kannst du ja immer noch eine 
Funktion schreiben, die einen Text ausgibt UND der du sagen kannst: Ich 
brauch aber 10 Zeichen. Die Funktion gibt dann den Text aus, zählt die 
Zeichen mit und schiebt eine entsprechende Anzahl an Leerzeichen nach. 
So eine Funktion ist auch insofern praktisch, weil sie überwachen kann, 
das nicht MEHR Zeichen ausgegeben werden, als in das vorgesehene 
Textfeld passen.

Aber bei 3, 4, 5 Texten mit unterschiedlichen Längen ist das alles kein 
Thema: Der Aufwand lohnt nicht. Die Texte auf gleiche Länge bringen ist 
viel einfacher und völlig ausreichend.

von Christian K. (Firma: Atelier Klippel) (mamalala)


Lesenswert?

Hallo Sebastian,

da gibt es mehrere Möglichkeiten. Eine wäre eine Ausgabe, die den Rest 
der LCD Zeile mit Leerzeichen füllt, z.B. so:
1
#define CHARS_PER_LINE    16
2
3
void lcd_write_line_rom(static const rom char *ldata)
4
{
5
    static unsigned char numchars;
6
7
    numchars = 0;
8
    
9
    while(*ldata)
10
    {
11
        lcd_write_data(*ldata++);
12
        numchars++;
13
    }
14
15
    while(numchars < CHARS_PER_LINE)
16
    {
17
        lcd_write_data(' ');
18
        numchars++;
19
    }
20
}

Diese Methode geht davon aus das man immer an der ersten Stelle der 
Zeile mit der Ausgabe anfängt, gibt dann den String aus und füllt den 
Rest der Zeile mit Leerzeichen aus.

Manchmal braucht man aber z.B. einen zentrierten Text, also so das man 
vor und nach dem String Leerzeichen braucht. Das könnte man z.B. so 
lösen:
1
#define CHARS_PER_LINE    16
2
3
void lcd_write_line_at_rom(unsigned char startpos, static const rom char *ldata)
4
{
5
    static unsigned char numchars;
6
7
    numchars = 0;
8
    
9
    while(numchars < startpos)
10
    {
11
        lcd_write_data(' ');
12
        numchars++;
13
    }
14
15
    while(*ldata)
16
    {
17
        lcd_write_data(*ldata++);
18
        numchars++;
19
    }
20
21
    while(numchars < CHARS_PER_LINE)
22
    {
23
        lcd_write_data(' ');
24
        numchars++;
25
    }
26
}

Möchte man eine Ausgabe von Werten nach einem festen Text, so wie sie 
der Karl Heinz angesprochen hat, muss man halt die Wertausgabe 
entsprechend so schreiben das sie immer eine feste Anzahl an Stellen 
benutzt und diese dann vor und/oder dem eigentlichen Wert dann 
entsprechend viele Leerzeichen ausgibt.

Man kann auch ein "selektives" Löschen machen, indem man eine Funkteion 
schreibt die nur eine gewünschte Anzahl an Leerstellen ab einer 
definierten Position ausgibt, z.B. so:
1
void lcd_partial_line_erase(unsigned char x, unsigned char y, unsigned char num_erase)
2
{
3
    static unsigned char cnt;
4
5
    cnt = 0;
6
7
    lcd_set_cursor(x, y);
8
    
9
    while(cnt < num_erase)
10
    {
11
        lcd_write_data(' ');
12
    }
13
}

Oder was auch immer für eine Kombination von all dem man haben möchte. 
Die Frage ist halt immer was sich mehr lohnt. Wenn Du z.B. nur zwei 
Strings hast die auch nur an zwei Stellen im Code ausgegeben werden, 
dann ist es sinnvoller bereits im String die nötigen Leerzeichen 
einzufügen. Das sind ja dann nur ein paar Bytes mehr an Flash-Verbrauch.

Wenn Du aber an vielen Stellen viele Strings ausgibst, mit allen 
möglichgen Längen, dann ist es besser das man passende Funktionen 
schreibt anstatt die Strings zu vergrössern, da ab einer gewissen Anzahl 
ganz einfach der Speicherverbrauch der Funktion kleiner wird als all die 
ganzen Leerzeichen in den Strings zusammen.

Man muss also immer abwägen was es braucht. Prinzipiell ist es aber eine 
gute Idee wenn man sich mal hinsetzt und seine eigene LCD Bibliothek 
schreibt mit allem, was einem so einfällt. Die benutzt man dann als 
Vorlage, kopiert sie in das nächste Projekt, und löscht dann im Projekt 
die Sachen die man nicht braucht. So schreibt man sich den Kram einmal 
und kann immer wieder darauf zurückgreifen.

Grüße,

Chris

von Sebastian (Gast)


Lesenswert?

werde das einfach so machen mit der gleichen Länge, das reicht für meine 
Zwecke total aus.

Dann bleibt nur noch das blinken vom anfang: ich muss zu Beginn meiner 
main das LCD einmal initialisieren, d.h. die LCD Init aufrufen. Darin 
enthalten ist, das LCD clear zu machen. Kann ich dem Programm irgendwie 
sagen, dass der bitte die Init nur einmal zu Beginn ausführt und danach 
nur noch den Rest macht?
hab das gestern schon mal mit einer while-Schleife versucht, aber das 
hat dann ganz komische Dinge gemacht. Alles, aber nicht das, was ich 
gerne wollte...

von Christian K. (Firma: Atelier Klippel) (mamalala)


Lesenswert?

Sebastian schrieb:
> werde das einfach so machen mit der gleichen Länge, das reicht für meine
> Zwecke total aus.
>
> Dann bleibt nur noch das blinken vom anfang: ich muss zu Beginn meiner
> main das LCD einmal initialisieren, d.h. die LCD Init aufrufen. Darin
> enthalten ist, das LCD clear zu machen. Kann ich dem Programm irgendwie
> sagen, dass der bitte die Init nur einmal zu Beginn ausführt und danach
> nur noch den Rest macht?
> hab das gestern schon mal mit einer while-Schleife versucht, aber das
> hat dann ganz komische Dinge gemacht. Alles, aber nicht das, was ich
> gerne wollte...

z.B.:
1
void main(void)
2
{
3
    pic_init();  // Initilaisieren des Chips, z.B. Port-Register, etc.
4
    lcd_init();  // Initialisieren des LCD
5
6
    .... (weiterer, einmalig auszuführender Code hier)
7
8
    while(1)  // Endlosschleife des Hauptprograms
9
    {
10
        .... (Haupt-Programmlogik hier)
11
    }
12
}

Grüße,

Chris

Edit: Wie Üblich sind die Funktionen in dem Beispiel von Dir zu 
schreiben ;)

von Sebastian (Gast)


Lesenswert?

danke Chris,
habe es gerade bevor ich deinen Post gelesen habe genau so umgesetzt und 
die Init existier in selbst erstellt bereits ;-)

jetzt ist das blinken tatsächlich weg und ich durchlaufe die Inits nicht 
mit dem Hauptpogramm noch mal.

Jetzt ist das LCD also endgültig lauffähig und ich kann mich um meine 
restlichen Programmteile kümmern. :-)

Vielen Dank für Eure Unterstützung,

Sebastian

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.