Forum: Mikrocontroller und Digitale Elektronik LCD-Ansteurung


von Josef H. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen.

ich habe ein LCD mit dem Mikrocontroller STM32F303 verbunden.

Der Mikrocontroller kann ich programmieren. Jedoch wenn ich das Display 
initialisieren sowie etwas anzeigen möchte, geht das nicht.

Code gibts oben

Habe ich irgendetwas in der Initialisierung oder im Befehlssatz falsch 
gemacht, dass ich nicht fähig bin ein einfaches Display anzusteuern?

Mfg

Display -> 
http://www.conrad.ch/ce/de/product/181705/?insert=62&insertNoDeeplink&productname=LC-Display-Schwarz-Gelb-Gruen-B-x-H-x-T-40-x-20-x-108-mm-EADIPS082-HNLED

von Regelcop (Gast)


Lesenswert?

Josef H. schrieb:
> Code gibts oben

*.txt Dateien wird kein Compiler übersetzen ....

Unmöglich eine *.txt Datei in eine *.c-Datei "umzuwandeln"?

von Regelcop (Gast)


Lesenswert?

Josef H. schrieb:
> Jedoch wenn ich das Display
> initialisieren sowie etwas anzeigen möchte, geht das nicht.

Weil du das Display erst initialisieren musst.

Codebeispiele gibt es mehr als genug.

von Josef H. (Gast)


Lesenswert?

Regelcop schrieb:
> Josef H. schrieb:
>> Code gibts oben
>
> *.txt Dateien wird kein Compiler übersetzen ....
>
> Unmöglich eine *.txt Datei in eine *.c-Datei "umzuwandeln"?

Habe nur das Wichtigste auskopiert und in die txt Datei gespeichert.

Regelcop schrieb:
> Weil du das Display erst initialisieren musst.

Aber mit meinem Abschnitt "Initialisiere Display" sollte das Display 
doch initialisiert werden?

Wie gesagt, die Abschnitte wurden in die txt Datei eingefügt.

von Regelcop (Gast)


Lesenswert?

Regelcop schrieb:
> Weil du das Display erst initialisieren musst.

ooops hab ich doch glatt was übersehen, ist ja doch eine Init da.

... aber diesen Wust von HAL_GPIO_WritePin Aufrufen tu ich mir
nicht an ....

von Regelcop (Gast)


Lesenswert?

Josef H. schrieb:
> und in die txt Datei gespeichert.

... und in die c-Datei konntest du es nicht speichern?

von Josef H. (Gast)


Lesenswert?

Ja hàtte können schon, aber da ich zeitlich begrenzte Zeit habe nahm ich 
txt..

spielt ja eigentlich auch keine Rolle..

Zuerst werden RS, RW und Enable auf LOW gezogen.
Danach werden die Datenpins aktiviert bzw. deaktiviert(je nach 
befehlssatz)
Anschliessend wird Enable kurz aktiviert, damit bei der fallenden Flanke 
die Daten gesendet werden.

von Dietrich L. (dietrichl)


Lesenswert?

Josef H. schrieb:
> spielt ja eigentlich auch keine Rolle.

Doch. Wenn Du es .c nennst bekommt die Textanzeige eine Farbgebung 
passend zur Sprache C.

von Josef H. (Gast)


Lesenswert?

Dietrich L. schrieb:
> Josef H. schrieb:
>> spielt ja eigentlich auch keine Rolle.
>
> Doch. Wenn Du es .c nennst bekommt die Textanzeige eine Farbgebung
> passend zur Sprache C.

Oke entschuldigung.. kann mir nun jemand auf meine Frage antworten?

von Regelcop (Gast)


Lesenswert?

Josef H. schrieb:
> kann mir nun jemand auf meine Frage antworten?

Schreib dir die Initialisierung von einem bekannten Beispiel
ab. So wie du macht man das nicht und es ist sehr unüber-
sichtlich und Fehleranfällig.

von Josef H. (Gast)


Lesenswert?

Genau deswegen mag ich dieses Forum nicht..

Alle wollen etwas dazu beitragen, jedoch nicht auf die positive Art..

Niemand von euch hier will helfen.. Nur blöd kommentieren..

Sorry aber hab langsam keine nerven mehr für diese Forum.......

von Regelcop (Gast)


Lesenswert?

Josef H. schrieb:
> Sorry aber hab langsam keine nerven mehr für diese Forum.......

Dann geh woanders hin.

Überall gibt es Beispiele dafür was du machen willst:

http://www.keil.com/forum/22798/lcd-project-at-stm32/

von pegel (Gast)


Lesenswert?

Mal abgesehen von Pin Quiz (Ardu Folgeerscheinung?) nimmt die HAL_Delay 
nur uint32. Alle deine Delays sind also keine.

Bitte schreibe erst eine Funktion mit sinnvollem Namen die ebenfalls 
sinnvoll bezeichnete Bytes übergibt.

Einen gewissen Grundstil sollte man schon von der Allgemeinheit 
übernehmen wenn man Antworten erwartet.


Oder schmoll weiter.

von Josef H. (Gast)


Lesenswert?

pegel schrieb:
> Mal abgesehen von Pin Quiz (Ardu Folgeerscheinung?) nimmt die HAL_Delay
> nur uint32. Alle deine Delays sind also keine

Habe nie mit Arduino gearbeitet..
Also HAL_Delay akzeptiert nur werte mit uint_t32 integer?


> Einen gewissen Grundstil sollte man schon von der Allgemeinheit
> übernehmen wenn man Antworten erwartet.
Würde sehr gerne einen wunderschönen, kommentierten Code zeigen. Jedoch 
habe ich dafür echt keine Zeit mehr..


> Oder schmoll weiter.

Muss ich wohl, wenn hier nichts kluges mehr kommt.

von pegel (Gast)


Lesenswert?

Dann sieh dir das keil Beispiel an.
Das ist eine gute Vorlage.

Keine Zeit mehr?
Sch... Solar betriebene PC ;)

von Peter D. (peda)


Lesenswert?

Als erstes gib mal den Pinnummern vernünftige Namen.
Und dann kapsele die Hardwarezugriffe in möglichst wenige Funktionen.
Und das Init ruft dann nur noch diese Funktionen mit den nötigen 
Parametern auf.

Deinen Spaghetticode aus riesenlangen HAL-schlag-mich-tot Ketten kann 
jedenfalls keiner verstehen.

Hier mal ein Beispiel für AVR, das man auch lesen kann:

http://www.avrfreaks.net/forum/tutc-lcd-tutorial-1001?skey=lcd%201001

Und daher auch einfach an andere MCs anpassen kann.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Josef H. schrieb:
> Jedoch
> habe ich dafür echt keine Zeit mehr..

Kryptischer Monstercode kostet Dich viel viel mehr Zeit, als lesbarer 
modularer Code.

von Regelcop (Gast)


Lesenswert?

Peter D. schrieb:
> Kryptischer Monstercode kostet Dich viel viel mehr Zeit, als lesbarer
> modularer Code.

Er hat ja auch keine Zeit seine Source-Schnipsel in eine *.c
Datei statt in eine *.txt Datei zu schreiben. Der Mehraufwand
ist verständlicherweise einfach zu gross:

Josef H. schrieb:
> Ja hàtte können schon, aber da ich zeitlich begrenzte Zeit habe nahm ich
> txt..

von Stefan F. (Gast)


Lesenswert?

Dein Code ist so falsch, unvollständig und schlecht lesbar, dass es gar 
keinen Sinn macht, hier konkrete Korrekturen vorzuschlagen.

Ich wäre viel zu faul, so viel wiederholten Text hinzuschreiben.

Zuerst braucht dein Code Struktur, das heisst konkret Funktionen oder 
Makros die so oder so ähnlich heissen:

lcd_set_rs_high();
lcd_set_rs_low();
lcd_set_en_high();
lcd_set_en_low();
lcd_write_nibble(value);

Darauf bauen dann die Hauptfunktionen auf:

lcd_init();
lcd_write_command(byte);
lcd_write_data(byte);

Darauf aufbauen solltest du die ganzen Steuerbefehle des Displays 
abstrahieren, zum Beispiel:

lcd_clear();
lcd_shift_left();
lcd_shift_right();
lcd_set_cursor(row, column);
lcd_cursor_mode(off/on/blink,block/line);
usw.

Oder du verwendest einen universellen Befehl für Kommandos und 
definierst Konstanten mit sprechenden Namen für alle möglichen Werte.

Mach das erst mal soweit fertig, und dann reden wir nochmal über deinje 
Initialisierungssequenz. Da fehlt nämlich eine ganze Menge.

Ich zeige Dir hier mal ein Beispiel, wie ich das auf AVR Mikrocontroller 
mache. Dieser Code ist ein Auszug auf dem Fringsbuch 
(http://stefanfrings.de/mikrocontroller_buch/index.html), wo das Ganze 
ausführlich erklärt ist.

Header Datei:
1
// The HD44780 Display is connected to Port D.
2
#define LCD_PORT_INIT  { DDRD |= 0b11111100; }
3
#define LCD_RS_HIGH    { PORTD |=  (1<<PD2); }
4
#define LCD_RS_LOW     { PORTD &= ~(1<<PD2); }
5
#define LCD_E_HIGH     { PORTD |=  (1<<PD3); }
6
#define LCD_E_LOW      { PORTD &= ~(1<<PD3); }
7
8
#define LCD_DATA_LOW_NIBBLE(b)  { \
9
    PORTD = (PORTD & 0x0F) | (b << 4); \
10
}
11
12
#define LCD_DATA_HIGH_NIBBLE(b) { \
13
    PORTD = (PORTD & 0x0F) | (b & 0xF0); \
14
}
15
16
// Initialize the display controller.
17
void LCD_init(uint8_t options);
18
19
// Send a command.
20
void LCD_command(uint8_t cmd);
21
22
// Commands and options (add options to the command):
23
#define LCD_FUNCTION_SET        0b00100000
24
#define    LCD_1_LINE           0b0000
25
#define    LCD_2_LINES          0b1000
26
#define    LCD_5x8_FONT         0b0000
27
#define    LCD_5x10_FONT        0b0100
28
29
// Clear display and set cursor to home position.
30
#define LCD_CLEAR_DISPLAY       0b00000001
31
32
// Set cursor to the home position and reset 
33
// the shift position.
34
// The DDRAM content remains unchanged.
35
// Note that this command takes much more time 
36
// than the clear display command.
37
#define LCD_RETURN_HOME         0b00000010
38
39
// Set entry mode 
40
// = what happens after writing a character to the DDRAM.
41
#define LCD_ENTRY_MODE_SET      0b00000100
42
#define    LCD_DECREMENT        0b00
43
#define    LCD_INCREMENT        0b10
44
#define    LCD_SHIFT            0b01
45
46
// Control which features are on:
47
#define LCD_ON_OFF_CONTROL      0b00001000
48
#define    LCD_OFF              0b000
49
#define    LCD_DISPLAY          0b100
50
#define    LCD_CURSOR           0b010
51
#define    LCD_BLINKING         0b001
52
53
// Shift the cursor
54
#define LCD_SHIFT_CURSOR_LEFT   0b00010000
55
#define LCD_SHIFT_CURSOR_RIGHT  0b00010100
56
57
// Shift the display
58
#define LCD_SHIFT_DISPLAY_LEFT  0b00011000
59
#define LCD_SHIFT_DISPLAY_RIGHT 0b00011100
60
61
// Set address of character generator RAM, 
62
// the following data are written to the CGRAM.
63
// Add the 6bit address value to the command.
64
#define LCD_SET_CGRAM_ADDRESS   0b01000000
65
66
// Set the address of display data RAM, 
67
// the following data are written to the DDRAM.
68
// Add the 7bit address value to the command.
69
// Note that the second line ususally begins
70
// at address 0x40.
71
#define LCD_SET_DDRAM_ADDRESS   0b10000000
72
73
// Write one byte to the data register (CGRAM or DDRAM).
74
void LCD_data(uint8_t data);
75
76
// Write a string to the data register (CGRAM or DDRAM).
77
void LCD_write(char* text);
78
79
// Write a string from program memory to the 
80
// data register (CGRAM or DDRAM).
81
void LCD_write_P(PGM_P text);

C Datei:
1
void LCD_command(uint8_t cmd)
2
{
3
    LCD_RS_LOW;  
4
    _delay_us(0.040);
5
    LCD_E_HIGH;
6
    LCD_DATA_HIGH_NIBBLE(cmd);
7
    _delay_us(0.250);
8
    LCD_E_LOW;
9
    _delay_us(0.250);
10
    LCD_E_HIGH;
11
    LCD_DATA_LOW_NIBBLE(cmd);
12
    _delay_us(0.250);
13
    LCD_E_LOW;
14
    if (cmd==0b00000010) // return home
15
    {
16
        _delay_us(1600);
17
    }
18
    else
19
    {
20
        _delay_us(60);
21
    }
22
}
23
24
void LCD_data(uint8_t data)
25
{
26
    LCD_RS_HIGH;  
27
    _delay_us(0.040);
28
    LCD_E_HIGH;
29
    LCD_DATA_HIGH_NIBBLE(data);
30
    _delay_us(0.250);
31
    LCD_E_LOW;
32
    _delay_us(0.250);
33
    LCD_E_HIGH;
34
    LCD_DATA_LOW_NIBBLE(data);
35
    _delay_us(0.250);
36
    LCD_E_LOW;
37
    _delay_us(60);
38
}
39
40
void LCD_write(char* text)
41
{
42
    char c;
43
    while ((c=*text))
44
    {
45
        LCD_data(c);
46
        text++;
47
    }
48
}
49
50
void LCD_write_P(PGM_P text)
51
{
52
    char c;
53
    while ((c=pgm_read_byte(text)))
54
    {
55
        LCD_data(c);
56
        text++;
57
    }
58
}
59
60
void LCD_init(uint8_t options)
61
{
62
    LCD_PORT_INIT;
63
    LCD_E_LOW;
64
    _delay_ms(50);
65
    LCD_RS_LOW;
66
    _delay_us(0.040);
67
    LCD_E_HIGH;
68
    LCD_DATA_HIGH_NIBBLE(0b00110000);
69
    _delay_us(0.250);
70
    LCD_E_LOW;
71
    _delay_ms(5);
72
    LCD_E_HIGH;
73
    _delay_us(0.250);
74
    LCD_E_LOW;
75
    _delay_us(150);
76
    LCD_E_HIGH;
77
    _delay_us(0.250);
78
    LCD_E_LOW;
79
    _delay_us(0.250);
80
    LCD_E_HIGH;
81
    LCD_DATA_HIGH_NIBBLE(0b00100000);
82
    _delay_us(0.250);
83
    LCD_E_LOW;
84
    _delay_us(50);
85
    LCD_command(LCD_FUNCTION_SET+options); 
86
    LCD_command(LCD_ON_OFF_CONTROL+LCD_DISPLAY); 
87
    LCD_command(LCD_CLEAR_DISPLAY); 
88
    LCD_command(LCD_ENTRY_MODE_SET+LCD_INCREMENT); 
89
    LCD_command(LCD_RETURN_HOME); 
90
}

Hauptprogramm:
1
int main(void) 
2
{
3
    LCD_init(LCD_2_LINES+LCD_5x8_FONT);    
4
    LCD_write_P(PSTR("Hallo"));
5
    LCD_command(LCD_SET_DDRAM_ADDRESS+0x40);
6
    LCD_write("Quentin");
7
}

von Regelcop (Gast)


Lesenswert?

Stefan U. schrieb:
> Ich zeige Dir hier mal ein Beispiel

Wichtige Regeln - erst lesen, dann posten!

    Groß- und Kleinschreibung verwenden
    Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

von Stefan F. (Gast)


Lesenswert?

Ich finde es immer wieder erstaunlich, wenn anonyme Zaungäste 
hilfbereite Menschen, die sich Mühe geben anpöbeln.

Das meine Rechtschreibung suboptimal ist, weiß ich selbst. Aber darum 
geht es hier nicht, wir sind nicht im Deutschunterricht.

Für Dein Verhalten solltest du dich in die Ecke neben der Tafel stellen 
und Dich schämen!

von Brummbär (Gast)


Lesenswert?

Regelcop schrieb:
> *.txt Dateien wird kein Compiler übersetzen ....

Doch. Dem ist es egal, ob ".c" oder ".txt" im Namen steht.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Für Dateianhänge sollte *.c gewählt werden, weil dann das Forum eine 
eigenen Quelltext-Anzeigefunktion anbietet.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Josef H. schrieb:

> ich habe ein LCD mit dem Mikrocontroller STM32F303 verbunden.
(...)
> Display ->
> 
http://www.conrad.ch/ce/de/product/181705/?insert=62&insertNoDeeplink&productname=LC-Display-Schwarz-Gelb-Gruen-B-x-H-x-T-40-x-20-x-108-mm-EADIPS082-HNLED

Ob das wirklich intelligent ist, ein LCD, dessen Betriebsspannung mit 5V 
angegeben ist, an einem Controller zu betreiben, der max. 3,6V 
verkraftet?
Im besten Fall benötigst Du eine negative Kontrastspannung.

Deshalb wäre es auch sehr hilfreich, wenn Du statt "geht das nicht" eine 
etwas eindeutigere Fehlerbeschreibung liefern würdest. Wenn Du schwarze 
Rechtecke auf dem Display siehst, liegt der Fehler in der 
Initialisierung, wenn das Display nichts darstellt, ist in jedem Fall 
die Kontrastspannung zu gering.

Grüßle,
Volker.

: Bearbeitet durch User
von Lächler (Gast)


Lesenswert?

Volker B. schrieb:
> Deshalb wäre es auch sehr hilfreich, wenn Du statt "geht das nicht" eine
> etwas eindeutigere Fehlerbeschreibung liefern würdest. Wenn Du schwarze
> Rechtecke auf dem Display siehst, liegt der Fehler in der
> Initialisierung, wenn das Display nichts darstellt, ist in jedem Fall
> die Kontrastspannung zu gering.

wie kannst Du nur ... da sagt der Josef doch glatt:

Josef H. schrieb:
> Genau deswegen mag ich dieses Forum nicht..
>
> Alle wollen etwas dazu beitragen, jedoch nicht auf die positive Art..
>
> Niemand von euch hier will helfen.. Nur blöd kommentieren..
>
> Sorry aber hab langsam keine nerven mehr für diese Forum.......

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

Habe den Code nur überflogen.
Wie es aussieht, wird beim Init nur 1x das Display initialisiert.
Korrekt(er) wäre die Methode 'nach Sprut':
http://sprut.de/electronic/lcd/index.htm#init

Spätestens, wenn Dein µC eine Reset macht, Dein Display aber nicht, 
versteht das Display nur noch 'Bahnhof' :)
(im Endeffekt wird 3x auf 8bit gestellt, bevor weiter initialisiert wird 
bzw. dazwischen auf 4bit umgeschaltet wird, da man auch so schon 7 Pins 
braucht)

Die Umstrukturierung lege auch ich Dir ans Herz.
Weiter wären Kommentare, was welches Bitmuster bezwecken soll, für den 
gemeinen Leser nützlich.

Was auch schon gefragt wurde:
Bekommst Du beim Einschalten des Display (Spannung an) eine Reihe 
Rechtecke angezeigt?
Steht aber auch bei Sprut, dort auch wesentlich besser beschrieben, als 
ich Das hier aufsagen könnte.

MfG

PS: Von den Displays habe ich auch noch zwei hier :)

von Stefan F. (Gast)


Lesenswert?

> Spätestens, wenn Dein µC eine Reset macht, Dein Display aber nicht,
> versteht das Display nur noch 'Bahnhof' :)

Bei meinem Code-Beispiel tritt das problem nicht auf, obwohl dort das 
Display nut einmal initialisiert wird. Ich habe mich einfach 1:1 an das 
Datenblatt des HD44780 gehalten.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

Ich bezog mich auf den .txt-Code im Ausgangspost - hätte Das vll. 
erwähnen sollen.

In Deinem Code sendest Du ja mehrfach '8bit' ans Display (ungeprüft, 
würde mich aber wundern, wenn Das was Anderes ist)

Stefan U. schrieb:
> LCD_DATA_HIGH_NIBBLE(0b00110000);
>     _delay_us(0.250);
>     LCD_E_LOW;
>     _delay_ms(5);
>     LCD_E_HIGH;
>     _delay_us(0.250);
>     LCD_E_LOW;
>     _delay_us(150);
>     LCD_E_HIGH;
>     _delay_us(0.250);
>     LCD_E_LOW;

MfG

EDIT
Ah - glaube, Dich jetzt zu verstehen:
Sofern der µC immer komplette Befehle ans Display geschickt bekommt, das 
Display also nicht 'aus dem Tritt' kommt, ist auch Alles wunderbar.
Seltsam wird Es, wenn das Display was Anderes erwartet, als der µC 
denkt, zu senden.

Denke, wir schwätzen in die gleiche Richtung

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

>Seltsam wird Es, wenn das Display was Anderes erwartet, als der µC
>denkt, zu senden.

Warum sollte das Display etwa anderes 'erwarten'?

MfG Spess

von Stefan F. (Gast)


Lesenswert?

Du hast das falsch verstanden. Die Initialisierungssequenz, die ich 
gemäß Datenblatt umgesetzte habe, sorgt für eine Synchronisation der 
Kommunikation. Es spielt leine Rolle, ob das Display vorher im 4Bit 
Modus war oder ein halbes Byte empfangen hatte.

Ich halte es nicht für nötig, diesen weit über 10 Jahre alten Kram 
plötzlich zu hintertfragen, da er bisher noch nie versagt hat. Ich 
htatte genau diese Sequenz schon auf zahlreichen Computern und 
Mikrocontrollern angewendet.

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.