Forum: Mikrocontroller und Digitale Elektronik Ansteuerung EA DIP203-LCD


von Marco G. (grmg2010)


Angehängte Dateien:

Lesenswert?

Moin,

ich habe ein EA DIP203-LCD mit grüner Hintergrundbeleuchtung. Im Betrieb 
zeigt sich ein schwarzer Hintergrund mit heller Schrift. anscheinend ist 
das Display invertiert. Gibt es ein konkretes Bit, welches sie 
Invertierung steuert? welche Bitkombination muss gewählt werden, um die 
Invertierung rückgängig zu machen und so die Schrift auf Schwarz und den 
Hintergrund auf hell zu schalten?

Gruß

von hinz (Gast)


Lesenswert?

Du musst das 
Polarisationsfilterabziehundumneunziggradgedrehtwiederaufklebbit setzen.

von Wolfgang A. (Gast)


Lesenswert?

Marco G. schrieb:
> welche Bitkombination muss gewählt werden, um die
> Invertierung rückgängig zu machen und so die Schrift auf Schwarz und den
> Hintergrund auf hell zu schalten?

Guckst du Datenblatt Seite 2: reverse bit

von Marco G. (grmg2010)


Lesenswert?

@ Wolfgang

Genau das habe ich auch gesehen und eigentlich auf Null gesetzt, aber 
trotzdem stellt das LCD es immer noch invertiert dar.

von Karl H. (kbuchegg)


Lesenswert?

Marco G. schrieb:
> @ Wolfgang
>
> Genau das habe ich auch gesehen und eigentlich auf Null gesetzt,

Das kann jeder sagen.

Zeig den Code

von Marco G. (grmg2010)


Lesenswert?

Hier mal der Code:
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
    LCD_DDR |= pins;
8
 
9
    // initial alle Ausgänge auf Null
10
    LCD_PORT &= ~pins;
11
 
12
    // warten auf die Bereitschaft des LCD
13
    _delay_ms( LCD_BOOTUP_MS );
14
 
15
16
    lcd_out( LCD_SOFT_RESET );
17
    _delay_ms( LCD_SOFT_RESET_MS1 );
18
 
19
    lcd_enable();
20
    _delay_ms( LCD_SOFT_RESET_MS2 );
21
 
22
    lcd_enable();
23
    _delay_ms( LCD_SOFT_RESET_MS3 );
24
 
25
    // 4-bit Modus aktivieren 
26
    lcd_out( LCD_SET_FUNCTION |
27
             LCD_FUNCTION_4BIT );
28
    _delay_ms( LCD_SET_4BITMODE_MS );
29
 
30
    // 4-bit Modus / 2 Zeilen / 5x7
31
    lcd_command( LCD_SET_FUNCTION |
32
                 LCD_FUNCTION_4BIT |
33
                 LCD_FUNCTION_4Line |
34
                 //LCD_FUNCTION_2LINE |
35
                 LCD_FUNCTION_5X7 |
36
                 0x20);
37
 
38
    // Display ein / Cursor aus / Blinken aus
39
    lcd_command( LCD_SET_DISPLAY |
40
                 LCD_DISPLAY_ON |
41
                 LCD_CURSOR_OFF |
42
                 LCD_BLINKING_OFF); 
43
 
44
    // Cursor inkrement / kein Scrollen
45
    lcd_command( LCD_SET_ENTRY |
46
                 LCD_ENTRY_INCREASE |
47
                 LCD_ENTRY_NOSHIFT );
48
 
49
    lcd_clear();
50
}
1
// Set Function --------------- 0b001xxxxx
2
#define LCD_SET_FUNCTION        0x20
3
 
4
#define LCD_FUNCTION_4BIT       0x00
5
#define LCD_FUNCTION_8BIT       0x10
6
#define LCD_FUNCTION_1LINE      0x00
7
#define LCD_FUNCTION_2LINE      0x08
8
#define LCD_FUNCTION_5X7        0x00
9
#define LCD_FUNCTION_5X10       0x04
10
#define LCD_FUNCTION_test       0x01
11
#define LCD_FUNCTION_4Line      0x09
12
#define LCD_FUNCTION_test       0x20
13
  
14
#define LCD_SOFT_RESET          0x30
LCD_FUNCTION_test soll die Invertierung aufheben.

von Karl H. (kbuchegg)


Lesenswert?

Marco G. schrieb:

> LCD_FUNCTION_test soll die Invertierung aufheben.

Schön.
Wird aber im Code gar nicht verwendet.

Aber das hier
1
#define LCD_FUNCTION_4Line      0x09

funktioniert im Zusammenhang mit dem hier
1
    lcd_command( LCD_SET_FUNCTION |
2
                 LCD_FUNCTION_4BIT |
3
                 LCD_FUNCTION_4Line |
4
                 //LCD_FUNCTION_2LINE |
5
                 LCD_FUNCTION_5X7 |
6
                 0x20);

so nicht.
Siehe das Initialisierungsbeispiel auf der Seite 3.
Um auf 4 Zeilen zu schalten sind offenbar 2 Bytes notwendig.
Erst mal muss ein SET_FUNCTION gemacht werden, bei dem das Bit "RE" 
(extension) den Wert 1 hat. Nach diesem Befehl wird ein weiteres Byte 
eingeschoben, in dem dann das Bit für den 4-Zeilen Modus sitzt.

Interesssanterweise hast du mit 0x09 genau das 'Reverse' Bit gesetzt.

von Marco G. (grmg2010)


Lesenswert?

Das ist mir gerade auch aufgefallen, das das 0x09 das Problem ist. Ich 
werde es jetzt noch einmal in zwei unterschiedlichen aufrufen probieren, 
wie im Datenblatt angegeben, nur als 4Bit-Modus.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> Erst mal muss ein SET_FUNCTION gemacht werden, bei dem das Bit "RE"
> (extension) den Wert 1 hat. Nach diesem Befehl wird ein weiteres Byte
> eingeschoben, in dem dann das Bit für den 4-Zeilen Modus sitzt.

Konkreter funktioniert das so:

In der Befehlstabelle ist die erste Spalte das RE Bit.
Je nachdem ob dieses Bit 0 oder 1 ist, haben ein paar der Befehle 
unterschiedliche Interpretation in den Bits.

Um das RE Bit auf 0 oder 1 zu kriegen ist ein "Function Set" Kommando 
notwendig. Mit dem kann das RE Bit auf den gewünschten Zustand gebracht 
werden und schaltet so zum Beispiel zwischen dem Kommado "Display 
on/off" und dem Kommando "extended Function Set" um, wenn vom LCD ein 
Kommando Byte empfangen wird, welches mit der Bitsequenz "0b00001xxx" 
das Kommando identifiziert.

von Marco G. (grmg2010)


Lesenswert?

Ich habe jetzt folgendes probiert, aber irgendwie funktioniert das noch 
nicht richtig:

lcd_command(0x24| //setzte 4Bit-Modus RE=1
            0x09);//setze 4-Zeilen Modus

lcd_command(0x20| //setzte 4Bit-Modus RE=0
            0x08);

Wenn ich die erste Variante wähle, gibt es zwei Zeilen invertiert, bei 
der zweiten Variante vier Zeilen nicht invertiert. Worin ist mein 
Denkfehler?

von Karl H. (kbuchegg)


Lesenswert?

Marco G. schrieb:
> Ich habe jetzt folgendes probiert, aber irgendwie funktioniert das noch
> nicht richtig:
>
> lcd_command(0x24| //setzte 4Bit-Modus RE=1
>             0x09);//setze 4-Zeilen Modus

2 Kommandos! Hintereinander!
1
   lcd_command( 0x24 );   // Function Set, wobei RE auf 1 geschaltet wird
2
   lcd_command( 0x09 );   // d.h. das hier ist nicht mehr das Kommando
3
                          // "Display on/off", sondern das Kommando "extended Function set"

ist doch wirklich nicht so schwer.


Und danach würde ich das RE Bit mit einem weiteren Function Set Kommando 
wieder auf 0 setzen.

von Karl H. (kbuchegg)


Lesenswert?

Marco G. schrieb:

> Worin ist mein
> Denkfehler?

Das du denkst, dein LCD würde sich irgendeinen feuchten Kehrricht darum 
scheren, mit wievielen und welchen Oder-Operationen du in deinem C Code 
das Byte zusammensetzt, dass dann als ganzes zum LCD übertragen wird.

von Marco G. (grmg2010)


Lesenswert?

Ich kann durch die Sequenz

lcd_command( 0x24 );
lcd_cómmand( 0x09 );
lcd_command( 0x20 );

den vierzeiligen Modus aktivieren. Wenn ich wieder auf den zweizeiligen 
Modus zurück möchte, muss ich doch einfach die Änderung rückgängig 
machen, also so:

lcd_command( 0x24 );
lcd_cómmand( 0x08 );
lcd_command( 0x20 );

Stimmt das so, oder habe ich noch etwas übersehen?

von Karl H. (kbuchegg)


Lesenswert?

Marco G. schrieb:

> Stimmt das so

Die Antwort sagt dir dein LCD
Entweder es tut das, was du von ihm willst. In dem Fall wird die Sequenz 
wohl soweit (bis auf Nebenbedingungen in den anderen Bits) richtig sein.
Oder es tut nicht das, was du von ihm willst, dann ist die Sequenz 
falsch.

von Marco G. (grmg2010)


Lesenswert?

und das genau: Ich schalte auf 2 Zeilen um und invertiere.

von Karl H. (kbuchegg)


Lesenswert?

> lcd_command( 0x20 );
Ich hätt halt 0x28 genommen, da du ja auf 2 zeilig willst.

D.h. eigentlich hätt ich auch nicht 0x28 genommen, sondern
1
    lcd_command( LCD_SET_FUNCTION |
2
                 LCD_FUNCTION_4BIT |
3
                 LCD_FUNCTION_2LINE |
4
                 LCD_FUNCTION_5X7 );
weils dann halt doch lesbarer ist, als eine Hex-Zahl. Auch wenns letzten 
Endes ohnehin für den µC aufs gleiche rausläuft.

von Marco G. (grmg2010)


Lesenswert?

Leider bringt das nichts, es bleibt bei einem vierzeiligen Display. Die 
Aufforderung wieder in den zweizeiligen Modus zu wechseln wird nicht 
angenommen.

von Karl H. (kbuchegg)


Lesenswert?

Wobei sich die Frage erhebt, ob das überhaupt möglich ist.
Wozu sollte man das auch tun, ein eigentlich 4 zeiliges LCD in einem 2 
Zeilen Modus betreiben. Die physikalisch ins Glas geätzten Pixel werden 
deswegen ja nicht mehr oder weniger.
Wenn du nur 2 der physikalisch vorhandenen 4 Zeilen benutzen willst, 
dann beschreib halt nur die beiden Zeilen.

von Marco G. (grmg2010)


Lesenswert?

Das ist natürlich richtig, aber laut Datenblatt soll dies ja gehen.

von Karl H. (kbuchegg)


Lesenswert?

Marco G. schrieb:
> Das ist natürlich richtig, aber laut Datenblatt soll dies ja gehen.

Das steht so nicht im Datenblatt.
Keine Ahnung ob der Controller das nochmal zurück schalten kann.
Wichtig ist, das man das LCD in einen 4-Zeilen Modus reinkriegt (wenn es 
den nicht schon beim Power-Up sowieso schon hat)

von Marco G. (grmg2010)


Lesenswert?

Ok, stimmt. Aber es funktioniert ja schon, es ist dann nur 
invertiert....

von Karl H. (kbuchegg)


Lesenswert?

Marco G. schrieb:
> Ok, stimmt. Aber es funktioniert ja schon, es ist dann nur
> invertiert....

Dann wirst du wohl irgendwo in deinem Code wieder mal das Bit 0 in beim 
Function Set gesetzt haben. Wenn du dauernd weiterhin mit Hex-Zahlen um 
dich wirfst, würde mich das nicht weiter wundern.

von Marco G. (grmg2010)


Angehängte Dateien:

Lesenswert?

Da hatte ich (mal wieder) das Datenblatt falsch interpretiert. Ich 
dachte, das RE-Bit muss auf null stehen, um zu invertieren (siehe 
Anhang)

von Karl H. (kbuchegg)


Angehängte Dateien:

Lesenswert?

Ach MIst, da hab ich mich auch verhaut.
Wenn das RE Bit erst mal auf 1 gesetzt ist, dann gilt ja nicht mehr die 
von dir eingekringelte INterpretation, sondern die darunter.

D.h. das ist ein mehrstufiger Prozess
* mit einem FUNCTION SET erst mal das RE Bit auf 1 setzen
* dann den 4-Zeilen Modus ausschalten
* dann mit der 'unteren' Interpretation das RE Bit wieder auf 0 setzen 
(momentan steht es ja noch auf 1)
* und erst dann gilt wieder die eingekringelte Version und du kannst auf 
2 Zeilen (bzw. Revers/Not Reverse) schalt

von Marco G. (grmg2010)


Lesenswert?

Ich habe das jetzt so gelöst:

lcd_command(0b001001010);

von Karl H. (kbuchegg)


Lesenswert?

Marco G. schrieb:
> Ich habe das jetzt so gelöst:
>
> lcd_command(0b001001010);

Von der Verwendung sprechender Bitnamen hälts du wohl nicht viel?

Aber ist ok. Ist ja nicht mein Projekt und ich muss es nicht warten.

von Marco G. (grmg2010)


Lesenswert?

Doch ich habe dies folgendermaßen genannt: LCD_FUNCTION_NONINVERT.

Die Bitfolge war nur einmal zum verdeutlichen der gesetzten Bits.

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.