Forum: Compiler & IDEs LCD 204B-NLW & AtMega32


von alex44 (Gast)


Angehängte Dateien:

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 :)

von Klaus W. (mfgkw)


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.

von Klaus W. (mfgkw)


Lesenswert?

PS:
Eine vernünftige HW-Beschreibung wäre zur Fehlersuche nützlich.

von Alex44 (Gast)


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

von SF (Gast)


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

von Alex44 (Gast)


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

von Alex44 (Gast)


Lesenswert?

Der LED-Test funktioniert übrigens und die Signalzeiten konnte ich per 
Oszi messen und stimmen mit den Einstellungen überein.

von Alex44 (Gast)


Angehängte Dateien:

Lesenswert?

hier noch das neueste Datenblatt zu dem LCD.

von holger (Gast)


Lesenswert?

>- D0,D1,D2,D3,RW liegen auf GND

Dann lass D0..D3 einfach mal in der Luft hängen.

von Alex44 (Gast)


Lesenswert?

hat nichts geändert...

Dem Verständnis wegen: Was hätte es bringen können?

von holger (Gast)


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.

von holger (Gast)


Lesenswert?

Moment mal, ATMega32 und Portc? Dann JTAG abschalten;)

von Alex44 (Gast)


Angehängte Dateien:

Lesenswert?

Na hui - JTAG
habe nochmal einen Anschlussplan vom Kontroller rangehäng. Welcher Pin 
ist da das Problem?

von holger (Gast)


Lesenswert?

>habe nochmal einen Anschlussplan vom Kontroller rangehäng. Welcher Pin
>ist da das Problem?

TDI, TDO, TCK, TMS

von Alex44 (Gast)


Lesenswert?

Das scheint ganz schön kompliziert zu werden. Ich muss das 
softwareseitig lösen, damit ich den Quellcode später weiterreichen kann 
(was ich muss)

von Alex44 (Gast)


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

von ... (Gast)


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.

von alex44 (Gast)


Lesenswert?

es reicht dann einfach
1
MCUCSR |= (1<<JTD);

oben in meine main.c mit einzufügen!?

von alex44 (Gast)


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.

von Stefan E. (sternst)


Lesenswert?

alex44 schrieb:
> es reicht dann einfach
1
 MCUCSR |= (1<<JTD);
> oben in meine main.c mit einzufügen!?

Nein, reicht nicht. Schau ins Datenblatt, was dort zu dem Bit steht.

von alex44 (Gast)


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 :-)

von Stefan E. (sternst)


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.

von alex44 (Gast)


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

von holger (Gast)


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.

von alex44 (Gast)


Lesenswert?

Gibt es da noch einen anderen Weg?

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
Noch kein Account? Hier anmelden.