LCD 204B-NLW & AtMega32

Gast #2222960
Lesenswert?

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 :)
Angehängte Dateien:
#2223128
Lesenswert?

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.
Gast #2224218
Lesenswert?

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
Gast #2224229
Lesenswert?

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...
Gast #2224734
Lesenswert?

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
Gast #2225256
Lesenswert?

>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.
Gast #2225596
Lesenswert?

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 
2
$34 ($54) | MCUCSR | JTD   | ISC2  | –     | JTRF  | WDRF  | BORF  | EXTRF | PORF

Jetzt müsste ich eigentlich nur das Bit von der Addresse holen und das 
Entsprechenden Null setzen. Geht das so?:
1
#define JTD 7
2
MCUCSR |= (1<<JTD);
Reicht das, oder muss ich da noch was dazuschreiben? Kennt avrgcc die 
adresse wo das hinmuss, oder muss da noch was entsprechendes definieren?

Grüße
Gast #2225621
Lesenswert?

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.
Gast #2225911
Lesenswert?

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
void lcd_init( void )
2
{
3
    // verwendete Pins auf Ausgang schalten
4
    uint8_t pins = (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.
Gast #2226776
Lesenswert?

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 :-)
#2226827
Lesenswert?

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.
Gast #2226935
Lesenswert?

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
Gast #2227000
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren