Forum: Mikrocontroller und Digitale Elektronik Frage zur LCD-Initialisierung


von Namenloser324 (Gast)


Lesenswert?

Hallo liebes Forum,

habe eine kurze Frage zur LCD-Ansteuerung:
Habe den EA W082-XLG 
(http://www.lcd-module.com/fileadmin/eng/pdf/doma/olede.pdf) vorliegen. 
Das Datasheet ist recht dürftig und erwähnt keine spezielle 
Initialisierungssequenz. Allerdings wird diese hier 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung#Die_LCD_Routinen 
erwähnt.

Gehe ich recht in der Annahme, dass trotz des Beispiels im Datasheet, 
ich genau wie im Tutorial erstmal eine Initialisierungssequenz "senden" 
muss?

von g457 (Gast)


Lesenswert?

> Das Datasheet ist recht dürftig und erwähnt keine spezielle
> Initialisierungssequenz.

Einfach Seite 5 nochmal lesen :-)

HTH

von Namenloser324 (Gast)


Lesenswert?

g457 schrieb:
>> Das Datasheet ist recht dürftig und erwähnt keine spezielle
>> Initialisierungssequenz.
>
> Einfach Seite 5 nochmal lesen :-)
>
> HTH

Hey,

habe ich, nur sagt das Tutorial zum einen, dass man erstmal 15 ms warten 
soll und dann
1
    // Soft-Reset muss 3mal hintereinander gesendet werden zur Initialisierung
2
    lcd_out( LCD_SOFT_RESET );
3
    _delay_ms( LCD_SOFT_RESET_MS1 );
4
 
5
    lcd_enable();
6
    _delay_ms( LCD_SOFT_RESET_MS2 );
7
 
8
    lcd_enable();
9
    _delay_ms( LCD_SOFT_RESET_MS3 );

ausführen soll. Davon steht im Datasheet nichts. Mein Test heute schien 
zu gehen (gemäß Anleitung), aber wollte sichergehen, dass ich nichts 
übersehe.

von spess53 (Gast)


Lesenswert?

Hi

Die Teile funktionieren mit einer stinknormalen HD44780-Initialisierung.

MfG Spess

von Nop (Gast)


Lesenswert?

Namenloser324 schrieb:
> Davon steht im Datasheet nichts.

Nein, denn das Display braucht derlei auch an sich nicht für den Init 
nach dem Einschalten. Aber stell Dir mal folgendes Szenario vor:

- Du schaltest das System ein
- Du wartest 20ms
- Du konfigurierst das Display (speziell 4/8 bit und so)
- System läuft
- System ist leider instabil, Watchdog macht Reset
- Du fährst wieder hoch
- System ist neu gebootet, aber Display steht immer noch in irgendeinem 
abstrusen Konfig-Zustand, der nicht mit Power-on identisch ist

=> und jetzt zahlt es sich aus, das Ding mehrfach zu resetten, damit die 
Init-Sequenz geht, egal was man vorher mal konfiguriert hatte.

von Namenloser324 (Gast)


Lesenswert?

Nop schrieb:
> Namenloser324 schrieb:
>> Davon steht im Datasheet nichts.
>
> Nein, denn das Display braucht derlei auch an sich nicht für den Init
> nach dem Einschalten. Aber stell Dir mal folgendes Szenario vor:
>
> - Du schaltest das System ein
> - Du wartest 20ms
> - Du konfigurierst das Display (speziell 4/8 bit und so)
> - System läuft
> - System ist leider instabil, Watchdog macht Reset
> - Du fährst wieder hoch
> - System ist neu gebootet, aber Display steht immer noch in irgendeinem
> abstrusen Konfig-Zustand, der nicht mit Power-on identisch ist
>
> => und jetzt zahlt es sich aus, das Ding mehrfach zu resetten, damit die
> Init-Sequenz geht, egal was man vorher mal konfiguriert hatte.

Okay, danke!

[quote]
Du wartest 20ms
[/quote]
Das ist die Dauer der internen Initialisierung, ja?

von Nop (Gast)


Lesenswert?

Namenloser324 schrieb:
> Das ist die Dauer der internen Initialisierung, ja?

Ich empfehle dazu mal diese Seite hier, die hat mir bei Text-LCDs sehr 
geholfen:
http://www.sprut.de/electronic/lcd/

Unter dem Punkt "Init" findet sich, daß die interne Reset-Prozedur etwa 
15ms dauert. Praktisch hab ich das einfach zu 20ms aufgerundet. Bei den 
sonstigen Timings nehme ich übrigens das Doppelte von dem an, was das 
jeweilige Datenblatt schreibt, dann ist man auf der sicheren Seite.

Man kann natürlich (außer bei Powerup) auch das busyflag abfragen, aber 
einfacher ist es, das wegzulassen und länger zu warten. Insbesondere, 
wenn man ein 5V-Display an einen 3.3V-Controller anschließt, spart man 
auch noch einen Levelshifter. Wobei das mit Deinem Display kein Thema 
ist, weil das sowieso mit 3.3V klarkommt, wenn man es auch an 3.3V 
betreibt.

Realistisch gesehen ist das alles eh nicht zeitkritisch, denn schon bei 
mehr als 2 Display-Updates pro Sekunde wird es für den ablesenden 
Menschen ohnehin unangenehm; ich würde sogar höchstens einmal pro 
Sekunde updaten.

von Namenloser324 (Gast)


Lesenswert?

Ich pushe nochmal, da es leider immernoch nicht funzt:

Welches Spannungsniveau interpretiert der LCD-Controller als High? 
Betreibe das Display mit 3.3..3.4 V und ich bin mir bei der Anleitung 
etwas unsicher. Eigentlich sollte sich High und Low auf die 
Versorgungsspannung beziehen, d.h. sollte passen.

von Georg G. (df2au)


Lesenswert?

Namenloser324 schrieb:
> Welches Spannungsniveau interpretiert der LCD-Controller als High?

Genau zur Beantwortung solcher Fragen wurde das Datenblatt erfunden. 
Dabei ist zu berücksichtigen, dass es nicht den LCD Controller gibt 
sondern diverse Hersteller mit u.U. abweichenden Spezifikationen.

Was ist bei "minimal 0.9*VDD" unklar?

: Bearbeitet durch User
von asdf (Gast)


Lesenswert?

Georg G. schrieb:
> Dabei ist zu berücksichtigen, dass es nicht den LCD Controller gibt

Namenloser324 schrieb:
> Habe den EA W082-XLG

von Namenloser324 (Gast)


Lesenswert?

Georg G. schrieb:
> Was ist bei "minimal 0.9*VDD" unklar?

Das es immernoch nicht geht :( Hatte gehofft, dass irgendwie zwar 3.3V 
Versorgungsspannung zum Betrieb, aber doch ein anderes Level für die 
Logik erwartet wird :/

Hier mal mein Code:
1
#include <stdbool.h>
2
#include <stdint.h>
3
#include "nrf_delay.h"
4
#include "boards.h"
5
#define PIN_RS 4
6
#define PIN_RW 22
7
#define PIN_EN 23
8
9
#define PIN_DB0 24
10
#define PIN_DB1 25
11
#define PIN_DB2 26
12
#define PIN_DB3 27
13
#define PIN_DB4 28
14
#define PIN_DB5 29
15
#define PIN_DB6 30
16
#define PIN_DB7 31
17
18
#define PIN_DB_OFFSET (PIN_EN+1)
19
20
void led_enable(void)
21
{
22
  nrf_gpio_pin_set(PIN_EN);
23
  nrf_delay_us(1);
24
  nrf_gpio_pin_clear(PIN_EN);
25
}
26
27
void writeData(char instruction)
28
{
29
  unsigned int pin = PIN_DB_OFFSET;
30
  for(; pin <= PIN_DB7;++pin)
31
  {
32
    bool p = instruction & (1 << (pin - PIN_DB_OFFSET));
33
    if(p == true){
34
      nrf_gpio_pin_set(p);
35
    }
36
    else{
37
      nrf_gpio_pin_clear(p);
38
    }
39
  }
40
41
}  
42
43
void WriteIns(char instruction)
44
{
45
  nrf_gpio_pin_clear(PIN_RS);
46
  nrf_gpio_pin_clear(PIN_RW);
47
  writeData(instruction);
48
  led_enable();
49
}
50
51
void writeChar(char c)
52
{
53
  nrf_gpio_pin_set(PIN_RS);
54
  nrf_gpio_pin_set(PIN_RW);
55
  writeData(c);
56
  led_enable();
57
}
58
59
void setRangeDirOut(unsigned int start, unsigned int end)
60
{
61
  int i;
62
  for(i = start; i <= end; ++i){
63
    nrf_gpio_cfg_output(i);
64
  }
65
}
66
67
/**
68
 * @brief Function for application main entry.
69
 */
70
int main(void)
71
{
72
 setRangeDirOut(4,31);
73
 nrf_delay_ms(20);
74
  WriteIns(0x30);
75
  nrf_delay_ms(5);
76
    WriteIns(0x30);
77
  nrf_delay_us(200);
78
  WriteIns(0x30);
79
  
80
  /* Configure board. */
81
  bsp_board_leds_init();
82
  WriteIns(0x08); //display off
83
84
  WriteIns(0x39); //function set european chararacter set
85
  WriteIns(0x06); //entry mode set increment cursor by 1 not shifting display
86
  WriteIns(0x17); //Character mode and internel power on
87
  WriteIns(0x01); //clear display
88
  WriteIns(0x02); //return home
89
  WriteIns(0x0C); //display on
90
  //WriteIns(0x0F);
91
  /* Toggle LEDs. */
92
  while (true)
93
  {
94
      for (int i = 0; i < LEDS_NUMBER; i++)
95
      {
96
          bsp_board_led_invert(i);
97
          nrf_delay_ms(500);
98
          //writeChar('H');
99
      }
100
  }
101
}

Es passiert: nichts. Pins sind alle richtig angeschlossen, wobei ich 
auch hier nochmal auf Nummer sicher gehen möchte: Die eine Spalte der 
Pins auf dem LED-Display umfasst alle ungeraden Zahlen und die andere 
alle geraden, ja? Nicht das es nachher an so etwas dummen liegt.

Die Pegel sind auch alle richtig, habe ich vorhin mit nem Multimeter 
gemessen, saubere 3.44V bei 3.45 VDD. Enable springt auch korrekt.

An sich scheint das Display auch zu laufen, manchmal, wenn ich noch 
nichts programmiert habe, geht es wenn dir Versorgungsspannung an ist 
tatsächlich an und der Cursor blinkt.

von Namenloser324 (Gast)


Lesenswert?

Achso, es handelt sich um das Nordic 52 DK-Board, dass ich benutze. 
(Samt nrf52832 natürlich)

von Karl B. (gustav)


Angehängte Dateien:

Lesenswert?

Namenloser324 schrieb:
> habe eine kurze Frage zur LCD-Ansteuerung:

Namenloser324 schrieb:
> Das Datasheet ist recht dürftig und erwähnt keine spezielle
> Initialisierungssequenz.


OK, die wichtigsten Befehlsfolgen sind auf Seite 5 der Dokumentation in 
C geschrieben.

Dabei gibt es offensichtlich immer wieder dieselben "erratischen" 
Blöcke,
gegen die man insbesondere als "LCD-Erstkonfrontierter" anrennt:

A:) tatsächliche Portzuweisung der verwendeten MCU

B:) Definition der Steuersignale Enable, RS, RWquer

C:) Zeitschleifen

D:) und für Fortgeschrittene: (I2C Bus), 4-Bit-Modus


Anbei ein (bei mir jedenfalls lauffähiges) Assemblerprogramm für die 
LCD-Initialisierung und Ausgabe von Charakters.

In der Hoffnung, dass dies weiterhilft:

(Das Proggi kann leicht auf DOG-Ms umgeschrieben werden, es ist 
ursprünglich für ein Displaytech 16x2 geschrieben mit 
HD44780-Controller.)

ciao
gustav

P.S:
Namenloser324 schrieb:
> Gehe ich recht in der Annahme, dass trotz des Beispiels im Datasheet,
> ich genau wie im Tutorial erstmal eine Initialisierungssequenz "senden"
> muss?

OK,
insbesondere, wenn MCU und LCD an derselben Versorgungsspannung 
angeschlossen sind, kann es sein, dass der "Power On Self Reset" des LCD 
noch nicht fertig ist, wenn die MCU bereits Steuersignale sendet.
Deswegen doppelt gemoppelt....

: Bearbeitet durch User
von Bernd N (Gast)


Lesenswert?

>> WriteIns(0x39); //function set european chararacter set

in dem Datenblatt steht da 0x38. Es kann auch durchaus sein das dein 
Display 5 V benötigt.

von Bernd N (Gast)


Lesenswert?

>> Supplied with 3.3V reduces brightness compered to 5V

Scheint 3,3 V zu sein, steht jedenfalls so im DB.

von Namenloser324 (Gast)


Lesenswert?

Hallo liebe Leute,

vielen Dank für eure Hilfe :)

ES GEHT HAHAHA

Zwei Ursachen:
- Dummer Programmierfehler in der "writeChar"-Funktion. Natürlich muss 
nur im Falle p == 0 der pin gecleared werden und in jedem anderen Fall 
der Pin gesetzt werden. Was so alles passiert wenn das C ein wenig 
einrostet^^

- Hatte die Textschreibmaske (also das Bitmuster) falsch aus nem anderen 
Beispiel kopiert und daher immer den Speicher GELESEN und nicht 
geschrieben hahahaha

Jetzt geht alles. Sogar mit 2.8V, hätte ich nicht gedacht, dann könnte 
ich sogar mit meiner Knopfzelle alles betreiben.

von Karl B. (gustav)


Angehängte Dateien:

Lesenswert?

Namenloser324 schrieb:
> - Hatte die Textschreibmaske (also das Bitmuster) falsch aus nem anderen
> Beispiel kopiert und daher immer den Speicher GELESEN und nicht
> geschrieben hahahaha



Hi,
was auch oft Probs. macht, sind Proggis, die aus Schnipseln oder - 
besser gesagt - sog. "include"-Dateien zusammengesetzt sind, bei denen 
bestimmte Targets, Asssemblerdirektiven, Deklarationsteile  etc. 
stillschweigend vorausgesetzt werden.
(Das gilt auch für das vorher einkopierte Beispiel. Es fehlten z.B.
die Zuweisung von "daten" und "licht" etc. Was hiermit nachgeholt werden 
soll.)
Progs. lassen sich oft nicht so easy 'mal auf eine andere ATMEL-MCU 
portieren.
Auch ist bei bestimmten Targets vieles "memory mapped", so dass mit den 
SRAM-typischen Befehlen mit sts und nicht in und out gearbeitet werden 
muss.

Hier noch ein kleines Beispiel, das lange Kopfzerbrechen machte, bis 
herausgefunden wurde, dass der 32U2 den SRAM-Bereich erst ab Adresse 100 
anspricht, und nicht - wie in der Programmvorlage angegeben - bei 
Adresse 60.

Habe jedenfalls keine Erfahrung, ob die C-Compiler von vorne herein 
diese Probs. immer ausmerzen.

ciao
gustav

P.S.:
Habe beide Varianten einmal ins Studio 4 Version 18 geladen. Assembliert 
mit no errors, obwohl der ATTINY2313 garkeinen HIGH-STACK hat.

: Bearbeitet durch User
von TF (Gast)


Lesenswert?

Karl B. schrieb:
> Hier noch ein kleines Beispiel, das lange Kopfzerbrechen machte, bis
> herausgefunden wurde, dass der 32U2 den SRAM-Bereich erst ab Adresse 100
> anspricht, und nicht - wie in der Programmvorlage angegeben - bei
> Adresse 60.

Steht aber in den Appnotes der einzelnen Controller:

m32u2def.inc:

; ***** DATA MEMORY DECLARATIONS 
*****************************************
.equ  FLASHEND  = 0x3fff  ; Note: Word address
.equ  IOEND  = 0x00ff
.equ  SRAM_START  = 0x0100
.equ  SRAM_SIZE  = 1024

von Karl B. (gustav)


Lesenswert?

Karl B. schrieb:
> nicht - wie in der Programmvorlage angegeben - bei
> Adresse 60.

Hi,
bestätigt, dass man doch lieber nochmal nachchecken sollte.
Da gibt es bestimmt noch ein paar üble Bugs mehr, deren stundenlange 
Fehlersuche überflüssig gemacht würde, wenn man sich angewöhnt hätte, 
nochmals aktuelle Appnotes zu durchforsten.

TF schrieb:
> Steht aber in den Appnotes der einzelnen Controller:

Aber auch hier nicht "blind" vertrauen, denn:
Dann taucht da in den Appnotes gelegentlich noch die Angabe "for 
compatibility use" auf.
Was heißt das jetzt konkret, geht's oder nicht?

Beispiel für den ATTINY4313:
Die geremten .equ-Anweisungen "for compatibility" 'mal der Appnote 
entnommen:

rs232init:
ldi temp, bdrt    ;Baudrate setzen
out UBRR, temp    ; .equ UBRR=UBRRL;for compatibility
ldi temp, 0x18    ;(1<<RXEN)+(1<<TXEN)
out UCR, temp    ; .equ UCR=UCSRB;for compatibility
ret
senden:      ;RS232-Ausgaberoutine
sbis UCSRA, UDRE  ; .equ USR=UCSRA;for compatibility
rjmp senden
out UDR, temp
ret

OK,
einfach einmal ausprobieren.
Beim ATTINY2313 meldet der Assembler:
: error: Undefined symbol: UCSRA
beim 4313-er gehts fehlerfrei durch
compatibility gilt also für "Nachfolge"-Typen
ciao
gustav

: Bearbeitet durch User
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.