www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Und wieder ein LCD Problem (Schwarze Kasten)


Autor: cpehonk (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,
ich brauche auch noch mal Rat & Tat bei dem Thema LCD:
Habe an einem at89C52 ein LCD (162A von Reichelt, KS 0070B) 
angeschlossen und will es im 4-Bit Modus betreiben. Den Quellkode habe 
ich beigefügt.
"SetDigit" gibt einfach an Port 1 für ein Doppel-7-Segment eine Zahl aus 
(Debugging light).
Verbunden sind:
AT89C52         LCD
P0.4            DB4
P0.5            DB5
P0.6            DB6
P0.7            DB7

P0.3            RS
P0.2            E

                R/W, DB0-DB3 auf GND
                Vdd = +5V, Vee über 10K Poti zwischen +5V und GND

Timing erzeuge ich via 16-Bit Timer 0.
Aber ich bekomme anscheinend die Initialisierung nicht hin. Sehe nach 
wie vor nur eine komplette Zeile schwarzer Kästchen. Habe gelesen, dies 
weise auf die fehlende Initialisierung hin. Was aber ist hier falsch ?

Bin für Euren Rat dankbar !!

Viele Grüße
Christoph

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht Initialisiert, oder es ist kaputt.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
VSS (Pin 1) muß auch noch auf GND

Autor: cpehonk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, Pin 1 des LCD ist auch an GND gelegt. Sorry, hatte ich nicht dazu 
geschrieben.
Da ich sowohl mit einem 161A als auch mit einem 162A nur die schwarzen 
Felder sehe, ist das Ding sicherlich nicht kaputt, sondern nicht 
initialisiert. Aber da liegt ja auch mein Problem. Laut Datenblatt alles 
richtig - nur funktionieren will es nicht. Vielleicht seht Ihr ja den 
Fehler ...

Viele Grüße
Christoph

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn die Sequenz stimmt, würde ich einfach mal alle Zeiten mal 10 
nehmen. Wenn du zu langsam bist, langweilt sich das LCD, spielt aber 
ansonsten mit. Bist du aber zu schnell ....

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du nach jedem senden von Daten an das LCD auch das Enable Signal 
von High auf Low wechseln lassen? Ansonsten übernimmt er die Daten ja 
nicht.

Autor: cpehonk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Werde das mit den Zeiten mal ausprobieren. Ich gehe bei "Chip Enable" 
von Active-Hi aus, also lasse ich ansonsten das Signal auf "0" liegen.
Hier der C-Code Ausschnitt:

void LcdClock(unsigned char val)
{
  LCD_OUT = ( val & LCD_VALUE ) ;
  _nop_() ;
  _nop_()  ;
  LCD_OUT = ( val & LCD_VALUE ) | LCD_E ;
  _nop_() ;
  _nop_() ;
  _nop_() ;
  _nop_() ;
  LCD_OUT = ( val & LCD_VALUE ) ;
}

Habe einen Quarz von 12 MHz am C52, damit sollten also ca. 330 ns 
vergehen, bevor E wieder von Hi auf Lo geht. Lt. Datenblatt reicht eine 
Flankendauer von 220 ns aus.
Verflixte kleine Biester ...

Christoph

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Werde das mit den Zeiten mal ausprobieren. Ich gehe bei "Chip Enable"
>von Active-Hi aus, also lasse ich ansonsten das Signal auf "0" liegen.
>Hier der C-Code Ausschnitt:

Die Zeit für denn Wechsel von High nach low ist zu gering. Ich habe bei 
einem 4MHz Quarz 5us benötigt um eine korrekte Funktion zu ermöglichen. 
Erhöhe diese also mal Testweise auf 10us und gehe dann Stück für Stück 
runter

Autor: cpehonk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja, ...

Ich habe jetzt in die Lo -> Hi -> Lo Schleife für "E" ein Delay von mehr 
als 50µs gesetzt ... ohne Erfolg. Auch die anderen Timings habe ich 
verlängert. Alles ohne Erfolg.
Habe auch lange für das DCF77-Modul von Reichelt gebraucht, aber dank 
der Verstärkerschaltung funzt das wenigstens jetzt super.

Da muss beim LCD also noch ein anderer "dicker" Fehler sein ...

Viele Grüße
Christoph

Autor: micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es kann auch die Kontrastspannung falsch sein. Hast Du da ein Poti drin?
http://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD

Eventuell ist auch der Duty-Cycle in der initalisierung falsch.

Autor: cpehonk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Kontrast-Spannung regle ich über das oben beschriebene 10K Poti.
Aber irgendwie will das Ding so gar nicht.

Duty-Cycle derzeit ist (E = Lo als Ausgangssituation):

delay 50 µs, dann Daten schreiben mit E = Hi, 50 µs warten, E = Lo

Muss man ggfs. einen bestimmten Port beim 89C52 verwenden ?
Ich nutze derzeit Port 0. Vielleicht reicht ja auch der Pin-Ausgang 
nicht ?

Autor: schudi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Christoph,

Port 0 ist meines wissens open Drain. Hast Du auch alle Pins mit Pull Up 
Widerständen beschaltet?

Grüße

Lothar

Autor: Werner Freytag (frewer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

an Deiner Stelle würde ich die Library von Fleury benutzen, die für das 
LCD einen kompletten Set von Routinen beinhaltet, die bestens 
funktionieren. Dann brauchst Du im Hauptprogramm nur noch LCD_init() 
aufrufen und alles ist gegessen. Davor natürlich sind die Vereinbarungen 
von Port und Pin in der zugehörigen Header-Datei einzustellen und 
natürlich die Osz-Frequenz. Bei Fleury ist alles drin mit der Ausnahme 
des Auslesens von Daten aus dem LCD-DRAM.
mfG
Werner

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Bei Fleury ist alles drin mit der Ausnahme
>des Auslesens von Daten aus dem LCD-DRAM.

Was hat Fleury mit 89C52 zu tun? Richtig! Gar nichts.

Autor: cpehonk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit dem Open-Drain ist ein guter Hinweis. Natürlich habe ich keine 
Pull-Ups davor. Wieviel K sollten es sein ? 10 K ?

Die Lib von Fleury habe ich mir angesehen und auch versucht, anzupassen. 
Ist aber, da nicht direkt (wie Holger geschrieben hat) für den C52 sehr 
mühsam.

Viele Grüße
Christoph

Autor: Steffen K. (steffen3)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als pull-up würde ich irgendwas zwischen 4k7 und 10k nehmen(ohne 
gewähr;-))

Autor: cpehonk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe es mal fix mit Port 2 versucht. War leider auch nicht besser.
(Ohne Pull-Ups). Der Fehler liegt wohl doch eher im Sourcecode begraben 
...

Viele Grüße
Christoph

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LCD_OUT = ( val & LCD_VALUE ) ;

Darüber solltest du noch mal ausgiebig nachdenken.
Was steht da im Endeffekt?

  LCD_OUT = ( val & 0xF8 ) ;

Bei val = 0x30 ist LCD_OUT auch 0x30.
Da du ja nur das Highnibble ausgibst könntest
du auch gleich schreiben:

  LCD_OUT = val ;

Wenn du LCD_RS setzen möchtest musst du das anders machen.
Kleiner Tip:
Port lesen in temp
Bits in temp ändern (Maskieren, löschen, verodern)
temp auf Port ausgeben

Autor: cpehonk (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Danke für den Tipp, Holger.

Hatte dies auch schon als Schwachpunkt entdeckt und die Funktionen neu 
geschrieben. Der geänderte Sourcecode ist im Anhang.
Geht aber immer noch nicht ... verfl... !!

Viele Grüße
Christoph

Autor: Bernhard M. (boregard)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

du hast:
#define  LCD_VALUE  (0xF0 | LCD_RS | LCD_RW)
und dann
LCD_OUT = ( val & LCD_VALUE ) ;
wobei val z.B. 0x30 beim init ist.
Da wird aber dann LCD_RS und LCD_RW nie gesetzt, die werden ja durch das 
& wieder gelöscht...

Wie wäre es mit:
#define  LCD_VALUE(a)  ((a) & 0xF0) | LCD_RS | LCD_RW)
und dann entsprechend:
LCD_OUT = LCD_VALUE (val) ;

Das könnte eher gehen, oder?

Gruß,
Boregard

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die meisten Probleme treten auf, weil die Leute versuchen, immer den 
ganzen Port zu setzen und sich dann in den AND/ORs verheddern.

Der 8051 hat wunderschöne Bitbefehle, damit gehts viel leichter:

http://www.mikrocontroller.net/attachment/30300/lcd_drv.zip

Dieses Beispiel läßt sich leicht auf den 8051 portieren.
Das Bitmacro braucht man nicht, der Keil C51 hat schon einen 
sbit-Befehl.
Also einfach diesen benutzen.
Die Directionbit braucht man auch nicht, also weglassen.
Nur das Delay-Macro muß man sich selber schreiben (kann man mit dem 
Timer machen).

Und P0 ohne pullups geht auf garkeinen Fall.


Peter

Autor: cpehonk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Boregard,

LCD_E wird in der "LcdClock" Routine entsprechend gesetzt ( "LCD_OUT = ( 
val & LCD_VALUE ) | LCD_E ; "). Die Werte für LCD_RS und LCD_RW (sofern 
benötigt), kommen in den LcdWriteChar() und LcdWriteCmd() Funktionen zum 
Einsatz (z.B. LcdWriteChar(): "LcdClock( ( dval & 0xF0 ) | LCD_RS ) ;").
Ich schaue mir das auch noch einmal an, aber per Debug schien es erstmal 
in Ordnung zu sein.

@Peter: Werde mal Dein angehängtes Archiv anschauen. Mit den 
Bit-Befehlen hast Du recht. Hatte nur erst einmal keine Lust, Assembler 
+ C zu mischen ...

Viele Grüße
Christoph

Autor: cpehonk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,

habe die Files von Dir angepasst. Leider ohne Erfolg. Habe langsam das 
Gefühl, dass das Problem im Berechnen der Delays liegt. Hat jemand 
fertige Routinen für "_delay_us" oder "_delay_ms" für einen C52 mit 12 
MHz Quarz ?

Viele Grüße
Christoph

Autor: cpehonk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zum Abschluss:

Bin zurück auf 8-Bit Breite gegangen und habe die Steuerleitungen auf 
einen anderen Port gelegt. Mit leicht modifiziertem Delay läuft das 
Display jetzt problemlos.

Danke nochmal an Alle, die gute Ratschläge parat hatten und mir geholfen 
haben.

Viele Grüße
Christoph

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.