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