PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Probleme mit] HD44780-LCD ansteuern



E. Hakennase
21.08.2008, 11:47
Hallo zusammen!
Ich bin ein Einsteiger im Gebiet MCs (AVR).
Mein aktuelles Projekt beinhaltet, ein LCD (HD 44780-kompatibel) mit einem ATmega32 anzusteuern.
Ich verwende dazu ein WINTEK WD-C2704M-1HNN (http://www.pollin.de/shop/detail.php?pg=NQ==&a=NzY3OTc4OTk=) mit 4*27 Zeichen im 4-bit Modus.
Meine Verschaltung liegt dabei an PortC.
Die Pinbelegung ist wiefolgt:
Db4 = Portc.4
Db5 = Portc.5
Db6 = Portc.6
Db7 = Portc.7
E = Portc.1
E2 = Portc.0
Rs = Portc.3
DB0-DB3 liegen auf Ground

RW liegt ursprünglich auf PortC.2, habe ich aber testhalber derzeit auf Ground, es ergibt sich aber derzeit kein beobachtbarer Unterschied.
Ich habe im Programm das RN-Wissen genutzt. Der Code ist folgender:
'$lib "lcd4e2.lbx"
$regfile = "m32def.dat"
$crystal = 1000000

Config Lcd = 40 * 4
Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portc.1 , E2 = Portc.0 , Rs = Portc.3

Dim ___lcde As Byte

___lcde = 0

'Initlcd
Cls
Do
Upperline
Locate 1 , 3
Lcd "Hallo Welt"
Waitms 1000
Locate 1 , 3
Lcd "Hello World"
Waitms 1000
Loop

End

Was ich jetzt beobachte ist, dass das LCD alle Felder der jeweils Controllerbezogenen oberen Zeile (d.h. Zeile 1 und 3) komplett dunkel einfärbt und die jeweils untere Zeile (2 und 4) komplett hell.

Dies scheint der Zustand des LCDs zu sein, wenn schlichtweg nur Spannung anliegt, weil das LCD während des Programmierens und auch sonst immer das anzeigt.

Der ATmega32 an sich tut korrekt, denn ich habe an ihm schon andere Sachen (LED blinkend,..) vor kurzem ausgeführt. D.h. er wird auch korrekt programmiert und tut.

Was mache ich falsch?

Gruß
E. Hakennase

Sauerbruch
21.08.2008, 12:13
...und am Kontrast-Eingang liegt auch eine regelbare Spannung?

E. Hakennase
21.08.2008, 12:17
Ja, das funktioniert. Hatte den Kontrast erst zu niedrig, habe ihn jetzt aber so eingestellt, das man gut sehen kann

Sauerbruch
21.08.2008, 13:34
O.k., dann ist es das schon mal nicht.

Zu ____lcde hab ich einen interessanten Link gefunden:

https://www.roboternetz.de/phpBB2/export.php?mode=txt&t=6676 - vielleicht liegt dort ja des Lösels Rätsung =P~

E. Hakennase
21.08.2008, 16:12
Ich meine nach Tests nein. Denn einen wirklichen Unterschied kann ich nicht ausmachen.
Ich habe derzeit zwei Punkte, an denen ich eine Möglichkeit sehe, dass es hakt.
Die erste (und meine stärkste) ist, dass die Zuweisung von den Pins nicht richtig klappt. In der Hilfe zur lcd4e2.lbx steht, dass ich das nur an PortB mit Standardbelegung betreiben könnte. Für alles andere müsste ich die Source der lib ändern, was ich mit der Demoversion nicht kann.

Andererseits gibts diese config lcdpin = Port -Lösung, in der ich laut Hilfe alles festlegen kann.
Irgendwas passt nicht.

Ich habe jetzt mal mein Display von PortC nach PortB in Standardbelegung umgesteckt, leider noch ohne Erfolg.
Das nervige dabei ist aber, dass mein ISP-Adapter aber an MISO/MOSI hängt, der ja auf PortB Platz nimmt. Das ständige rumgestecke auf dem Steckbrett ist nervig, geht aber noch. Später auf der Platine nimmer.

Das zweite ist, dass ich den MC derzeit mit 1 MHz betreibe. In den Demos sond immer 4 MHz angegeben. Von meinem Verständnis von den Displays dürfte dieser Geschwindigkeitsunterschied aber eigentlich nichts ausmachen, weil ich ja im Zweifelsfall immer ein Busy-flag oder ein wait habe.

linux_80
21.08.2008, 16:53
Hallo,

wenn man die "lcd4e2.lbx" verwendet ist es egal was man bei Config angibt, denn in der Lib sind die Ports fest auf PortB programmiert !


;Rs = PortB.0
;RW = PortB.1 we dont use the R/W option of the LCD in this version so connect to ground
; E = PortB.2
;E2 = PortB.3 for lcd with 2 chips
;Db4 = PortB.4 the data bits must be in a nibble to save code
;Db5 = PortB.5
;Db6 = PortB.6
;Db7 = PortB.7

Beispiele dazu sind im Bascom-Verzeichnis unter Samples.
Mit ___lcde = 0 adressiert man den oberen Teil, mit ___lcde = 1 den unteren Teil des LCDs.

Mit 1MHz sollte es eigentlich schon gehen, hab das selber aber noch ned probiert. Bascom wertet das Busy-flag des LCD nicht aus, sondern wartet einfach eine gewisse Zeit.

Dnerb
21.08.2008, 19:31
Mit 1MHz sollte es eigentlich schon gehen, hab das selber aber noch ned probiert. Bascom wertet das Busy-flag des LCD nicht aus, sondern wartet einfach eine gewisse Zeit.

Die Taktfrequenz ist völlig egal solange sie richtig angegeben wird. Der Compiler baut eine Verzögerung entsprechend der Taktfrequenz in den Code ein.

E. Hakennase
21.08.2008, 21:51
Ok. Das dachte ich mir fast.
Habe ich mit dem Bascom in der Freeware-Version die Möglichkeit, das ganze auf den PortC umzumodeln (andere Library?)

Zu Testzwecken würde mir notfalls auch erstmal ein Controller reichen. (Aber was mache ich dann später?)

Dnerb
21.08.2008, 22:19
Hi,

ich habe es eine Lib gemacht.

Dazu habe ich hier im Forum, oder im Mikrocontroller.net Forum folgendes gefunden und auch so erfolgreich eingesetzt.

Leider weis ich nicht mehr wer der Autor war.

Also falls der Autor ein Problem damit hat das ich es hier darstelle, bitte melden!



Also so wie's ich jetzt gemacht hab, ist die Verdrahtung eigentlich
egal (im Gegensatz zur LBX!!). Man verdrahtet das Ganze wie ein
"normales" LCD, nur dass man eben zwei Controllerleitungen hat.
Dementsprechend bei "Config Lcdpin" auch den zweiten Controller
beachten !!

Wichtig ist, dass man, bevor das LCD konfiguriert wird eine Variable
"___lcdno" als Bit definiert! (mit der alias-Funktion kann man dann
noch einen schöneren Namen vergeben :-) ) Mit dieser Variablen steuert
man dann das Display.
Bei ___lcdno = 0 wird der Controller für die obere Hälfte ausgewählt,
bei ___lcdno = 1 der Controller für die untere Hälfte.

Beispiel:
.
.
.
Dim ___lcdno as Bit
Config Lcdpin = Pin, E = Portb.0 , E2 = Portb.1 , Rs = Portb.2 ,usw...
Config Lcd = 40*4
Initlcd
Cursor Off
.
.
.
das war's dann eigentlich auch schon :-)

Wenn man dann was auf's LCD schreiben will, zuerst den Controller
auswählen und dann ganz "normal" schreiben...

Beispiel:

___lcdno = 0
Locate 1 , 1
Lcd "dein Text" 'Text in Zeile 1
Locate 2 , 1
Lcd "Text" 'Text in Zeile 2

___lcdno = 1
Locate 1 , 1
Lcd "dein Text" 'Text in Zeile 3
...

-------------------

es gibt jetz noch ne Ergänzung bzw. änderung zu meiner Beschreibung!!

Es muss so lauten:
...
Config Lcd 40*4

___lcdno = 0 'ober Displayhälfte initialisieren
Initlcd
Cursor Off

___lcdno = 1 'untere Displayhälfte initialisieren
Initlcd
Cursor Off
...

so funktioniert's 100%


Gruß Bernd

E. Hakennase
22.08.2008, 08:19
Handelt es sich dabei jetzt um Quellcode zur Standardlibrary, oder ist das für eine Lib, die du nur noch nicht hochgeladen hast?

E. Hakennase
22.08.2008, 13:04
Soo,
ich habs jetzt nochmal damit versucht umzusetzen. Ich habe mal angenommen, dass die Standardlibrary genommen wird (also kein $lib sonstwas-Eintrag)
Leider auch dasselbe Ergebnis.

Ich poste zur Sicherheit hier mal den Schaltplanausschnitt mit Kommentaren, vielleicht liegt da ein Fehler drin begraben?

Kommentare zum Schaltplan:
Das IC ist ein Atmel ATmega32
Das Poti hat einen korrekten Wert (ich glaube 4,7k wars, Platine liegt nebenan), jedenfalls funktioniert die Kontrastfunktion
Der Wannenstecker zum LCD hat folgende Belegung laut Datenblatt:
1 GND
2 VDD +5V
3 Vo (Kontrastspannung)
4 RS
5 R/W
6 E1
7 E2
8-15 D0-D7


RW liegt per MC programmiert auf GND

linux_80
22.08.2008, 13:09
Hallo,
Beim letzten Satz stimmt noch was nicht, RW sollte auf Gnd liegen, und wenn das per Software eingestellt wird, muss man danach nochmal ein Initlcd aufrufen, damit das LCD initialisiert wird. Vorher gehts ja nicht, denn das RW ist evtl. auf High.

Du solltest so zumindest eine Hälfte des LCDs ans laufen bekommen.

E. Hakennase
22.08.2008, 13:22
Also genauer gesagt habe ich das so umgesetzt, dass ich PortC.2 (RW-Leitung) als Eingang mit Pullup Widerständen deklariert habe, um dann anschließend ohne Risiko eine Leitung von GND an den Pin legen zu können.
Denn wenn ich folgendes mache, erhalte ich mit beiden Zuständen 5V (trotz 0 oder 1 *grübel*)


config PortC.2 = output
PortC.2 = 0 'bzw 1


Der gesamte aktuelle code sieht so aus (der Vollständigkeit halber)



$regfile = "m32def.dat"
$crystal = 1000000

Dim ___lcdno As Bit
Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portc.1 , E2 = Portc.0 , Rs = Portc.3
Config Lcd = 40 * 4
Config Lcdmode = Port
Config Lcdbus = 4
Config Porta.7 = Output 'nicht relevant
Config Portc.2 = Input

Portc.2 = 1 'pullup widerstand ein

Waitms 1000

'Portc.2 = 1

___lcdno = 0

Initlcd
Cursor Off
Cls
Do
Porta.7 = 0 'LED-Blinker, nicht relevant
Locate 1 , 3
Lcd "Hallo Welt"
Waitms 1000
Porta.7 = 1 'LED-Blinker, nicht relevant
Locate 1 , 3
Lcd "Hello World"
Waitms 1000
Loop

End

Ich bin verwirrt :-k

linux_80
22.08.2008, 13:41
Du schreibst immer RS, es sollte die RW-Leitung auf Gnd gezogen werden, nicht per Pullup auf Vcc !
Deshalb den Port auf Output und eine 0 ausgeben, danach ein Initlcd.

E. Hakennase
24.08.2008, 13:44
Hallo linux_80,
ich hab gerade gemerkt, dass ich immer RS statt RW geschrieben habe, wie du richtig bemerkt hast. Ich habs korregiert und eigentlich immer von RW gesprochen (nur RS geschrieben). PortC.2 ist die RW Leitung.

Die Sache mit den Pullup-Widerständen habe ich nur versucht, weil ich es nicht schaffe, den Port auf GND zu bekommen. Wenn ich den als Output mit 0 konfiguriere, kann ich gegen Ground trotzdem 5V Potenzial messen.

Daher hatte ich mir gedacht, dass ich den Port mittels eines Kabels mit Ground verbinde und zur Sicherheit die Pullup-Widerstände einschalte, damit ich mir den MC nicht verbrate (kann das passieren?)

Gebracht hat es bisher aber nichts...

linux_80
24.08.2008, 16:50
Wenn Du die Leitung schon mit Gnd verbunden hast, lass den Pullup weg, denn da fliesst ja sonst nur ungenutzt Strom durch, wenn auch nicht viel.
Am besten garnicht mit dem µC verbinden, aber Eingang ist auch nicht schlecht.
Wenn Du da aber noch mehr als 0V messen kannst, stimmt was mit der Gnd-Verbindung nicht.

E. Hakennase
24.08.2008, 20:27
Also aktueller Stand ist, dass ich die Leitung jetzt endgültig auf GND gelegt habe, ohne was am MC zu machen. PortC.2 ist somit frei.

Ich kann, wie oben erwähnt den PortC.2 aber nicht korrekt steuern, das verwundert mich.

Also habe ich mir jetzt mal ein simples Programm draufgeladen, was einfach an PortC.2 eine LED zum blinken bringen soll. Sie leuchtet aber stattdessen nur schwach...

MC defekt?

Edit: Können "nur" einzelne Ports was abbekommen?

Dnerb
24.08.2008, 21:00
Handelt es sich dabei jetzt um Quellcode zur Standardlibrary, oder ist das für eine Lib, die du nur noch nicht hochgeladen hast?

Hallo,

sorry, war ein paar Tage verreist.



ich habe es eine Lib gemacht.


Der Satz ist leider völliger Unsinn und sollte wie folgt lauten:

ich habe es ohne eine Lib gemacht.

Ich hoffe ich habe Dich nicht zuviel verwirrt!

Gruß Dnerb

E. Hakennase
25.08.2008, 01:38
Nein, ich habs ja auch ohne probiert. Problem oben geschrieben ;)

linux_80
25.08.2008, 16:17
Hi,
Du hast ja einen Mega32, wenn da PortC.2 nicht geht, sieht das sehr nach aktiviertem JTAG aus (was bei einem neuen M32 immer so ist). Deshalb mal die Fusebits kontrollieren.

E. Hakennase
26.08.2008, 15:16
hmm. JTAG war aktiv, ich habe es deaktiviert. Aber irgendwas muss es geben, dass da noch mit reinspielt :(

Rein technisch gesehen kann ich keinen Fehler erkennen (Lötstellen,...)

Irgendwann wirds aber nochwas!

pyr0skull
26.08.2008, 15:43
Dieses Wintek LCD funktioniert bei mir mit diesem Code:


$regfile = "m168def.dat"
$crystal = 16000000
$baud = 9600


Dim ___lcdno As Byte


Config Lcd = 40 * 4
Config Lcdpin = Pin , Db4 = Portb.5 , Db5 = Portb.0 , Db6 = Portd.7 , Db7 = Portd.6 , E = Portb.3 , E2 = Portc.3 , Rs = Portc.2

___lcdno = 0
Initlcd
Cls
Cursor Off
___lcdno = 1
Initlcd
Cls
Cursor Off

Do

___lcdno = 0
Locate 1 , 1
Lcd "Zeile 1"
Locate 2 , 1
Lcd "Zeile 2"

___lcdno = 1
Locate 1 , 1
Lcd "Zeile 3"
Locate 2 , 1
Lcd "Zeile 4"

Loop


End


RW und die 4 anderen Datenports liegen auf GND. Achte aber drauf, dass die Ports nicht für was anderes benutzt werden. Hab mal versucht das Display an ein RN-Minicontrol anzuschließen und bin fast daran verzweifelt, dass der ISP dieselben Ports benutzt hat. Hab 2 Stunden gebraucht um das rauszufinden.

E. Hakennase
26.08.2008, 16:38
Klasse, es funktioniert \:D/
Genial, einen Schritt weiter, juhuu :D :D

Ich kann jetzt beide Displays korrekt ansteuern, derzeit wandert ein "Hallo Welt" über die ersten beiden Zeilen :)

Was war?
Zusammengefasst:
1. JTAG war aktiv, daher konnte ich den PortC nicht korrekt benutzen.
2. Mein Testprogramm versuchte testhalber nur die ersten beiden Zeilen anzusteuern (frei nach "nicht zu viel auf einmal"). War also auf E1 angewiesen
3. Das untere Display hatte schon die ganze Zeit funktioniert, hatte ich aber nie getestet. Durch das letzte hier gepostete (und leicht angepasste) Programm wurde auch das untere Display angesteuert. Ergebnis war zunächst:
Die obere Hälfte zeigt sich uninitialisiert (1 Balken, 1 leer), die untere Hälfte zweig "Zeile 3" und "Zeile 4" an.
4. Nach weiteren Tests (E1 und E2 im Programm vertauschen), musste wohl doch etwas an der E1 Leitung nicht stimmen. Kurz nachgelötet und dann ging auch die obere Hälfte. Jetzt noch schnell das Programm dazu geschrieben und es tut

Einfach GENIAL, Leute!
Das sind jetzt 3 Monate Einstiegsarbeit nebenher (Schaltplan, Layout, Platine ätzen, Steckbrett, bestücken,...) und ich komm langsam auf den Trichter. Ich hab zwar noch nicht alles fertig, was fertig werden soll, aber eine Hürde ist genommen :D

Vielen Dank dafür!

Gruß
E.Hakennase