Hallo!
Ich verwende ein Displaytech 162B im 4-Bit Betrieb) und verstehe die
Initialisierungsroutine nicht ganz.
Wenn ich das Datenbit DB4 in den ersten 3 Schritten auf 1 stelle,
funktioniert die Anzeige nicht. Ist das Bit jeweils auf 0, ist alles OK!
Sollte nach der Anleitung im Datenblatt nicht 3 Mal eine 1 für DB4
geschrieben werden? Der 4-Bit Modus wird ja erst im 4. Schritt (set
function - interface auf 4 bit setzen) eingestellt.
Oder habe ich hier etwas falsch verstanden?
Anbei meine Init-Tabelle und das Datenblatt.
Die 1 bedeutet 8-Bit-Mode, die 0 4-Bit-Mode.
Da man sich nie sicher sein kann, in welchem Zustand sich das Dislay
befindet (z.B. nach Reset am μC):
Startzustand: 8-Bit 4-Bit 1.Nibble 2.Nibble
Nibble
1. 0011 8-Bit-Mode 8-Bit-Mode abh.von 1.Nibble, dont care
2. 0011 8-Bit-Mode 1line,5x7 8-Bit-Mode
3. 0011 8-Bit-Mode 8-Bit-Mode 1line,5x7
Ab hier haben wir definitiv 8-Bit-Mode (ein E-Pulse->ein Kommando)
4. 0010 4-Bit-Mode 4-Bit-Mode 4-Bit-Mode
Ab hier haben wir definitiv 4-Bit-Mode, müssen also 2 Nibbles je
Kommando ausgeben
5. 0010 4-Bit-Mode
6. NFxx N:lines; F:font
Damit hat man EINEN zuverlässigen Weg aus jedem Anfangszustand. Nach
Power-On am Display funktionieren auch andere. Erst bei Reset am μC
sieht man, ob's immer geht.
m. g. schrieb:> sbi(LCDPORT, LCD_PIN_D5); // D5 = 1> sbi(LCDPORT, LCD_PIN_D4); // D4 = 1> _delay_ms(40);
Ich glaube, du solltest die Daten auch abschicken.
Ralf G. schrieb:> Ich glaube, du solltest die Daten auch abschicken.
Huiii! Natürlich ;-)
Ich hab´s jetzt mal so gelöst:
Die Lösung mit den beiden Bits D5 und D4 in 2 Zeilen für die oberen 4
Bits zu setzen gefällt mir aber nicht wirklich gut. Hat hier jemand eine
bessere Lösung?
1
/****** Initialisierung des LCD Controllers *****/
2
voidlcd_init()
3
{
4
/* Port auf Ausgang schalten */
5
LCDDDR=0xFF;
6
LCDPORT=0x00;
7
_delay_ms(40);// Warten bis LCD bereit ...
8
9
/* LCD Soft-Reset 1*/
10
LCDPORT=(1<<LCD_PIN_D5);
11
LCDPORT|=(1<<LCD_PIN_D4);
12
set_enable();// Daten/Kommando übernehmen
13
LCDPORT=0x00;
14
set_enable();// Daten/Kommando übernehmen
15
_delay_ms(40);
16
17
/* LCD Soft-Reset 2*/
18
LCDPORT=(1<<LCD_PIN_D5);
19
LCDPORT|=(1<<LCD_PIN_D4);
20
set_enable();// Daten/Kommando übernehmen
21
LCDPORT=0x00;
22
set_enable();// Daten/Kommando übernehmen
23
_delay_ms(5);
24
25
/* LCD Soft-Reset 3*/
26
LCDPORT=(1<<LCD_PIN_D5);
27
LCDPORT|=(1<<LCD_PIN_D4);
28
set_enable();// Daten/Kommando übernehmen
29
LCDPORT=0x00;
30
set_enable();// Daten/Kommando übernehmen
31
_delay_ms(1);
32
33
/* 2 Zeilen, 4-Bit Modus */
34
lcd_send(BEFEHL,LCD_SET_1);// Register SET FUNCTION = 0010 1000
35
lcd_send(BEFEHL,LCD_OFF);// Set LCD OFF
36
lcd_send(BEFEHL,LCD_CLEAR);// Clear LCD
37
lcd_send(BEFEHL,LCD_SET_2);// Set ENTRY MODE = 0000 0110
m. g. schrieb:> Hat hier jemand eine bessere Lösung?
LCDPORT &= ~(alle bits die du neu setzen willst)
^ not!
LCDPORT |= (genau das was du alles reinschreiben willst)
>> set_enable();
eine sehr ungeeignete Benamung, denn was man setzt ist
erst einmal gesetzt. Das was deine Routine macht ist aber
offensichtlich einen Zyklus ausführen.
Mitlesa schrieb:>>> set_enable();>> eine sehr ungeeignete Benamung, denn was man setzt ist> erst einmal gesetzt. Das was deine Routine macht ist aber> offensichtlich einen Zyklus ausführen.
Ja, da hast du recht!
Ich hab meinen Code nun wie folgt geändert:
1
/****** Initialisierung des LCD Controllers *****/
Du schreibst immer noch den ganzen Port obwohl du nur 4 Bit
brauchst und willst. Könnte ja sein dass due die anderen
Bits für was anderes brauchst.
Das LCD braucht beim Init nur die 4 Bit da es ja noch nicht
weiss ob es 4 oder 8 bit machen soll, daher ist der zweite
Zyklus, das untere Nibble, nicht erforderlich.
Vor allem betreibst du die Schnittstelle immer im 4-Bit-Modus (Ausgabe
des 2.Nibbles). Diese 3x "8-Bit-Mode" am Anfang sollen das LCD aber
definiert in den 8-Bit-Modus bringen. Erst dann weiß man, daß das nun
folgende "4-Bit" richtig interpretiert wird.
1
/****** Initialisierung des LCD Controllers *****/
Carl D. schrieb:> Falls es dir aber nicht darum geht das zu verstehen, warum nimmst du> nicht einfach den Code aus dem Tutorial?
Danke für die Hilfe!
Mir geht es vor allem darum, den Code und die Initialisierung zu
verstehen!
Stimmt, ich hätte jedwede Hilfe aus formalen Gründen ablehnen sollen.
(es gibt neben dem weißen Schimmel auch noch den Schwarzen, nicht zu
vergessen den Adligen: von Amtswegen)
Ok, soweit habe ich das jetzt verstanden!
Wenn ich jetzt aber am PORTD den Pin 3 für Enable und Pin 2 für RS
verwenden möchte, dann muss ich die Bits D5 und D4 mit dem Makro
sbi(Port,Pin) setzen. Richtig?
1
#define LCDPORT PORTD
2
#define LCDDDR DDRD
3
#define LCD_PIN_RS 2
4
#define LCD_PIN_E 3
5
#define LCD_PIN_D4 4
6
#define LCD_PIN_D5 5
7
#define LCD_PIN_D6 6
8
#define LCD_PIN_D7 7
9
#define LCD_SETDDRAM 0x80 // Set Display RAM Address
10
...
11
...
12
...
13
/****** Initialisierung des LCD Controllers *****/
14
voidlcd_init()
15
{
16
/* Port auf Ausgang schalten */
17
LCDDDR=0xFF;
18
LCDPORT=0x00;
19
_delay_ms(40);// Warten bis LCD bereit ...
20
21
/* LCD Soft-Reset 1*/
22
sbi(LCDPORT,LCD_PIN_D5);// LCD D5 = 1
23
sbi(LCDPORT,LCD_PIN_D4);// LCD D4 = 1
24
toggle_enable();// Kommando übernehmen
25
_delay_ms(40);
26
27
/* LCD Soft-Reset 2*/
28
toggle_enable();// Kommando übernehmen
29
_delay_ms(5);
30
31
/* LCD Soft-Reset 3*/
32
toggle_enable();// Kommando übernehmen
33
_delay_ms(1);
34
35
// Ab hier ist sicher der 8-Bit Mode eingestellt!
36
// Somit wird das folgende Kommando auch richtig verstanden!