Hallo,
ich habe fast da gleiche Problem wie hier schon beschrieben
Beitrag "LCD Displaytech 204B & ATmega32"
Auch bei mir erscheinen nach dem Einschalten nur die Zeilen 1 und 3.
Ändern tut sich da jedoch nichts. Mit dem Oszi konnte ich feststellen,
dass das enable-Bit low und rw und rs high sind (statisch).
Wenn ich lcd_string("Hello World!"); in die while-Schleife in main.c
stecke dann springt das enable-Bit mit
h(6us)-l(20us)-h(6us)-l(20us)-h(6us)-l(60us) und rs, rw sind high. Auf
den Datenleitungen scheint auch etwas übertragen zu werden. Komisch ist,
dass das MSB einen induktiven Kurvenverlauf hat. Mit zwei kurzen
Impulsen und einem langen.
Im Datenblatt steht am Rand ein Kommentar:
"Im 4-Bit Mode ist die Busy-Abfrage vor jedem Bytezugriff notwendig"
In den Routinen aus dem Tutorial konnte ich keine Aufrufe dazu finden.
Weiß aber auch nicht, wie man eine solche Abfrage durchführt. (Wenn denn
nötig)
Ansonsten habe ich echt keinen Plan wie ich da weite ran gehen soll.
Leider ist das Datenblatt auch nicht sehr umfangreich.
Ich bedanke mich schon im Vorraus für eure Hilfe.
PS: Eure Tutorien finde ich echt gut gelungen :)
alex44 schrieb:> und rw und rs high sind (statisch).alex44 schrieb:> und rs, rw sind high.
Nur wenn RW low ist, wird geschrieben.
Falls du vom gleichen Beispiel im Tutorial redest, wird RW da gar nicht
per Programm gesetzt, sondern dauerhaft auf low gelegt (per Schaltung).
alex44 schrieb:> Im Datenblatt steht am Rand ein Kommentar:> "Im 4-Bit Mode ist die Busy-Abfrage vor jedem Bytezugriff notwendig"
Wenn man jeweils lange genug wartet, braucht man kein BUSY abfragen.
Siehe oben.
alex44 schrieb:> Ansonsten habe ich echt keinen Plan wie ich da weite ran gehen soll.> Leider ist das Datenblatt auch nicht sehr umfangreich.
Das Beispiel aus dem Tutorial vielleicht mal genau übernehmen?
Ein weiterer Fallstrick ist die Taktfrequenz: wenn der Rechner schneller
läuft, als der Compiler vermutet (F_CPU), dann stimmen die Wartezeiten
nicht.
Zur Kontrolle lasse ich gerne mal mit delay_ms(1000) eine LED blinken;
dann sieht man schnell, ob eine Sekunde wirklich eine Sekunde ist.
Hallo
Klaus Wachtler schrieb:> alex44 schrieb:>> Im Datenblatt steht am Rand ein Kommentar:>> "Im 4-Bit Mode ist die Busy-Abfrage vor jedem Bytezugriff notwendig">> Wenn man jeweils lange genug wartet, braucht man kein BUSY abfragen.> Siehe oben.
"Merkt" das LCD, ob es abgefragt worden ist? Ich glaube nicht. Die
Anfrage ist dann nur für den Datensender interessant.
Klaus Wachtler schrieb:> Ein weiterer Fallstrick ist die Taktfrequenz: wenn der Rechner schneller> läuft, als der Compiler vermutet (F_CPU), dann stimmen die Wartezeiten> nicht.> Zur Kontrolle lasse ich gerne mal mit delay_ms(1000) eine LED blinken;> dann sieht man schnell, ob eine Sekunde wirklich eine Sekunde ist.
Die eingestellten Zeiten stimmen. Konnte ich nachmessen.
Ich habe mal im Datenblatt nachgeschaut. Kann es an den Flanken und an
den Pulslängen liegen?
Da steht:
- max 25ns - Flankenanstieg
- min 0,45us - Enable Impuls high
- min 1,00us - Enable Zyklus
- min 0,14us - Address setup
Besonders beim ersten steht im Blatt: "besonders zu beachten". Ich kann
das mit meinem Oszi nur nicht genau messen, da ich nur bis 0,5us runter
kann.
Ich werde mal ein kleines Testprogramm ohne Routinen schreiben. Mal
sehen was dabei rumkommt.
Klaus Wachtler schrieb:> PS:> Eine vernünftige HW-Beschreibung wäre zur Fehlersuche nützlich.
Was ist das?
Danke und Gruß
Alex
Wie hast du denn den Kontrastpin des LCDs(Pin3, Vee) angeschlossen? So
wie im Tutorial
(http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung)?
Hast du dann mal am Poti gedreht?
Eventuell hast du einfach nur den Kontrast falsch eingestellt.
Eine Hardwarebeschreibung wäre, wenn du uns erklärst/veranschaulichst,
wie du das LCD beschaltest hast und an den µC angeschlossen hast.
Eventuell mit Schaltplan und einem Foto des Aufbaus.
Ansonsten kann man, ob der vielen Fehlermöglichkeiten nur raten, was bei
dir konkret falsch sein könnte...
Hallo,
- VDD ist an einen 5V Spannungsregler angeschlossen.
- Vee ist über ein 10k Poti wie im Tutorial angeschlossen.
- LED+ hat einen 50 Ohm Vorwiderstand.
- D4 liegt an PC0
- D5 liegt an PC1
- D6 liegt an PC2
- D7 liegt an PC3
- RS liegt an PC4
- E liegt an PC6
- D0,D1,D2,D3,RW liegen auf GND
Da delay.h auf 10000000ul eingestellt ist habe ich das in die routinen.h
so übernommen.
Dazu habe ich die routinen.h angepasst...
1
// LCD DB4-DB7 <--> PORTC Bit PC0-PC3
2
#define LCD_PORT PORTC
3
#define LCD_DDR DDRC
4
#define LCD_DB PC0
5
6
// LCD RS <--> PORTD Bit PC4 (RS: 0=Data, 1=Command)
7
#define LCD_RS PC4
8
9
// LCD EN <--> PORTD Bit PC5 (EN: 1-Impuls für Daten)
10
#define LCD_EN PC6
Da es mein Display mit zwei verschieden Kontrollern gibt, habe ich beide
ausprobiert:
für KS0073
1
#define LCD_DDADR_LINE1 0x00
2
#define LCD_DDADR_LINE2 0x20
3
#define LCD_DDADR_LINE3 0x40
4
#define LCD_DDADR_LINE4 0x60
für HD44780
1
#define LCD_DDADR_LINE1 0x00
2
#define LCD_DDADR_LINE2 0x40
3
#define LCD_DDADR_LINE3 0x14
4
#define LCD_DDADR_LINE4 0x54
Habe auch beides mit
1
while(1)
2
{
3
lcd_string("Hello World!");
4
}
in der main getestet.
Dann habe ich mal die Zeiten aus dem Datenblatt angepasst:
1
#define LCD_BOOTUP_MS 50
2
#define LCD_ENABLE_US 1
3
#define LCD_WRITEDATA_US 50
4
#define LCD_COMMAND_US 50
5
6
#define LCD_SOFT_RESET_MS1 5
7
#define LCD_SOFT_RESET_MS2 5
8
#define LCD_SOFT_RESET_MS3 5
9
#define LCD_SET_4BITMODE_MS 5
10
11
#define LCD_CLEAR_DISPLAY_MS 2
12
#define LCD_CURSOR_HOME_MS 2
Auch versucht habe ich in der init:
1
lcd_command(LCD_SET_DISPLAY|
2
LCD_DISPLAY_ON|
3
LCD_CURSOR_ON|
4
LCD_BLINKING_ON);
ändert aber auch nichts
Was ich immer sehe, wenn ich den Kontrast hoch regele ist, sind jeweils
ein Balken in Zeile eins und drei.
Ich hoffe, dass diese Informationen weiter helfen können...
Gruß
Alex
>hat nichts geändert...
Schade:(
>Dem Verständnis wegen: Was hätte es bringen können?
Normalerweise schliesst man diese Leitungen nicht an
GND an. Es soll wohl Displays geben die das wohl möchten,
aber die sind eher die Ausnahme. Ich hatte noch keins von den Dingern.
Falls dein Display einen Ks0073 Controller hat, dann reicht das hier
nicht:
>für KS0073>>#define LCD_DDADR_LINE1 0x00
Allerdings solltest du auch deinen Anschluss zum
Display noch ein paar mal überprüfen. Hardwarefehler
waren hier zu mindestens 50% das Problem wenn das
LCD nicht geht.
Habe da was im Datenblatt gefunden:
"When the JTAGEN fuse is unprogrammed, these four TAP pins are normal
port pins and the TAP controller is in reset. When programmed and the
JTD bit in MCUCSR is cleared, the TAP input signals are internally
pulled high and the JTAG is enabled for Boundary-scan and programming.
In this case, the TAP output pin (TDO) is left floating in states where
the JTAG TAP controller is not shifting data, and must therefore be
connected to a pull-up resistor or other hardware having pull-ups (for
instance the TDI-input of the next device in the scan chain). The device
is shipped with this fuse programmed."
Ich nehme mal an, dass man sich hier über den MCUCSR Fusebite hermachen
und dort das bit JTD zu null setzen muss.
In der Registerübersicht findet sich weiter folgendes:
1
Address | Name | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
MCUCSR ist ein µC-Register und hat mit den Fuses nicht wirklich was zu
tun.
Alex44 schrieb:> Jetzt müsste ich eigentlich nur das Bit von der Addresse holen und das> Entsprechenden Null setzen.
Nein, das Flag heißt nicht umsonst JTD ("JTAG Disable"). Du mußt es auf
1 setzen.
Im Deinem angedeuteten Sourcecode ist es allerdings schon richtig. Nur
das define ist Mist, das steht bereits in dem ensprechenden Headerfile
drin.
Was mich übrigens immer noch ziemlich stark irritiert ist, dass ein Bit
nicht so gesetzt wird wie ich es meine programmiert zu haben.
Dazu habe ich folgendes ergänzt:
routinen.h
1
// LCD RW <--> PORTC Bit PC5 (RW: 0=Write, 1=Read)
2
#define LCD_RW PC5
routinen.c
1
voidlcd_init(void)
2
{
3
// verwendete Pins auf Ausgang schalten
4
uint8_tpins=(0x0F<<LCD_DB)|// 4 Datenleitungen
5
(1<<LCD_RS)|// R/S Leitung
6
(1<<LCD_EN)|// Enable Leitung
7
(1<<LCD_RW);// RW Leitung
8
LCD_DDR|=pins;
9
10
// initial alle Ausgänge auf Null
11
LCD_PORT&=~pins;
12
13
// RW auf 0 setzen - LCD-Empfängt Daten
14
LCD_PORT&=~(1<<LCD_RW);
15
...
16
}
dabei ist
1
// RW auf 0 setzen - LCD-Empfängt Daten
2
LCD_PORT&=~(1<<LCD_RW);
doppelt gemoppelt, da das ja schon mit LCD_PORT &= ~pins; abgegolten
sein sollte. Aber das alleine führte auch nicht zum Erfolg.
Ich konnte allerdings feststellen nachdem ich
1
MCUCSR|=(1<<JTD);
in die main.c eingefügt habe, dass sich die Ausgangsspannung an PC5
komisch verhält. Ohne LED bekomme ich da ein high, mit LED fällt die
Spannung auf ca. 2V ab.
Ich hoffe, dass das zur Fehlerfindung beiträgt.
Stefan Ernst schrieb:> Nein, reicht nicht. Schau ins Datenblatt, was dort zu dem Bit steht.
Eine wenig hilfreiche Antwort. Hätte ich es verstanden, würde ich nicht
fragen.
Trotz allem fand ich einen Hinweis in einem anderen Beitrag.
1
MCUCSR|=(1<<JTD);
2
MCUCSR|=(1<<JTD);
Einfach zweimal den Befehl und alles ist schick. Das Programm läuft ;-)
Danke für eure Hilfe :-)
alex44 schrieb:> Eine wenig hilfreiche Antwort.
Nein? Du hast doch offensichtlich auf Grund dieser Antwort nochmal
recherchiert und die Lösung gefunden, oder nicht?
> Hätte ich es verstanden, würde ich nicht fragen.
Du hast nirgendwo erwähnt die Beschreibung zu dem Bit im Datenblatt
gelesen (aber nicht verstanden) zu haben. Daher meine Aufforderung, sich
das mal durchzulesen.
Und ehrlich gesagt bin ich immer noch geneigt zu bezweifeln, dass du sie
je gelesen hast (weder vor noch nach meiner Antwort), denn die
Beschreibung dort ist kaum missverständlich.
Stefan Ernst schrieb:> Nein? Du hast doch offensichtlich auf Grund dieser Antwort nochmal> recherchiert und die Lösung gefunden, oder nicht?
Da hast Du Recht :)
Zu dem anderen: Ich habe es versucht zu lesen aber mit meinen
Englischkenntnissen kann ich wirklich keinen beeindrucken. Von daher...
Nichts desto Trotz: Vielen Dank nochmal
>Trotz allem fand ich einen Hinweis in einem anderen Beitrag.>>MCUCSR |= (1<<JTD);>MCUCSR |= (1<<JTD);>>Einfach zweimal den Befehl und alles ist schick. Das Programm läuft ;-)
Geht doch;) JTAG Fuse abschalten hätte auch gereicht und frisst
kein Flash.