Hallo an alle, bin gerade dabei an mein HD44780 Display Custom Characters zu senden. Nach dem Lesen des Datenblattes denke ich, dass ich das System verstanden habe, aber leider zeigt das Display nichts an. Es können maximal 8 Custom Characters gespeichert werden. Zum CGRAM wechselt man mit 0x40. Zum DDRAM wechselt man mit 0x80. Anschließend kann man mit 0x00 den ersten Custom Character aufrufen, sofern man mit 0x40 begonnen hat. Auf dieser Website war das auch super erklärt: http://www.8051projects.net/lcd-interfacing/lcd-custom-character.php Das Display selber funktioniert, ich kann auch normalen Text darauf ausgeben. Verkabelung passt auch. RS ist mit PD7 verkabelt. Ich finde den Fehler einfach nicht, hat jemand einen Lösungsansatz für mich? Irgendetwas muss ich übersehen. An den Thread habe ich meinen vollständigen Quellcode und einen Teil der LCD Lib angehängt. Das ganze stammt von einem Nerdkit. Dies bedeutet ich verwende einen ATMega168 als MCU. Danke schon mal für die Unterstützung.
Nino K. schrieb: > Irgendetwas muss ich übersehen.
1 | lcd_set_type_command(); // Change into command mode |
2 | lcd_write_byte(0x80); // Change to DDRAM |
3 | |
4 | lcd_home(); |
5 | lcd_write_byte(0x00); // Show stored custom character on lcd screen |
Hallo Nino, macht
1 | lcd_home(); |
automatisch auch
1 | lcd_set_type_data(); |
Wenn nicht, dann musst Du das selber umstellen. Die home-Funktion befindet sich leider nicht im angehängten Teil deiner LCD Lib. Und
1 | lcd_home(); |
setzt den Cursor schon auf die erste Stelle im Display. Davor die DDRAM-Adresse zu setzen ist überflüssig. Gruß John
Hi John, danke für die Rückmeldung. lcd_home() macht folgendes:
1 | void lcd_home() { |
2 | lcd_set_type_command(); |
3 | lcd_write_byte(0x02); |
4 | delay_ms(50); |
5 | }
|
Dann sollte es mit dem folgenden Code funktionieren? Sofern ich dich richtig verstanden habe. Ich habe das "lcd_home()" durch "lcd_set_type_data()" ersetzt. Oder muss ich noch etwas dabei beachten?
1 | #define F_CPU 14745600
|
2 | |
3 | #include <stdio.h> |
4 | |
5 | #include <avr/io.h> |
6 | #include <avr/pgmspace.h> |
7 | #include <inttypes.h> |
8 | |
9 | #include <inttypes.h> |
10 | #include <string.h> |
11 | |
12 | #include <util/delay.h> |
13 | #include "../libnerdkits/delay.h" |
14 | #include "../libnerdkits/lcd.h" |
15 | |
16 | int main(void) { |
17 | |
18 | // fire up the LCD
|
19 | lcd_init(); |
20 | lcd_home(); |
21 | |
22 | lcd_set_type_command(); // Change into command mode |
23 | lcd_write_byte(0x40); // Change to CGRAM to store custom character - at 0x00 |
24 | lcd_set_type_data(); // Change into data mode |
25 | |
26 | lcd_write_byte(0x00); // Send Hexa Bytes of Custom Character Begin |
27 | lcd_write_byte(0x0E); |
28 | lcd_write_byte(0x1F); |
29 | lcd_write_byte(0x1F); |
30 | lcd_write_byte(0x1F); |
31 | lcd_write_byte(0x0E); |
32 | lcd_write_byte(0x00); |
33 | lcd_write_byte(0x00); // Send Hexa Bytes of Custom Character End |
34 | |
35 | lcd_set_type_command(); // Change into command mode |
36 | lcd_write_byte(0x80); // Change to DDRAM |
37 | |
38 | lcd_set_type_data(); |
39 | lcd_write_byte(0x00); // Show stored custom character on lcd screen |
40 | |
41 | // busy loop
|
42 | while(1) { |
43 | |
44 | // do nothing
|
45 | }
|
46 | |
47 | return 0; |
48 | }
|
John schrieb: > Ja, sollte so funktionieren. Und das tut es auch. Vielen vielen Dank für deine Hilfe. Habe es gerade getestet. Bin echt nicht darauf gekommen, dass ich das Laden des Custom Characters im Data Modus machen muss. Juhu.
Diese ganze Modus Umschalterei ist nicht zweckdienlich. Vor allen Dingenspiegelt es nicht das wieder, was am LCD passiert. Das LCD kennt Kommandos und anzuzeigende (oder eben in diesem Fall ins DDRAM auszugebende) Daten. Das ist alles. Das ist die ganze Unterschiedung: Das nächste ans LCD übertragene Byte, ist das vom LCD als Kommando aufzufassen oder ist das als Datenbyte aufzufassen. D.h. vernünftigerweise macht man sich 2 Ausgabefunktionen. Die eine, die ein Kommandobyte ausgibt und die andere, die ein Datenbyte ausgibt. Die beiden Funktionen unterscheiden sich nur in der Behandlung der RS Leitung. Die Home Funktion, die ja naturgemäss ein Kommando ausgibt, sieht dann so aus
1 | void lcd_home() { |
2 | lcd_write_command( 0x02 ); |
3 | delay_ms(50); |
4 | }
|
und auch andere Funktionen, die dem LCD einen Befehl übermitteln, benutzten die lcd_write_command Funktion. Die lcd_write_data Funktion wird immer dann benutzt, wenn eben ein Datenbyte (also KEIN Kommando) auszugeben ist. Dann kommt man auch nicht mit diversen Modusumschaltungen durcheinander, die man eingeführt hat, obwohl es keine Notwendigkeit dafür gibt. Es ist immer klar, ob ein Kommando ans LCD zu übermitteln ist, oder ob es sich um Daten handelt.
Um den Code etwas übersichtlicher zu gestalten habe ich nun versucht anhand der Arduino Lib (LiquidCrystal) eine Funktion in meine Nerdkit LCD Lib einzubauen. Aber ich bekomme am Display immer nur ein komplett ausgefülltes Rechteck zu sehen. Was mache ich hier falsch? Anbei die neue Funktion in meiner Nerdkit LCD Lib:
1 | void lcd_createChar(uint8_t location, uint8_t charmap[]) { |
2 | int i = 0; |
3 | location &= 0x7; // 8 possible characters regarding to 1Byte availability |
4 | lcd_set_type_command(); // Change into command mode |
5 | lcd_write_byte(0x40 | (location << 3)); |
6 | lcd_set_type_data(); // Change into data mode |
7 | |
8 | for (i=0; i<8; i++) { |
9 | lcd_write_byte(charmap[i]); |
10 | }
|
11 | |
12 | lcd_set_type_command(); // Change into command mode |
13 | lcd_write_byte(0x80); // Change to DDRAM |
14 | lcd_set_type_data(); // Change into data mode |
15 | }
|
Und hier der Quellcode vom Hauptprogramm:
1 | #define F_CPU 14745600
|
2 | |
3 | #include <stdio.h> |
4 | |
5 | #include <avr/io.h> |
6 | #include <avr/pgmspace.h> |
7 | #include <inttypes.h> |
8 | |
9 | #include <inttypes.h> |
10 | #include <string.h> |
11 | |
12 | #include <util/delay.h> |
13 | #include "../libnerdkits/delay.h" |
14 | #include "../libnerdkits/lcd.h" |
15 | |
16 | uint8_t p1[8] = {0,14,31,31,31,14,0,0}; |
17 | |
18 | int main(void) { |
19 | |
20 | // fire up the LCD
|
21 | lcd_init(); |
22 | lcd_home(); |
23 | |
24 | lcd_createChar(0, p1); // Create Char on position 0x00 |
25 | |
26 | lcd_write_byte(0x00); // Show stored custom character on lcd screen |
27 | |
28 | // busy loop
|
29 | while(1) { |
30 | |
31 | // do nothing
|
32 | }
|
33 | |
34 | return 0; |
35 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.