Hallo
Ich bin gerade am Anfang des C Lernens und habe nun ein LCD an meinen
Mega128 angeschlossen. Ich verwende die Headerdatei von Peter Fleury und
ein Beispielprogramm von ihm. Doch am LCD wird nichts angezeigt. In
einem C-Buch habe ich eine Logik gesehen, die zwischen Rd, Wr und E
angeschlossen ist. Muss ich auch so eine Logik einbauen oder reicht es
wenn ich das LCD direkt über 4 Bit mid dem Mega128 verbinde?
Der Compiler zeigt nur immer "undefined reference" an.
Wenn der Compiler "undefined reference" anzeigt, dann ist das eine
Fehlermeldung! D.h. das Programm wird gar nicht korrekt kompiliert, und
das hat nichts mit irgendwelcher Logik zu tun. Wenn Du mal die komplette
Fehlermeldung posten könntest, wäre das eine große Hilfe!
Ich habe ein 4x20 LCD das kommpatibel zum HD44780 ist. Ich habe nun im
Forum gelesen dass ich die LCD.c und die testLCD.c einbinden muss.
Dadurch sind auch die Fehler verschwunden. Doch das LCD zeigt immer noch
nichts an. Ich habe das LCD an Porta und habe die LCD.h Datei so
umgeänder. Die RW leitung habe ich auf GND ich hoffe dass dies so auch
funktioniert.
Nach dieser Anleitung bin ich vorgegangen. Doch in der LCD.h steht etwas
von Port RW. Ich habe in C noch nicht so viel Ahnung. Deshalb kann ich
mid den LCD und testLCD Datein noch nicht sehr viel anfangen. Aber mit
irgendetwas muss man ja auch mal beginnen C zu lernen. Muss ich da noch
etwas umstellen?
> Doch das LCD zeigt immer noch nichts an.
Gar nichts?
-> Kontrastspannung stimmt nicht oder Versorgungsspannung
ist nicht angeschlossen
LCD zeigt in der 1. und 3. Zeile eine Reihe von 'Balken'
-> Kontrastspannung stimmt und du hast ein Problem
in der Initialisierung
Welches ist es nun?
Also was denn jetzt, Fehlermeldung oder nicht?
Ich habe mit der vielgerühmten Fleury-Lib noch nicht gearbeitet, meine
mich aber erinnern zu können, dass man erstmal angeben muss, an welchen
Pins das Display überhaupt angeschlossen ist, sonst schreiben die
Funktionen ins Nirvana und am Display kommt nix an. Und diese Angaben
sehe ich in Deinem Programm nicht.
dies steht ja in der h. Datei, an welche Pins dies angeschlossen ist.
Ist dies Beispiel von Peter Fleury nicht so gut? gibts eventuell andere
Beispiele die man besser verstehen kann.
Ich glaube es liegt am RW anschluss. ich habe gelesen, dass diese Lib
die Busy-Kontrolle unterstützt. Ich probiere dies jetzt mal aus obes
dann läuft. Doch ist es auch möglich dies ohne die RW leitung zum laufen
zum bringen? Denn ich habe ein Board wo dieser Pin auf GND ist.
> ich habe gelesen, dass diese Lib> die Busy-Kontrolle unterstützt.> Denn ich habe ein Board wo dieser Pin auf GND ist.
Dann ist alles klar.
Die Fleury Lib braucht die RW Leitung. Die wartet
und wartet und wartet und wartet ... darauf das
das LCD mittels Busy Flag mitteilt, dass es bereit
ist wieder Daten anzunehmen.
>Aber mich würde doch interresieren obs nicht doch ohne gehen würde?
Nennt sich die Leitung nicht "/RW"?
Ein "/" vor einem Buchstaben bedeutet in der Regel, dass die damit
zusammenhängende Funktion bei L-Pegel aktiv ist.
Du versuchst also die ganze Zeit etwas in ein LCD zu schreiben, das gar
nicht deine Daten haben will, sondern selber welche loswerden will.
@Rahul-Oskar:
Nö, die Leitung heißt R//W (der zweite "/" soll die Negation sein...)
und kann, wenn kein Busy-Read gemacht werden soll, auf GND gelegt werden
(also permanent Write).
Michael wrote:
> nun läuft das LCD. es lag doch an der RW-Leitung. Danke für eure Hilfe.> Aber mich würde doch interresieren obs nicht doch ohne gehen würde?
Klar. Würde auch gehen.
Im Fleury Code gibt es eine Funktion für das Abfragen
des Busy Flags. Die musst du umschreiben: Von 'Warten
auf das Busy Flag' zu 'Eine konstante Zeitdauer warten'
so nun habe ich in der "static uint8_t lcd_waitbusy(void)" nur noch
_delay_ms(50); stehen. Bis jetzt funktionierts auch. Soweit ich den Code
verstanden habe muss ich sonst nichts mehr umkstellen. wie weit kann ich
denn mit dem delay runter gehnen. Hat das was mit der Datadelay time auf
sich oder auf welche Zeit muss ich da schauen im Datenblatt?
> Soweit ich den Code verstanden habe muss ich sonst nichts mehr> umkstellen.
Richtig
> wie weit kann ich denn mit dem delay runter gehnen.
Probiers einfach aus. Ich würde mal schätzen, dass ein
Clear-Display am längsten dauert. Also ständig
Clear Display und einen Text hinten nach schicken.
Wenn der Text nicht mehr vollständig angezeigt wird,
dann wars zu kurz. Von der Zeitdauer dann noch
ein bischen was extra dazugeben (zur Sicherheit).
Danke für deine Antwort. In dieser Waitbusy Schleife wird aber auch noch
der addresscounter abgefragt. Brauche ich den unbedingt? weil
funktionieren tuts auch ohne?
Hast Du kein Datenblatt von dem Display? Da steht eigentlich immer drin,
welche Stellen welche Adressen haben. Das ist z.T. auch
herstellerabhängig. Bei den meisten 4-zeiligen Displays sind die 1. und
3. Zeile eine logische Zeile und die 2. und 4. Zeile genauso. Wenn Du
also die erste Zeile schreibst und dann am Ende weiterschreibst, müsste
eigentlich in der 3. Zeile weitergeschrieben werden.
Das Datenblatt habe ich schon aber ich kann mit den Adressen nicht viel
anfangen. Außerdem muss es doch auch eine andere Möglichkeit geben in
die anderen Zeilen zu schreiben. Die Adressen stehen schon in der LCD.h
drin.
/* put string to display (line 1) with linefeed */
lcd_puts("LCD Test Line 1\n");
/* cursor is now on second line, write second line */
lcd_puts("Line 2");
warum ist dann Line 2 in der 2. Zeile?
Wenn die Fleury-Lib (mit der ich wie gesagt nicht arbeite, weil ich
meine LCD-Routinen i.d.R. selber schreibe) das mit den Adressen alles
schon drin hat, dann musst Du sicher irgendwo einstellen, dass Du ein
4-zeiliges Display benutzt (wenn Du es noch nicht getan hast), denn die
zeichnen sich wie gesagt meist dadurch aus, dass sie eigentlich (von der
Adressierung her) nur zweizeilig sind. Die 4 Zeilen muss die Software
bereitstellen.
eingestellt habe ich die 4 Zeilen in der LCD.h. Aber wie mache ich das
dann wenn ich gleich in einer bestimmten Zeile beginnen will. im
Beispiel steht nur lcd_puts, dann schreibt er dies in die erste Zeile.
Woher weis der Controller aber dass er dies in die 1. Zeile schreiben
soll? Ich kapier nicht ganz wie der dann in die nächste Zeile springt.
Dann musst Du dem Display-Controller mit der entsprechenden Funktion
mitteilen, an welche Adresse er das nächste Zeichen schreiben soll. Gibt
es zu der Fleury-lib keine Dokumentation, in der das drinsteht? Sollte
mich schwer wundern. Ich glaub, die Funktion, die Du brauchst heißt
"lcd_gotoxy". Da kannst Du eine Zeilen- und Spaltennummer angeben.
Aber tu Dir einen Gefallen und lies Dir die Doku durch! Es ist nicht
Sinn des Forums, hier den Leuten irgendwelche Informationen vorzubeten,
die sie ohne viel Aufwand aus anderen Quellen viel schneller erhalten
können. Und ich meine, mich erinnern zu können, des öfteren gelesen zu
haben, dass die Fleury-lib recht gut dokumentiert sei.
> /* put string to display (line 1) with linefeed */> lcd_puts("LCD Test Line 1\n");>> /* cursor is now on second line, write second line */> lcd_puts("Line 2");>> warum ist dann Line 2 in der 2. Zeile?
weil hier
lcd_puts("LCD Test Line 1\n");
^
|
Ein Zeilenvorschub gemacht wird. Und wenn mich nicht alles
täuscht dann werte Peter Fleury dieses Zeichen '\n' auch
aus und setzt den Cursor in die nächste Zeile, so wie
es sein soll. Das Einzige was er noch nicht macht, ist
das Display scrollen, wenn man unten rauskommt. Frag
mich aber nicht was in diesem Fall passiert.
Ansonsten:
lcd_gotoxy( Spalte, Zeile );
schickt den Cursor in eine bestimmte Zeile und dort
auf eine bestimmte Spalte.
Ich würde dir empfehlen, dass du mal in das lcd.h
hineinschaust. Dort sind unter anderem auch alle
Funktionen drinn (und auch kurz beschrieben) die
dir so zur Verfügung stehen. So wie es in C üblich ist.
Wenn du die Fleury Lib am laufen hast und auch alles
richtig eingestellt ist, kannst du das Datenblatt zum LCD
vergessen. Fast. Mit einer Ausnahme: Wenn du selbst Zeichen
definieren willst. Aber ansonsten brauchst du das Ding
nicht mehr. Und das ist auch gut, so denn das ist der Sinn
einer fertigen Library.
Bald kenn ich die Lib auswendig. Mit \n funktioniert dies auch wunderbar
von der 1. auf die 2. Zeile. Doch auf die dritte springt er nicht. Ich
nehme mir jetzt mal den addressCounter unter die Lupe.
Da hilft mir die ganze Doku nichts. Nun habe ichs doch nochmal mid der
RW version ausprobiert und mit der klapt es auch einwandfrei. Das
Programm benötigt den return address counter. Aber ich weis noch nicht
wie ich das umschreiben kann, weil ich in der lcd_read Funktion nichts
vom addressCounter finde.
> Aber ich weis noch nicht wie ich das umschreiben kann, weil ich> in der lcd_read Funktion nichts vom addressCounter finde.
Ist doch nicht so schwer das zu finden.
Das hier ist die Busy Wait Funktion:
1
staticuint8_tlcd_waitbusy(void)
2
3
{
4
registeruint8_tc;
5
6
/* wait until busy flag is cleared */
7
while((c=lcd_read(0))&(1<<LCD_BUSY)){}
8
9
/* the address counter is updated 4us after the busy flag is cleared */
10
delay(2);
11
12
/* now read the address counter */
13
return(lcd_read(0));// return address counter
14
15
}/* lcd_waitbusy */
Die liest vom LCD aus, wo sich zur Zeit der Cursor befindet
und retourniert das Ergebnis.
Daher müssen wir weiter suchen, wo lcd_waitbusy benutzt
wird. Irgendwo wird es einen Aufruf der Funktion geben,
bei dem der Returnwert auch benutzt wird.
Aha. Es gibt insgesamt zwei Stück davon. Hier sind sie
1
intlcd_getxy(void)
2
{
3
returnlcd_waitbusy();
4
}
Den verfolgen wir etwas später weiter, was es mit diesem
Aufruf auf sich hat. Interessanter ist der 2.te
1
voidlcd_putc(charc)
2
{
3
uint8_tpos;
4
5
6
pos=lcd_waitbusy();// read busy-flag and address counter
7
if(c=='\n')
8
{
9
lcd_newline(pos);
10
}
11
else
12
{
13
#if LCD_WRAP_LINES==1
14
...
Da hebn wirs doch schon. Die Cursorposition vom lcd_waitbusy()
wird in pos gespeichert. Wenn das nächste auszugebende Zeichen
ein '\n' ist, dann wird die Funktion lcd_newline mit eben dieser
Cursorposition aufgerufen.
Was passiert in lcd_newline() ?
Der einlietende Kommentar sagt eigentlich schon alles:
Der Cursor wird an den Anfang der nächsten Zeile bewegt
bzw. zur ersten Zeile, wenn er ganz unten war.
Und genau das macht dann auch der Code.
Soweit zur Analyse des bestehenden. Die Frage die sich
jetzt stellt lautet: Wenn du vom Display nicht lesen
kannst, kannst du logischerweise auch nicht feststellen
wo am LCD der Cursor tatsächlich ist. Welche Möglichkeiten
hast du statt dessen
* Du verzichtest auf das Weiterschalten mittels '\n'.
Ist kein Beinbruch. Es gibt ja immer noch die Möglichkeit
mittels gotoxy den Cursor direkt zu positionieren
* Du benutzt wieder die RW Leitung
* Du führst selbst Buch darüber wo den der Cursor am LCD sein
müsste und benutzt dies anstelle der Abfrage des LCD. Dazu musst
du natürlich in allen Funktionen die die Cursorposition
verändern eingreifen und dasselbe was das Display mit
seinem Cursor macht auch in deiner Variable nachziehen.
Ist zwar etwas Aufwand, würde aber gehen. Zumindest solange
bis der erste Schlauberger das LCD unter Umgehung deiner
angepassten Library auf das Display zugreift.
Hallo
Bin seit ein paar Wochen mit dem gleichen Problem beschäftigt. Also
meine LCD ist im 4 bit modus ohne den Busy auszulesen. Bei mit besteht
nicht die Möglichkeit das umzuändern deshalb währe meine Frage ob du
(Michael) dein angepasstes Programm hier rein setzen kannst.