Moin moin alle mit einander ! Ich habe momentan ein recht komplexes Projekt am laufen und versuche dabei ein 16 x 4 Display der Firma Electronic Assembly. Um genau zu sein, handelt es ich um das EA W164B-NLW DotMatrix Display. https://cdn-reichelt.de/documents/datenblatt/A500/LCD164ABL%23EAS.pdf Ich benutze momentan noch Bascom, werde jedoch später aus C umsteigen. Bascom ist nur zum Probieren, ob alles so läuft wie es soll ;) Ich habe nun versucht das Display wie folgt an zu steuern: ------------------------------------------------------------------------ ----- Ddrc = &B11111111 Ddrd = &B11111111 Config Lcd = 16 * 4 Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.3 , Db6 = Portc.2 , Db7 = Portc.1 , E = Portc.5 , Rs = Portc.6 Portd.7 = 1 Waitms 20 Locate 2 , 4 Lcd "Hallo" End ------------------------------------------------------------------------ ----- Jedoch musste ich unglücklicher weise feststellen, dass dies so nicht ganz geht. Momentaner Standpunkt ist der, dass Ich das Display am leuchten habe und auch den Kontrast zum Einstellen, kann ich benutzen. Jedoch ist da schon das erste Problem. Ich habe nur in der ersten und in der dritten Zeile die Möglichkeit, den Kontrast ein zu stellen. 2. und 4. Zeile lassen sich nicht regeln, bzw. zeigen kein Kontrast an. Außerdem habe ich keinerlei Möglichkeit etwas auf dem Display etwas aus zu geben. Nun ist meine frage, wie ich dem ganzen am besten auf die Schliche komme. Mit einem anderen Display was ich mal hatte, geht das so ohne Probleme oder ähnliches. Ich wäre euch wirklich sehr sehr dankbar, wenn mir jemand Hilft ! Vielen vielen dank schon einmal im voraus ! Mfg JuBa3006
:
Verschoben durch User
Wenn nur die erste und die dritte Zeile beim Kontrast-Einstellen sichtbar sind, ist das LCD nicht initialisiert. Prüfe bitte nochmal deine Verkabelung! Bzw. setzte mal ein "INITLCD" oder "CLS" nach dem Wait
Gugst du hier: http://halvar.at/elektronik/kleiner_bascom_avr_kurs/lcd_textanzeige/?PageSpeed=noscript
Moin .... Ihr seit echt cool. Jetzt schon eine Antwort. Ein Traum ! :D Sooo ... habe nun das initlcd mal eingefügt ... unmittelbar nach dem waitms 50 befehl. Jedoch ohne Erfolg. Es hat sich nichts geändert. Verkabelung ist überprüft. Habe die Pins alle bis an den Mikrocontroller durchgemessen und die Belegung stimmt auf jeden Fall. Ja Fusebits sind auch aus ... auf JTAG auf 1 gesetzt und in die Fuse geschrieben ;) //EDIT: Ich habe die Datenpins 0-3 nicht auf Gnd gelegt, aber das sollte doch trotzdem Funktionieren oder ?
:
Bearbeitet durch User
Schon mal nach dem Beispiel im Datenblatt initialisiert ?
...ja da bin ich gerade dabei. Jedoch habe ich keine Ahnung, wie ich die Tabelle aus zu werten habe. Es ist dazu ja leider auch nichts beschrieben. //Die hier oben verlinkte Tutorial Seite kannte ich schon. Die Seite konnte mir leider auch nicht weiter helfen. :(
Julian B. schrieb: > Die hier oben verlinkte Tutorial Seite kannte ich schon. Die Seite > konnte mir leider auch nicht weiter helfen. Dann kann dir hier auch keiner helfen!
Moin @Teo Derix schönen Dank. Ich habe doch schon geschrieben, was ich in Bascom geschrieben habe und das ich dann Inilcd hinzugefügt habe. So ... und nichts anderes wird auf der Seite beschrieben. es wird von einem 2 Zeiler ausgegangen und es werden nur die grundlegendsten Sachen erläutert. Also müsste es nach der Seite, laut dessen Autor jetzt funktionieren. Tut es ja aber nicht. Daher habe ich mich ja an euch gewandt Ich habe auch schon alle Ports auf High und Low nachgemessen. Es schalten alle Ports ohne Probleme. // Wie kann ich das Initialisierungsbeispiel aus der .pdf in Bascom einbinden ? :) mfg JuBa3006
Hallo, zeige doch mal den ganzen Code den Du da zusammen kopiert hast. Da der Code Schnipsel erleine so nicht funktionieren kann. lg
Moin Hier ist einmal der Code, der einfach nur etwas schreiben soll ######################################################################## $regfile = "m16adef.dat" Ddrc = &B11111111 Ddrd = &B11111111 Config Portc = Output Config Portd = Output '----------------------------------------------------------------------- Config Lcd = 16 * 4 Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.3 , Db6 = Portc.2 , Db7 = Portc.1 , E = Portc.5 , Rs = Portc.6 Portd.7 = 1 '----------------------------------------------------------------------- Waitms 50 Initlcd Cls Cursor On Blink Locate 1 , 1 Lcd "Hallo" Do Waitms 100 Loop End ######################################################################## Wenn ich zumindest schon einmal wenigstens in einer Zeile ein Wort hinbekommen würde, wäre ich froh ;) Hatte eben noch einmal alles auf den Port A gesteckt, jedoch das gleiche Ergebnis. Hoffe ihr könnt mir da weiter helfen :) :// mfg JuBa3006 //EDIT: PortD.7 ist die Hintergrundbeleuchtung
:
Bearbeitet durch User
$regfile = "m16adef.dat" $crystal = 8000000 $hwstack = 100 $swstack = 100 $framesize = 100 Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , _ Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2 Config Lcd = 16 * 4 Cursor Off Dim Initcounter As Byte Dim Bt As Byte Dim S As String * 2 Do For Initcounter = 1 To 36 'LCD löschen Cls 'Haupttext der ersten Zeile anzeigen Locate 1 , 1 Lcd "Hallo Welt...." 'Haupttext der zweiten Zeile anzeigen Locate 2 , 1 Lcd "Servus LCD...." 'Jede Sekunde um 1 hochzählen und neuen Wert anzeigen For Bt = 1 To 99 'Neuen Wert in einen Text umwandeln S = Str(bt) S = Format(s , "00") 'Neuen Wert in der ersten Zeile ab Spalte 15 anzeigen Locate 1 , 15 Lcd S 'Neuen Wert in der zweiten Zeile ab Spalte 15 anzeigen Locate 2 , 15 Lcd S 'Eine Sekunde warten Wait 1 Next Bt 'Das LCD nach ca. einer Stunden neu initialisieren If Initcounter = 36 Then Initlcd End If Next Initcounter Loop End
:
Bearbeitet durch User
Moin Ich habe den Code übernommen und musste mal wieder feststellen, das es nicht geht. Die datenpins habe ich übernommen und alles so eingetragen .... Das einzige was jetzt ist ist, dass das Display von der Hintergrund Helligkeit dunkler ist. mfg JuBa3006
Hallo, mal am Kontrastregler gestellt. Zeige mal deinen Aufbau Schaltplan und oder Bild. lg
Hier einmal die Pläne Wenn Bilder erwünscht sein sollte auch gerne ;) // Ja ... am Poti habe ich mal gedreht .... Kompletten bereich zwischen kaum Kontrast und voll //EDIT: Bei dem 2. Anhang wird der Eingang bzw Ausgang oben ganz rechts genutzt ;)
:
Bearbeitet durch User
Julian B. schrieb: > Hier einmal die Pläne Das sind keine Schaltpläne! Was aber trotzdem sofort auffällt, bitte hier nachlesen: http://www.mikrocontroller.net/articles/Kondensator#Entkoppelkondensator
J. H. schrieb: > R/W an Minus angeschlossen? Moin Ja R/W liegt auf Gnd ... so wie es eigentlich auch soll. // mir war es bewusst, das es nicht die Schaltpläne sind (Entschuldigung für den unpräzise gewählten ausdruck :p ;) ), aber ich habe bewusst die Layouts genommen. So kann ich davon ausgehen, das ihr von dem selben Standpunkt mein Problem betrachtet ;) # Entkoppelkondensatoren ... die einen sagen, das muss unbedingt beachtet werden und andere sagen, das ist hierbei schnurz pups egal. Müssen da welche für die Funktionstüchtigkeit hin ? :o
:
Bearbeitet durch User
Julian B. schrieb: > // mir war es bewusst, das es nicht die Schaltpläne sind (Entschuldigung > für den unpräzise gewählten ausdruck :p ;) ), aber ich habe bewusst die > Layouts genommen. So kann ich davon ausgehen, das ihr von dem selben > Standpunkt mein Problem betrachtet ;) > > # Entkoppelkondensatoren ... die einen sagen, das muss unbedingt > beachtet werden und andere sagen, das ist hierbei schnurz pups egal. > Müssen da welche für die Funktionstüchtigkeit hin ? :o Damit bin ich hier raus! Viel Glück noch.
Julian B. schrieb: > Ich habe die Datenpins 0-3 nicht auf Gnd gelegt, aber das sollte > doch trotzdem Funktionieren oder ? Auf GND ist die blödeste Idee. Auch wenn man das überall wiederfindet. Im Datenblatt steht etwas dazu. Julian B. schrieb: > # Entkoppelkondensatoren ... die einen sagen, das muss unbedingt > beachtet werden und andere sagen, das ist hierbei schnurz pups egal. > Müssen da welche für die Funktionstüchtigkeit hin ? :o Von den Dingern kann man eigentlich nie genug haben, auch wenn es tatsächlich hier und da mal ohne funktioniert. Deshalb kann man sie auch mal ganz naiv weg lassen und die dabei entstehenden Fehler in der Software suchen. Das macht nämlich mehr Spaß, an einer Stelle einen Fehler zu suchen, an der er gar nicht ist. Julian B. schrieb: > mir war es bewusst, das es nicht die Schaltpläne sind Und? Kommen die noch? Teo Derix schrieb: > Damit bin ich hier raus! Verständlich ... Gruß Jobst
Moin Ja klar kommen die noch, aber ich hatte es gestern Abend keine Zeit mehr die Display Platine noch einmal mit dem Schaltplan zu vergleichen. Jetzt habe ich es geschafft und will euch auch diese Pläne noch zukommen lassen ;) mfg JuBa3006
Moin moin Im Eifer des Gefechts, habe ich doch glatt den Fehler gefunden ! :D Ich hatte eine Verbindung zwischen Pin 5 & & und da 6 Enable ist, kann es Garnichts Funktionieren, wenn dort Gnd anliegt. Die Verbindung zwischen den Kontakten habe ich nur durch Zufall gefunden. Beim durchpiepen kam zwischendurch immer mal was und mal nicht. Also Lupe genommen und siehe da, da ist eine Haarkleine Verbindung. Solch eine kleine und haarfeine Verbindung hatte ich noch nie zu vor gesehen :x Vor allem war noch Flussmittel drüber und man konnte nichts erkennen. Aber vielen vielen Dank an euch, das ihr mir so tatkräftig unter die Arme gegriffen habt ! // Andere sache ... ist das mit dem TXD und RXD so richtig ?
Übrigens: Was bedeuted LCD? Und was bedeuted LCD Display?
Moin Ja ... ich weiß das Display ist ein wenig überflüssig :D LCD = liqued crystal Dispaly // Edit: LCD steht im übrigen auch für den Labrador Club Deutschland :D
:
Bearbeitet durch User
Hi >Jetzt habe ich es geschafft und will euch auch diese Pläne noch zukommen >lassen ;) Bist du immer so sparsam im Umgang mit Abblockkondensatoren? MfG Spess
spess53 schrieb: > Bist du immer so sparsam im Umgang mit Abblockkondensatoren? Psssssst .......... nix veraten ! Sonst wird das wird später nicht so unterhaltsam .....
@ Julian B. (juba3006) > Schaltplan.JPG > 160 KB, 3 Downloads Mehrere Fehler. 1. Bildformate, PNG ist besser. Ist aber nebensächlich. 2. Die Kontrasteinstellung ist falsch. Es reicht, einen Poti von VEE nach GND zu schalten, ohne VCC Schluss. So wie es jetzt ist, geht es NIE! Denn die Kontrastspannung liegt zwisch 0-1,5V gegen GND! Du erzeugst aber ein Spannung nahe VCC! http://elm-chan.org/docs/lcd/lcd3v.html Figure 1. https://www.mikrocontroller.net/articles/Kondensator#Entkoppelkondensator Das ist die heilige Kuh der Digitaltechnik und nicht verhandelbar!
spess53 schrieb: > Bist du immer so sparsam im Umgang mit Abblockkondensatoren? Bei seinem LCD Problem hilft es auch nicht..
Moin So Jungs ... langsam wird es echt sehr witzig. Kondensatoren, habe ich nicht viele in der Zeichnung drin, jedoch sind auf den Platinen nachträglich welche vorgesehen worden. Nein ich bin nicht sparsam mit Kondensatoren. Die hätte ich im Überfluss da. @ Falk Brunner Meine Verschaltung ist nichts anderes als ein Spannungsteiler. Und das ist schon richtig. Ich kann die Kontaktspannung ohne Probleme einstellen, und die soll auch so bei 0,5V liegen. Der Kontrast passt alles perfekt. (einige Hersteller habe diese Verschaltung sogar in Ihren Datenblättern mit drin ! ) ;) Wenn Ihr mal weiter gelesen hättet und auf den post von heute morgen um 11 Uhr noch was eingegangen wärt, wüsstet ihr wo ich den Fehler gefunden habe. // und das mit den Kondensatoren werde ich mir zu herzen nehmen. Das ist nicht verkehrt. Stimmt wohl. Deshalb hatte ich ja schon einige nachträglich auf die Platine hinzugefügt. ;)
@ Julian B. (juba3006) >Kondensatoren, habe ich nicht viele in der Zeichnung drin, jedoch sind >auf den Platinen nachträglich welche vorgesehen worden. Das erscheint äußerst sinnvoll . . . >Meine Verschaltung ist nichts anderes als ein Spannungsteiler. Das ist unbestritten.- > Und das >ist schon richtig. Das ist eher strittig ;-) >Ich kann die Kontaktspannung ohne Probleme einstellen, und die soll auch >so bei 0,5V liegen. Gemessen? Wollen wir wetten, dass dein SCHALTPLAN falsch ist? Pin 1 ist 0V(GND), Pin 2 +5V(VCC) Der 10k Poti hängt an Pin2 / 5V, in Reihe mit 27k. Damit kann man maximal auf 27/(27+10)*5V=3,64V runterdrehen. Damit ist dein Kontrast weg! Man sieht rein gar nichts! >Der Kontrast passt alles perfekt. >(einige Hersteller habe diese Verschaltung sogar in Ihren Datenblättern >mit drin ! ) ;) Dumm nur, dass dort der Spannungsteiler anders herum ist. Nämlich mit dem Poti an Masse anstatt an +5V. >Wenn Ihr mal weiter gelesen hättet und auf den post von heute morgen um >11 Uhr noch was eingegangen wärt, wüsstet ihr wo ich den Fehler gefunden >habe. Beitrag "Re: Display Ansteuerung - 16 x 4 DotMatrix LCD" Schön. Das ändert trotzdem nichts an der Tatsache, dass dein Schaltplan fehlerhaft ist. Jeder Anfänger, der das nachbaut, wird wahnsinnig!
Moin Der maximale Regelbereich beträgt 0,1 - 2,2 V Jetzt weiß ich was du meinst, aber verbessere mich wenn ich falsch liege. Ich habe das so herum gemacht, damit ich immer den Widerstand von 27k Ohm davor habe, damit ich niemals die blanken 5v da liegen habe. Den besten Kontrastwert habe ich bei 0,2V und da ich die 10k Ohm Potis im Überfluss habe, dachte ich dass das kein Problem wäre. Den Vorwiderstand könnte ich noch einmal anders wählen, sodass ich nicht in den Bereich von 1V komme. Dann schalten ich um die Potiwirkung zu minimieren einfach einen Widerstand parallel an das Poti und somit müsste ich meinen gewünschten Regelbereich erreicht haben. Wenn ich das doch andersherum schalten würde, würde ich irgendwann auf pin 3 die blanken 5V liegen habe, wenn ich das Poti ganz auf Anschlag drehen solle ... :o Oder habe ich dich falsch verstanden ?
Gut du hast einen Fehler gefunden, aber geht das Display jetzt ?
Jip mit beheben der ungewollten Verbindung, Funktioniert alles perfekt so wie es soll. ;) Ist das mit den TXD und RXD eigentlich jetzt so richtig, wie ich das in den Plänen gemacht habe ??
:
Bearbeitet durch User
@Julian B. (juba3006) >Der maximale Regelbereich beträgt 0,1 - 2,2 V Weil du deinen Poti NICHT wie im Schaltplan angeschlossen hast, sondern anders herum. >Ich habe das so herum gemacht, damit ich immer den Widerstand von 27k >Ohm davor habe, damit ich niemals die blanken 5v da liegen habe. Verstehe, ist aber hier unkritisch, da geht nichts kaputt. >Den besten Kontrastwert habe ich bei 0,2V und da ich die 10k Ohm Potis >im Überfluss habe, dachte ich dass das kein Problem wäre. Ist es auch nicht. >Den >Vorwiderstand könnte ich noch einmal anders wählen, sodass ich nicht in >den Bereich von 1V komme. Du kannst ihn weglassen. Man braucht auch nur einen Endanschlus und den Mittelabgriff, der 2. Endanschluss kann offen bleiben. Denn IM LCD ist schon ein Spannungsteiler drin. > Dann schalten ich um die Potiwirkung zu >minimieren einfach einen Widerstand parallel an das Poti und somit >müsste ich meinen gewünschten Regelbereich erreicht haben. Vergiss den Murks. >Wenn ich das doch andersherum schalten würde, würde ich irgendwann auf >pin 3 die blanken 5V liegen habe, wenn ich das Poti ganz auf Anschlag >drehen solle ... :o Oder habe ich dich falsch verstanden ? Siehe oben!
Julian B. schrieb: > Wenn ich das doch andersherum schalten würde, würde ich irgendwann auf > pin 3 die blanken 5V liegen habe, wenn ich das Poti ganz auf Anschlag > drehen solle ... :o Oder habe ich dich falsch verstanden ? Nö. Aber so falsch ist es in Deinem Plan.
Moin Ich sehe es gerade .... der Plan hat wohl da tatsächlich eine anomalie :D Da hatte ich heute morgen wohl noch nicht alle Synapsen aktivieren können :D
@Julian B. (juba3006) >Ich sehe es gerade .... der Plan hat wohl da tatsächlich eine anomalie >:D Deswegen zeichnet man auch als Hobbybastler ZUERST einen Schaltplan und baut danach die Schaltung auf.
Falk Brunner schrieb: > @Julian B. (juba3006) > > Ich sehe es gerade .... der Plan hat wohl da tatsächlich eine anomalie >>:D > > Deswegen zeichnet man auch als Hobbybastler ZUERST einen Schaltplan und > baut danach die Schaltung auf. niemals. 99.9% direkt Layout, ätzen, bestücken.
@ Crazy H. (crazy_h) >> Deswegen zeichnet man auch als Hobbybastler ZUERST einen Schaltplan und >> baut danach die Schaltung auf. >niemals. 99.9% direkt Layout, ätzen, bestücken. Man muss es nicht sinnvoll und richtig machen. Man kann auch obercool tun und ignorant sein. Ist ein Menschenrecht.
Falk Brunner schrieb: > @ Crazy H. (crazy_h) > > Deswegen zeichnet man auch als Hobbybastler ZUERST einen Schaltplan und > baut danach die Schaltung auf. > > niemals. 99.9% direkt Layout, ätzen, bestücken. > > Man muss es nicht sinnvoll und richtig machen. Man kann auch obercool > tun und ignorant sein. Ist ein Menschenrecht. Bedeutet ? Einen Schaltplan zeichne ich nur, wenn ich das jemand zeigen muß. Nur für mich und damit es einen gibt ? Für was ?
@ Crazy H. (crazy_h) >> Man muss es nicht sinnvoll und richtig machen. Man kann auch obercool >> tun und ignorant sein. Ist ein Menschenrecht. >Bedeutet ? Deutsch? Geschlossener Satz? Möglich? > Einen Schaltplan zeichne ich nur, wenn ich das jemand zeigen > muß. Nur für mich und damit es einen gibt ? Für was ? Für DICH! Um deine Schaltung zu verstehen und ggf. zu korrigieren oder zu verbessern. Für alles was über einen NE555 Blinker hinausgeht, ist das nicht nur sinnvoll sondern nötig. Aber solche Geistesgrößen wie du die haben natürlich mehrseitige Schaltpläne detailiert im Kopf. Heute wie morgen wie in einem Jahr? Wozu die Leute nur Papier und Tinte erfunden haben?
Stimmt und wenn der TO hier gleich einen Schaltplan gezeigt hätte, hättest du auch gleich den Schluss zwischen Pin 5 & 6 gesehen wall <-- Insidergag
:
Bearbeitet durch User
Hallo, da ja Dein LCD geht wie Du sagst sei doch mal so nett und Zeige ein Bild vom LCD mit dem Code den ich Dir gepostet hatte. Lg
Moin Ich habe momentan noch einen anderen Code drauf ... aber ich kann heute Abend das ganze mal aufspielen und dann euch das Gesamtergebnis zeigen ;) // Falls Ihr mich falsch verstanden hattet, der Schaltplan exestierte schon vorher, jedoch muss ich die Steckerbelegung beim Layout ändern und somit musste ich das im Schaltplan auch ändern. Dies hatte ich jedoch bis zu dem Zeitpunkt noch nicht ;)
:
Bearbeitet durch User
Moin Hier wie versprochen die Bilder zu meinem Aktuellen Projekt, wo das Display auch zu gehört ;) // Der von dir verlinkte Quellcode läuft nicht .... ich habe alle Ports angepasst, aber es passiert nichts bis auf, dass das Display etwas dunkler wird ;)
Moin moin ... könntet ihr mir einmal helfen ? Brauche ich den R/W Pin am LCD für C ?! Ich habe diesen momentan nicht angesteuert. In Bascom ist das kein Problem, aber ist das in C auch so ? mfg JuBa3006
JuBa 3006 schrieb: > Ich habe diesen momentan nicht angesteuert. In Bascom ist das kein > Problem, aber ist das in C auch so ? Dem LCD ist die Programmiersprache völlig wurscht. Ob R/W angesteuert werden muss, hängt davon ab, ob du aus dem Display irgendetwas lesen möchtest. Wenn du nichts lesen möchtest, brauchst du die Richtung auch nicht umzuschalten.
Nabend Cool das jetzt schon eine Antwort kam. Okay ... das habe ich mir schon gedacht, jedoch weiß ich nicht wodran es liegt. Zumindest kann ich R/W schon einmal ausschließen. Hier einmal der bisherige Code: # --> Lcd_routines.h
1 | // Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
|
2 | // http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung
|
3 | //
|
4 | |
5 | #ifndef LCD_ROUTINES_H
|
6 | #define LCD_ROUTINES_H
|
7 | |
8 | #include <avr/pgmspace.h> |
9 | |
10 | ////////////////////////////////////////////////////////////////////////////////
|
11 | // Pinbelegung für das LCD, an verwendete Pins anpassen
|
12 | // alle Pins müssen in einem Port liegen
|
13 | // die 4 Bit für die Daten müssen zusammenliegen, können aber an einer
|
14 | // beliebigen Postion anfangen
|
15 | |
16 | #ifndef LCD_PORTS
|
17 | #define LCD_PORTS
|
18 | |
19 | #define LCD_PORT PORTC
|
20 | #define LCD_DDR DDRC
|
21 | |
22 | // 4 Bit LCD Datenbus DB4-DB7, das unterste Bit DB4 kann auf den Portbits 0..4 liegen
|
23 | |
24 | // LCD DB4-DB7 <--> PORTC Bit PC0-PC3
|
25 | #define LCD_DB PC1
|
26 | |
27 | // LCD Steuersignale RS und EN
|
28 | |
29 | // LCD RS <--> PORTC Bit PC4 (RS: 0=Data, 1=Command)
|
30 | #define LCD_RS PC6
|
31 | |
32 | // LCD EN <--> PORTC Bit PC5 (EN: 1-Impuls für Daten)
|
33 | #define LCD_EN PC5
|
34 | |
35 | #endif // LCD_PORTS
|
36 | |
37 | ////////////////////////////////////////////////////////////////////////////////
|
38 | // LCD Ausführungszeiten (MS=Millisekunden, US=Mikrosekunden)
|
39 | |
40 | #ifndef LCD_TIMINGS
|
41 | #define LCD_TIMINGS
|
42 | |
43 | #define LCD_BOOTUP_MS 15
|
44 | #define LCD_ENABLE_US 1
|
45 | #define LCD_WRITEDATA_US 46
|
46 | #define LCD_COMMAND_US 42
|
47 | |
48 | #define LCD_SOFT_RESET_MS1 5
|
49 | #define LCD_SOFT_RESET_MS2 1
|
50 | #define LCD_SOFT_RESET_MS3 1
|
51 | #define LCD_SET_4BITMODE_MS 5
|
52 | |
53 | #define LCD_CLEAR_DISPLAY_MS 2
|
54 | #define LCD_CURSOR_HOME_MS 2
|
55 | |
56 | #endif // LCD_TIMINGS
|
57 | |
58 | ////////////////////////////////////////////////////////////////////////////////
|
59 | // Zeilendefinitionen des verwendeten LCD
|
60 | // die Einträge hier sollten für ein LCD mit einer Zeilenlänge von 16 Zeichen passen
|
61 | // bei anderen Zeilenlängen müssen diese Einträge angepasst werden
|
62 | |
63 | #define LCD_DDADR_LINE1 0x00
|
64 | #define LCD_DDADR_LINE2 0x40
|
65 | #define LCD_DDADR_LINE3 0x10
|
66 | #define LCD_DDADR_LINE4 0x50
|
67 | |
68 | ////////////////////////////////////////////////////////////////////////////////
|
69 | // Initialisierung: muss ganz am Anfang des Programms aufgerufen werden.
|
70 | void lcd_init( void ); |
71 | |
72 | ////////////////////////////////////////////////////////////////////////////////
|
73 | // LCD löschen
|
74 | void lcd_clear( void ); |
75 | |
76 | ////////////////////////////////////////////////////////////////////////////////
|
77 | // Cursor in die erste Zeile, erste Spalte (Position 0,0)
|
78 | void lcd_home( void ); |
79 | |
80 | ////////////////////////////////////////////////////////////////////////////////
|
81 | // Cursor an eine beliebige Position
|
82 | void lcd_setcursor( uint8_t x, uint8_t y ); |
83 | |
84 | ////////////////////////////////////////////////////////////////////////////////
|
85 | // Ausgabe eines einzelnen Zeichens an der aktuellen Cursorposition
|
86 | void lcd_data( uint8_t data ); |
87 | |
88 | ////////////////////////////////////////////////////////////////////////////////
|
89 | // Ausgabe eines Strings an der aktuellen Cursorposition
|
90 | // String liegt im RAM
|
91 | void lcd_string( const char *data ); |
92 | |
93 | ////////////////////////////////////////////////////////////////////////////////
|
94 | // Ausgabe eines Strings an einer bestimmten Cursorposition
|
95 | // String liegt im RAM
|
96 | void lcd_string_xy( uint8_t x, uint8_t y, const char *data ); |
97 | |
98 | ////////////////////////////////////////////////////////////////////////////////
|
99 | // Ausgabe einer Zahl an der aktuellen Cursorposition
|
100 | // Zahl liegt im RAM
|
101 | void lcd_number( uint8_t number, uint8_t len, uint8_t fill ); |
102 | |
103 | ////////////////////////////////////////////////////////////////////////////////
|
104 | // Ausgabe einer Zahl an einer bestimmten Cursorposition
|
105 | // Zahl liegt im RAM
|
106 | void lcd_number_xy( uint8_t x, uint8_t y, uint8_t number, uint8_t len, uint8_t fill ); |
107 | |
108 | ////////////////////////////////////////////////////////////////////////////////
|
109 | // Ausgabe eines Strings an der aktuellen Cursorposition
|
110 | // String liegt im Flash
|
111 | void lcd_string_P( PGM_P data ); |
112 | |
113 | ////////////////////////////////////////////////////////////////////////////////
|
114 | // Definition eines benutzerdefinierten Sonderzeichens.
|
115 | // data muss auf ein Array mit den Zeilencodes des zu definierenden Zeichens
|
116 | // zeigen, Daten liegen im RAM
|
117 | void lcd_generatechar( uint8_t code, const uint8_t *data, uint8_t lines ); |
118 | |
119 | ////////////////////////////////////////////////////////////////////////////////
|
120 | // Definition eines benutzerdefinierten Sonderzeichens.
|
121 | // data muss auf ein Array mit den Zeilencodes des zu definierenden Zeichens
|
122 | // zeigen, Daten liegen im FLASH
|
123 | void lcd_generatechar_P( uint8_t code, PGM_P data, uint8_t lines ); |
124 | |
125 | ////////////////////////////////////////////////////////////////////////////////
|
126 | // Ausgabe eines Kommandos an das LCD.
|
127 | void lcd_command( uint8_t data ); |
128 | |
129 | ////////////////////////////////////////////////////////////////////////////////
|
130 | // LCD Befehle und Argumente.
|
131 | // zur Verwendung in lcd_command
|
132 | |
133 | // Clear Display -------------- 0b00000001
|
134 | #define LCD_CLEAR_DISPLAY 0x01
|
135 | |
136 | // Cursor Home ---------------- 0b0000001x
|
137 | #define LCD_CURSOR_HOME 0x02
|
138 | |
139 | // Set Entry Mode ------------- 0b000001xx
|
140 | #define LCD_SET_ENTRY 0x04
|
141 | |
142 | #define LCD_ENTRY_DECREASE 0x00
|
143 | #define LCD_ENTRY_INCREASE 0x02
|
144 | #define LCD_ENTRY_NOSHIFT 0x00
|
145 | #define LCD_ENTRY_SHIFT 0x01
|
146 | |
147 | // Set Display ---------------- 0b00001xxx
|
148 | #define LCD_SET_DISPLAY 0x08
|
149 | |
150 | #define LCD_DISPLAY_OFF 0x00
|
151 | #define LCD_DISPLAY_ON 0x04
|
152 | #define LCD_CURSOR_OFF 0x00
|
153 | #define LCD_CURSOR_ON 0x02
|
154 | #define LCD_BLINKING_OFF 0x00
|
155 | #define LCD_BLINKING_ON 0x01
|
156 | |
157 | // Set Shift ------------------ 0b0001xxxx
|
158 | #define LCD_SET_SHIFT 0x10
|
159 | |
160 | #define LCD_CURSOR_MOVE 0x00
|
161 | #define LCD_DISPLAY_SHIFT 0x08
|
162 | #define LCD_SHIFT_LEFT 0x00
|
163 | #define LCD_SHIFT_RIGHT 0x01
|
164 | |
165 | // Set Function --------------- 0b001xxxxx
|
166 | #define LCD_SET_FUNCTION 0x20
|
167 | |
168 | #define LCD_FUNCTION_4BIT 0x00
|
169 | #define LCD_FUNCTION_8BIT 0x10
|
170 | #define LCD_FUNCTION_1LINE 0x00
|
171 | #define LCD_FUNCTION_2LINE 0x08
|
172 | #define LCD_FUNCTION_5X7 0x00
|
173 | #define LCD_FUNCTION_5X10 0x04
|
174 | |
175 | #define LCD_SOFT_RESET 0x30
|
176 | |
177 | // Set CG RAM Address --------- 0b01xxxxxx (Character Generator RAM)
|
178 | #define LCD_SET_CGADR 0x40
|
179 | |
180 | #define LCD_GC_CHAR0 0
|
181 | #define LCD_GC_CHAR1 1
|
182 | #define LCD_GC_CHAR2 2
|
183 | #define LCD_GC_CHAR3 3
|
184 | #define LCD_GC_CHAR4 4
|
185 | #define LCD_GC_CHAR5 5
|
186 | #define LCD_GC_CHAR6 6
|
187 | #define LCD_GC_CHAR7 7
|
188 | |
189 | // Set DD RAM Address --------- 0b1xxxxxxx (Display Data RAM)
|
190 | #define LCD_SET_DDADR 0x80
|
191 | |
192 | |
193 | #endif // LCD_ROUTINES_H
|
# --> lcd_rountines.c
1 | // Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
|
2 | // http://www.mikrocontroller.net/articles/HD44780
|
3 | // http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung
|
4 | //
|
5 | // Die Pinbelegung ist über defines in lcd.h einstellbar
|
6 | |
7 | #include <avr/io.h> |
8 | #include "lcd-routines.h" |
9 | #include <util/delay.h> |
10 | |
11 | /////////////////////////////////////////////////////////////////////////////////
|
12 | // Erzeugt einen Enable-Puls
|
13 | |
14 | static void lcd_enable( void ) { |
15 | LCD_PORT |= (1<<LCD_EN); // Enable auf 1 setzen |
16 | _delay_us( LCD_ENABLE_US ); // kurze Pause |
17 | LCD_PORT &= ~(1<<LCD_EN); // Enable auf 0 setzen |
18 | }
|
19 | |
20 | ////////////////////////////////////////////////////////////////////////////////
|
21 | // Sendet eine 4-bit Ausgabeoperation an das LCD
|
22 | static void lcd_out( uint8_t data ) { |
23 | data &= 0xF0; // obere 4 Bit maskieren |
24 | LCD_PORT &= ~(0xF0>>(4-LCD_DB)); // Maske löschen |
25 | LCD_PORT |= (data>>(4-LCD_DB)); // Bits setzen |
26 | lcd_enable(); |
27 | }
|
28 | |
29 | ////////////////////////////////////////////////////////////////////////////////
|
30 | // Initialisierung: muss ganz am Anfang des Programms aufgerufen werden.
|
31 | void lcd_init( void ) { |
32 | // verwendete Pins auf Ausgang schalten
|
33 | uint8_t pins = (0x0F << LCD_DB) | // 4 Datenleitungen |
34 | (1<<LCD_RS) | // R/S Leitung |
35 | (1<<LCD_EN); // Enable Leitung |
36 | LCD_DDR |= pins; |
37 | |
38 | // initial alle Ausgänge auf Null
|
39 | LCD_PORT &= ~pins; |
40 | |
41 | // warten auf die Bereitschaft des LCD
|
42 | _delay_ms( LCD_BOOTUP_MS ); |
43 | |
44 | // Soft-Reset muss 3mal hintereinander gesendet werden zur Initialisierung
|
45 | lcd_out( LCD_SOFT_RESET ); |
46 | _delay_ms( LCD_SOFT_RESET_MS1 ); |
47 | |
48 | lcd_enable(); |
49 | _delay_ms( LCD_SOFT_RESET_MS2 ); |
50 | |
51 | lcd_enable(); |
52 | _delay_ms( LCD_SOFT_RESET_MS3 ); |
53 | |
54 | // 4-bit Modus aktivieren
|
55 | lcd_out( LCD_SET_FUNCTION | |
56 | LCD_FUNCTION_4BIT ); |
57 | _delay_ms( LCD_SET_4BITMODE_MS ); |
58 | |
59 | // 4-bit Modus / 2 Zeilen / 5x7
|
60 | lcd_command( LCD_SET_FUNCTION | |
61 | LCD_FUNCTION_4BIT | |
62 | LCD_FUNCTION_2LINE | |
63 | LCD_FUNCTION_5X7 ); |
64 | |
65 | // Display ein / Cursor aus / Blinken aus
|
66 | lcd_command(LCD_SET_DISPLAY | |
67 | LCD_DISPLAY_ON | |
68 | LCD_CURSOR_OFF | |
69 | LCD_BLINKING_OFF); |
70 | |
71 | // Cursor inkrement / kein Scrollen
|
72 | lcd_command( LCD_SET_ENTRY | |
73 | LCD_ENTRY_INCREASE | |
74 | LCD_ENTRY_NOSHIFT ); |
75 | |
76 | lcd_clear(); |
77 | }
|
78 | |
79 | ////////////////////////////////////////////////////////////////////////////////
|
80 | // Sendet ein Datenbyte an das LCD
|
81 | void lcd_data( uint8_t data ) { |
82 | LCD_PORT |= (1<<LCD_RS); // RS auf 1 setzen |
83 | |
84 | lcd_out( data ); // zuerst die oberen, |
85 | lcd_out( data<<4 ); // dann die unteren 4 Bit senden |
86 | |
87 | _delay_us( LCD_WRITEDATA_US ); |
88 | }
|
89 | |
90 | ////////////////////////////////////////////////////////////////////////////////
|
91 | // Sendet einen Befehl an das LCD
|
92 | void lcd_command( uint8_t data ) { |
93 | LCD_PORT &= ~(1<<LCD_RS); // RS auf 0 setzen |
94 | |
95 | lcd_out( data ); // zuerst die oberen, |
96 | lcd_out( data<<4); // dann die unteren 4 Bit senden |
97 | |
98 | _delay_us(LCD_COMMAND_US ); |
99 | }
|
100 | |
101 | ////////////////////////////////////////////////////////////////////////////////
|
102 | // Sendet den Befehl zur Löschung des Displays
|
103 | void lcd_clear( void ) { |
104 | lcd_command( LCD_CLEAR_DISPLAY ); |
105 | _delay_ms( LCD_CLEAR_DISPLAY_MS ); |
106 | }
|
107 | |
108 | ////////////////////////////////////////////////////////////////////////////////
|
109 | // Sendet den Befehl: Cursor Home
|
110 | void lcd_home( void ) { |
111 | lcd_command( LCD_CURSOR_HOME ); |
112 | _delay_ms( LCD_CURSOR_HOME_MS ); |
113 | }
|
114 | |
115 | ////////////////////////////////////////////////////////////////////////////////
|
116 | // Setzt den Cursor in Zeile y (0..3) Spalte x (0..15)
|
117 | |
118 | void lcd_setcursor( uint8_t x, uint8_t y ) { |
119 | uint8_t data; |
120 | |
121 | switch (y) { |
122 | case 0: // 1. Zeile |
123 | data = LCD_SET_DDADR + LCD_DDADR_LINE1 + x; |
124 | break; |
125 | case 1: // 2. Zeile |
126 | data = LCD_SET_DDADR + LCD_DDADR_LINE2 + x; |
127 | break; |
128 | case 2: // 3. Zeile |
129 | data = LCD_SET_DDADR + LCD_DDADR_LINE3 + x; |
130 | break; |
131 | case 3: // 4. Zeile |
132 | data = LCD_SET_DDADR + LCD_DDADR_LINE4 + x; |
133 | break; |
134 | default:
|
135 | return; // für den Fall einer falschen Zeile |
136 | }
|
137 | |
138 | lcd_command( data ); |
139 | }
|
140 | |
141 | ////////////////////////////////////////////////////////////////////////////////
|
142 | // Schreibt einen String auf das LCD
|
143 | |
144 | void lcd_string( const char *data ) { |
145 | while( *data != '\0' ) |
146 | lcd_data( *data++ ); |
147 | }
|
148 | |
149 | void lcd_string_xy( uint8_t x, uint8_t y, const char *data ) { |
150 | lcd_setcursor( x, y ); |
151 | lcd_string( data ); |
152 | }
|
153 | |
154 | ////////////////////////////////////////////////////////////////////////////////
|
155 | // Schreibt eine Zahl auf das LCD
|
156 | |
157 | void lcd_number( uint8_t number, uint8_t len, uint8_t fill ) { |
158 | uint8_t digit1 = 0; |
159 | uint8_t digit2 = 0; |
160 | while (number >= 100) { |
161 | digit1++; |
162 | number -= 100; |
163 | }
|
164 | while (number >= 10) { |
165 | digit2++; |
166 | number -= 10; |
167 | }
|
168 | if (len > 2) lcd_data( (digit1 != 0) ? digit1+'0' : fill ); |
169 | if (len > 1) lcd_data( ((digit1 != 0) || (digit2 != 0)) ? digit2+'0' : fill ); |
170 | lcd_data( number+'0' ); |
171 | }
|
172 | |
173 | void lcd_number_xy( uint8_t x, uint8_t y, uint8_t number, uint8_t len, uint8_t fill ) { |
174 | lcd_setcursor( x, y ); |
175 | lcd_number( number, len, fill ); |
176 | }
|
177 | |
178 | ////////////////////////////////////////////////////////////////////////////////
|
179 | // Schreibt einen String auf das LCD
|
180 | // String liegt direkt im Flash Speicher
|
181 | |
182 | void lcd_string_P( PGM_P data ) { |
183 | uint8_t tmp; |
184 | |
185 | tmp = pgm_read_byte( data ); |
186 | while( tmp != '\0' ) { |
187 | lcd_data( tmp ); |
188 | data++; |
189 | tmp = pgm_read_byte( data ); |
190 | }
|
191 | }
|
192 | |
193 | ////////////////////////////////////////////////////////////////////////////////
|
194 | // Schreibt ein Zeichen in den Character Generator RAM
|
195 | // Daten liegen direkt im RAM
|
196 | |
197 | void lcd_generatechar( uint8_t code, const uint8_t *data, uint8_t lines ) { |
198 | uint8_t i; |
199 | |
200 | // Startposition des Zeichens einstellen
|
201 | lcd_command( LCD_SET_CGADR | (code<<3) ); |
202 | // Bitmuster übertragen
|
203 | for ( i=0; i<lines; i++ ) { |
204 | lcd_data( *data++ ); |
205 | }
|
206 | }
|
207 | |
208 | ////////////////////////////////////////////////////////////////////////////////
|
209 | // Schreibt ein Zeichen in den Character Generator RAM
|
210 | // Daten liegen direkt im Flash-Speicher
|
211 | |
212 | void lcd_generatechar_P( uint8_t code, PGM_P data, uint8_t lines ) { |
213 | uint8_t i; |
214 | |
215 | // Startposition des Zeichens einstellen
|
216 | lcd_command( LCD_SET_CGADR | (code<<3) ); |
217 | // Bitmuster übertragen
|
218 | for ( i=0; i<lines; i++ ) { |
219 | lcd_data( pgm_read_byte(data) ); |
220 | data++; |
221 | }
|
222 | }
|
# --> GCC_Application_1
1 | /*
|
2 | * GccApplication1.c
|
3 | *
|
4 | * Created: 07.03.2015 22:47:45
|
5 | * Author: Asus
|
6 | */
|
7 | |
8 | #define F_CPU 10000000UL
|
9 | |
10 | #include <avr/io.h> |
11 | #include "lcd-routines.h" |
12 | |
13 | int main(void) |
14 | {
|
15 | DDRD |= (1 << PD7); |
16 | PORTD |= (1 << PD7); |
17 | |
18 | lcd_init(); |
19 | lcd_clear(); |
20 | lcd_setcursor(0, 0); |
21 | lcd_string("Hello World"); |
22 | |
23 | while(1) |
24 | {
|
25 | //TODO:: Please write your application code
|
26 | }
|
27 | }
|
Das ist unsere momentanes LCD Programm zum testen. Also kommends sind teils falsch und verschoben und alles ;) viel copy and past und wieder löschen ... zum ausprobieren, was funzt und was nicht. ;) Momentan haben wir das Problem, das wir nichts geschrieben bekommen und auch ncihts gelöscht bekommen. Wir haben irgend welche willkürlichen Zeichen auf dem Display, die bei immer wieder aufspielen einfach nur verschoben werden. Ansonsten verändert sich nichts. Vllt. könnt ihr mir ja helfen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.