Forum: Compiler & IDEs prüfen ob LCD-Display angeschlossen


von Erik H. (agutanus)


Angehängte Dateien:

Lesenswert?

Ich habe ein Programm zur Lüftersteuerung geschrieben, was auch an sich 
super läuft.
Allerdings ist das ganze darauf ausgelegt ohne Display zu laufen, da 
dieses lediglich zum Ändern der Einstellungen benötigt wird.

Sobald ich aber den µC ohne Display starte passiert einfach nichts! Ich 
nehme an, dass in den Funktionen zum Initialisieren des Displays 
irgendwelche Warteschleifen auf Antwort warten und so das Programm 
aufhalten.

Jetzt suche ich eine Möglichkeit zu erkennen, ob das Display 
angeschlossen ist, um eventuell beim Starten alle Display-Befehle zu 
deaktivieren.

von Karl H. (kbuchegg)


Lesenswert?

Erik H. schrieb:

> Sobald ich aber den µC ohne Display starte passiert einfach nichts! Ich
> nehme an, dass in den Funktionen zum Initialisieren des Displays
> irgendwelche Warteschleifen auf Antwort warten und so das Programm
> aufhalten.

Warteschleifen nicht.

Du benutzt die LCD Routinen vom Peter Fleury.
Die lesen aktiv das Busy Flag aus und warten solange bis das LCD 
antwortet.
Zuständig ist die zentrale Routine lcd_waitbusy(void).
Die ersetzt du einfach durch eine delay Funktionalität, die ein paar ms 
wartet.

Du kannst dann zwar vom LCD nichts mehr auslesen, da man das aber 
meistens sowieso nicht macht, ist das kein großer Verlust.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Karl heinz Buchegger schrieb:
> Die ersetzt du einfach durch eine delay Funktionalität, die ein paar ms
> wartet.

Besser noch: das erste Busywait wird gepollt mit zeitlicher
Überwachung.  Wenn es nach endlicher Zeit (also ein gutes Stück
mehr als das, was laut Datenblatt normal wäre) immer noch nicht
"unbusy" ist, dann wird in der Applikation ein Flag gesetzt, dass
das LC-Display nicht angeschlossen ist, und künftig keine weiteren
Ausgabeversuche mehr gemacht.

von Erik H. (agutanus)


Lesenswert?

@dl8dtl: sowas in der Art hatte ich mir auch gedacht!
Im Programm laufen fast alle Ausgaben über 2 bis 3 Funktionen. Ich werde 
dort einfach das "Display-Flag" abfragen und dann gegebenenfalls die 
Ausgabe überspringen.

unter "lcd_waitbusy()" ist diese Schleife zu finden:
1
/* wait until busy flag is cleared */
2
    while ( (c=lcd_read(0)) & (1<<LCD_BUSY)) {}

könnte ich das so lösen?:
1
/* check for display */
2
    uint8_t counter = 0; 
3
    while ( ((c=lcd_read(0)) & (1<<LCD_BUSY)) && (counter < 50) )
4
    {
5
        delay(100);
6
        counter++;
7
    }
8
    // nach 5 ms keine Antwort erhalten: ohne Display fortfahren
9
    if(counter == 50)
10
        display_flag = 0;   // mit 1 initialisiert

Ich habe gerade kein Datenblatt zur Hand um eine geeignete Zeit heraus 
zu suchen, aber 5 ms Wartezeit erscheint mir lang genug.

von Karl H. (kbuchegg)


Lesenswert?

Erik H. schrieb:
> @dl8dtl: sowas in der Art hatte ich mir auch gedacht!
> Im Programm laufen fast alle Ausgaben über 2 bis 3 Funktionen. Ich werde
> dort einfach das "Display-Flag" abfragen und dann gegebenenfalls die
> Ausgabe überspringen.

Wenn du schon in die Fleury Funktionen eingreifst, dann würde ich die 
Abfrage auf LCD vorhanden auch in diese Funktionen hineinziehen.
Ist schöner und universeller, als deinen Anwendungscode mit Abfragen zu 
spicken. Und: da kannst die Abfrage nicht vergessen.

> könnte ich das so lösen?:

klingt fürs erste vernünftig

> zu suchen, aber 5 ms Wartezeit erscheint mir lang genug.

klingt gut.

von Erik H. (agutanus)


Angehängte Dateien:

Lesenswert?

Hab die lcd.h und lcd.c für meine Zwecke angepasst:
in der lcd_init-Funktion ist nun folgende Abfrage enthalten
1
/* check if display is connected */
2
    uint8_t counter = 0;
3
    while ( ((c=lcd_read(0)) & (1<<LCD_BUSY)) && (counter < 50) )
4
    {
5
        delay(100);
6
        counter++;
7
    }
8
    if(counter == 50)    // busy-flag not cleared after 5 ms
9
    {
10
        lcd_flag = 0;    // no display connected
11
        return;
12
    }

in allen von mir benutzten Funktionen folgende Abfrage:
(put_c, put_s, gotoxy, clrscr)
1
    if(lcd_flag == 0)
2
        return;

lcd_flag ist in der lcd_edit.h (letzte Zeile) initialisiert.

von Erik H. (agutanus)


Lesenswert?

Nachtrag:
mir ist noch was eingefallen:
das Display hat doch sicherlich Pullup oder Pulldown-Widerstände an den 
Datenleitungen. Wenn dann noch ein 1 MOhm Widerstand an einen µC-Pin 
(Datenleitung) an das entgegengesetzte Potenzial gelegt wird könnte man 
noch vor der Display-Initialisierung den Zustand abfragen um zu 
erkennen, ob eines angeschlossen ist.

von Erik H. (agutanus)


Lesenswert?

Nach fast 3 Stunden Fehlersuche und vergeblichen Tests konnte ich noch 
immer nicht herausfinden, warum die oben beschriebene Schleife (check if 
display is connected) niemals den 50. Durchlauf erreicht...

Auf jeden Fall habe ich es dann innerhalb einer halben Stunde nach der 
im letzten Beitrag beschriebenen Methode probiert - und es funktioniert 
perfekt!
Die RS und RW-Pins sind beim Anschließen des Displays immer HIGH. Habe 
also den RS-Pin mit 1 MOhm gegen Masse geschaltet, sodass ich vor der 
Display-Initialisierung einfach dessen Status abfrage und in "lcd_flag" 
speichere. Jede lcd-Funktion enthält dann noch die Abfrage
1
if(lcd_flag == 0)
2
   return;
sodass diese Funktionen bei Aufruf direkt wieder verlassen werden.

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.