Forum: Compiler & IDEs Fehler bei 4Bit LCD Init?


von Thorsten P. (chaosmaker)


Angehängte Dateien:

Lesenswert?

Guten Morgen zusammen!

Ich verzweifel gerade dabei, ein LCD-Display an einen ATmega16 zu 
klemmen.
Allen die mich jetzt aufmerksam machen wollen auf anderen Foreneinträge 
kann ich versichern, ich habe schon alles durchsucht (nicht nur dieses 
Forum hier) und alle vorgefertigeten Codes ausprobiert.

Immer mit dem selben Missrfolg, dass sich nichts tut und das Display 
leer bleibt oder nur für den Bruchteil einer Sekunde auf beiden Zeilen 
den gleichen Sonderzeichenmüll anzeigt.

Kurz vorweg, der ATmega16 wurde schon gewechselt und das Display wurde 
auch schon durch ein Display anderen Types ersetzt, daher schliesse ich 
einen Hardwareschaden an den 2 Bauteilen aus.

Ich hoffe das wer den Fehler sieht den ich gemacht habe. Möglich wäre 
es, dass hier ein Fehler drin ist der natürlich in dem zum Teil fertig 
angebotenen Code nicht drin ist (allerdings funktionieren diese 
Beispiele ja auch nicht). Daher möchte ich alles von Grund auf einmal 
durchtesten und ausprobieren. Falls es nicht am Code liegen sollte, weis 
ich zumindest das die Software funktioniert.

Ich habe mir das Hitachi Datenblatt des HD44780 Controllers durchgelesen 
und eine sehr vereinfachte Form des 4Bit Inits und der Datenübertragung 
gebastelt.

Um die Arbeit zu erleichtern habe ich das Hitachi Datenblatt in  den 
Anhang gesteckt.
Die Seiten 47 (4Bit Init) und 25,26 (Table 6) der PDF sind wichtig.

Pinnbelegung von PA0 bis PA6:
D4 D5 D6 D7 RS RW EN
Die Spannungsversorgung sollte auch stimmen.

Es handelt sich um ein 2 Zeiliges Display mit 5x8 Punkten.

Hier der etwas beschnittene Code:
1
#define F_CPU 4000000  
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
6
#define LCD_PORT      PORTA
7
#define LCD_RS        4
8
#define LCD_RW        5
9
#define  LCD_EN        6
10
11
#define LCD_enable_pulse()   LCD_PORT &= ~(1 << LCD_EN);_delay_us(5);LCD_PORT |=  (1 << LCD_EN)
12
13
void   Port_Init(void) {  
14
  DDRA = 0b11111111;    // LCD  
15
  DDRD = 0b11110011; 
16
}
17
18
int   main(void) {
19
  
20
  Port_Init();
21
  LED1_R();
22
  LED2_R();
23
  LCD_PORT = 0b00000000;
24
  double speed = 10;
25
26
  // INIT  
27
28
  DELAY(1000); // 1000ms = 1s
29
30
  LCD_PORT = 0b00000011;  LCD_enable_pulse();     DELAY(10);
31
  
32
  LCD_PORT = 0b00000011;  LCD_enable_pulse();     DELAY(1);
33
  
34
  LCD_PORT = 0b00000011;  LCD_enable_pulse();  DELAY(speed);
35
  
36
  LCD_PORT = 0b00000010;  LCD_enable_pulse();     DELAY(speed);
37
  
38
  LCD_PORT = 0b00000010;  LCD_enable_pulse();  DELAY(speed);
39
  LCD_PORT = 0b00001011;  LCD_enable_pulse();  DELAY(speed);  
40
  
41
  LCD_PORT = 0b00000000;  LCD_enable_pulse();  DELAY(speed);
42
  LCD_PORT = 0b00001000;  LCD_enable_pulse();  DELAY(speed);  
43
44
  LCD_PORT = 0b00000000;  LCD_enable_pulse();  DELAY(speed);
45
  LCD_PORT = 0b00000001;  LCD_enable_pulse();  DELAY(speed);
46
  
47
  LCD_PORT = 0b00000000;  LCD_enable_pulse();  DELAY(speed);
48
  LCD_PORT = 0b00000111;  LCD_enable_pulse();  DELAY(speed);
49
50
  // DATA
51
52
  LCD_PORT = 0b00010011;  LCD_enable_pulse();  DELAY(speed);
53
  LCD_PORT = 0b00010001;  LCD_enable_pulse();  DELAY(speed);
54
  // => 1
55
56
  LCD_PORT = 0b00010011;  LCD_enable_pulse();  DELAY(speed);
57
  LCD_PORT = 0b00010010;  LCD_enable_pulse();  DELAY(speed);
58
  // => 2
59
60
  LCD_PORT = 0b00010011;  LCD_enable_pulse();  DELAY(speed);
61
  LCD_PORT = 0b00010011;  LCD_enable_pulse();  DELAY(speed);
62
  // => 3
63
  
64
  while(1) {
65
  
66
  }
67
}

Vielen Dank schonmal.

von Johannes M. (johnny-m)


Lesenswert?

Im Datenblatt meines HD44780-kompatiblen Displays sieht die 
Initialisierung etwas anders aus. Außerdem ist es sinnvoll, den 
ENABLE-Impuls als High-Impuls und nicht wie bei Dir als Low-Impuls 
durchzuführen. Abgesehen davon solltest Du alles an Code schicken, was 
für das Problem relevant sein könnte. Ich vermisse z.B. die Definition 
von DELAY().

von Thorsten P. (chaosmaker)


Lesenswert?

Ok den Pulse habe ich eben umgedreht da tut sich immer noch nichts.
1
#define LCD_enable_pulse()   LCD_PORT |=  (1 << LCD_EN);_delay_us(5);LCD_PORT &= ~(1 << LCD_EN)

Die DELAY Methode hatte ich mir schon einmal zurechtgefummelt und mit in 
den Header gepackt. hier ist der Code.
1
void   DELAY(float wait_delay) {
2
  float p;
3
  for(p=0;p<=wait_delay;p++) 
4
  {_delay_ms(1);}
5
}

Könntest du mir den Link für dein Datenblatt geben? Möglicherweise hat 
Hitachi ja doch unterschiede zum allgemienen HD44780 Chip.

von Johannes M. (johnny-m)


Lesenswert?

Was für ein Display ist das überhaupt? Meine sind von Electronic 
Assembly (www.lcd-module.de). Früher habe ich mal mit einem Sharp 2x16 
gearbeitet, und mit der selben Init-Routine laufen definitiv auch die 
EA-Module.

BTW:
Was hat Dich eigentlich geritten, einen float als Übergabeparameter für 
die DELAY-Funktion zu verwenden? Für eine Variable, bei der eh nur der 
ganzzahlige Anteil eine Bedeutung hat, benutzt man doch um Himmels 
Willen keinen Gleitkommatyp!

von Johannes M. (johnny-m)


Lesenswert?

> Könntest du mir den Link für dein Datenblatt geben? Möglicherweise hat
> Hitachi ja doch unterschiede zum allgemienen HD44780 Chip.
Übrigens: Der HD44780 IST von Hitachi. Deshalb wird es da wohl kaum 
Unterschiede geben. Bei anderen Display-Controllern (sog. 
44780-kompatible, z.B. der KS 0073, der in den EA-Displays verbaut ist) 
kann es geringfügige Unterschiede im Timing geben.

von Thorsten P. (chaosmaker)


Angehängte Dateien:

Lesenswert?

Johannes M. wrote:
> BTW:
> Was hat Dich eigentlich geritten, einen float als Übergabeparameter für
> die DELAY-Funktion zu verwenden? Für eine Variable, bei der eh nur der
> ganzzahlige Anteil eine Bedeutung hat, benutzt man doch um Himmels
> Willen keinen Gleitkommatyp!

Das ist ein Überbleibsel. Zuerst sollte das Dalay eben auch z.B. 120.5 
anerkennen können. Aber das hat wohl nichts mit dem grundlegenden 
Problem zu tun.

Datenblatt ist im Anhang.

von Johannes M. (johnny-m)


Angehängte Dateien:

Lesenswert?

Schön, das Datenblatt gibt anscheinend überhaupt keine Auskunft über 
4-Bit-Initialisierung. Das Hauptproblem an Deiner Initialisierung dürfte 
sein, dass Du die 8-Bit-Init aus dem Datenblatt übernommen hast und das 
Display zunächst auch auf 8 Bit initialisierst! Du darfst am Anfang kein 
"0b00000011" senden. Das muss "0b00000010" sein. Die erste Version sagt 
dem Display, dass es im 8-Bit-Modus angesteuert wird.

Ich hab Dir mal das Sharp-LCD-Manual angehängt. Ist zwar schon älter, 
aber mit den Initialisierungsroutinen da drin hab ich bisher noch jedes 
Display ans laufen gekriegt. Auf S. 14 ist die Init-Sequenz für den 
4-Bit-Modus.

von Johannes M. (johnny-m)


Lesenswert?

BTW:
Mit den Displaytech-Modulen hab ich auch schon gearbeitet und die 
Initialisierungs-Sequenz nach dem Sharp-Manual funktioniert 
nachgewiesenermaßen.

von Thorsten P. (chaosmaker)


Lesenswert?

Im Hitachi DB und in deinem von Sharp steht das zuerst 3mal 0b00000011 
(im 8Bit Modus) gesendet werden soll und dann erst 0b00000010 zum 
umschalten auf 4Bit.

Netterweise passt dein Vorschlag. Ich bekomme jetzt eine Ausgabe, mit 
ein paar Ausgabefehlern. Aber die bekomme ich schon behoben.

Danke vielmals!

von Johannes M. (johnny-m)


Lesenswert?

Jau, hast Recht. Hatte ich jetzt nicht mehr so genau hingeschaut. Aber 
wenns läuft ist ja gut.

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.