Hallo Ich habe heute mein HD44780 kompatibles LCD Display angeschlossen udn versuche nun vergebens etwas auszugeben. Als ich das ganze das erstemal angeschlossen habe da waren alle Stellen wo man dann etwas ausgeben kann noch dunkel und übers Poti regelbar, das ist nichtmehr so. kann es sein das das kaputt ist? Also es mach nichts außer schön blau leuchten. Wie kann man das ganze einfach testen? Anschlüsse habe ich eigl alle überprüft möchte den 4-bit modus http://www.reichelt.de/?;ACTION=7;LA=6;OPEN=0;INDEX=0;FILENAME=A500%252FLCD162CBL%2523EAS.pdf;SID=28j-7afqwQARwAAEaGIsQ56348d90cb62dc427f0177218373e087 Ich habe das gefühl ich verstehe dei initialisierung falsch und wie gebe ich dann ein Zeichen aus, z.B. H das dieplay ist zweilzeilig. Danke
so ist mein testcode
1 | #include <avr/io.h> |
2 | #include <stdio.h> |
3 | #include <stdlib.h> |
4 | |
5 | #define LCD_PORT PORTC
|
6 | #define LCD_DATA0_PIN 3
|
7 | #define LCD_DATA1_PIN 4
|
8 | #define LCD_DATA2_PIN 5
|
9 | #define LCD_DATA3_PIN 6
|
10 | #define LCD_RS_PIN 0
|
11 | #define LCD_RW_PIN 1
|
12 | #define LCD_E_PIN 2
|
13 | |
14 | void msleep(int msec); |
15 | void enable(); |
16 | |
17 | int main(void) |
18 | {
|
19 | DDRC = 0xff; // port als ausgang |
20 | msleep(20); |
21 | |
22 | LCD_PORT = 0b00010000; // 4bit datenlänge einschalten |
23 | enable(); |
24 | msleep(10); |
25 | |
26 | |
27 | LCD_PORT = 0b00000000; |
28 | enable(); |
29 | msleep(10); //display ein cursor ein cursor blinken |
30 | LCD_PORT = 0b01111000; |
31 | enable(); |
32 | msleep(10); |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | while(1); |
41 | }
|
42 | |
43 | void enable() |
44 | {
|
45 | LCD_PORT |= (1 << LCD_E_PIN); |
46 | msleep(5); |
47 | LCD_PORT &= ~(1 << LCD_E_PIN); |
48 | }
|
49 | |
50 | void msleep(int msec) |
51 | {
|
52 | for (int s=0; s<msec; s++) { |
53 | for (long int i=0; i<2403; i++) { |
54 | asm volatile("nop"); |
55 | }
|
56 | }
|
57 | }
|
>Ich habe das gefühl ich verstehe dei initialisierung falsch und wie >gebe ich dann ein Zeichen aus, z.B. H das dieplay ist zweilzeilig. Ein Flußdiagramm der Initialisierung sollte im Datenblatt vorhanden sein. Am besten suchst du mal nach Softwarebeispielen.
Soweit ich es im Kopf habe muss 3x 0x03 und einpaar zeichen mehr ausgegebenwerden zur Initialisierung. Zu diesem Controller findet man genügend Beispiele. Nicht vergessen D/I umschalten.
Ja Ok aber wie ist das mit Function Set da blick ich nicht durch. Muss ich das 2mal machen? und da muss ich ja auch irgendwie die Display größe mit reinbringen wie mache ich das?
>größe mit reinbringen wie mache ich das? Gar nicht. Initialisieren musst du nur auf eine oder zwei Zeilen. > LCD_PORT = 0b00010000; // 4bit datenlänge einschalten Und zählen lernen;) 0x20 sieht bei mir anders aus.
Cyb3r schrieb: >aber wie ist das mit Function Set da blick ich nicht durch. >Muss ich das 2mal machen? Ich sah Beispiele, wo es auch 3 mal gemacht wurde. Und zwischen den Initialisierungsschritten, müssen Wartezeiten eingehalten werden. Daher, bitte auf jeden Fall mal das Datenblatt besorgen.
holger schrieb:
> Und zählen lernen;) 0x20 sieht bei mir anders aus.
omg Liese doch mal den Quellcode ich hab doch oben definiert wie meine
Pinbelegung ist auch wenn ichs zu dem Zeitpunkt nicht nutze
So ich habe meine Quellcode einmal überarbeitet:
Jedoch ist mein Problem nun wie dei Funktion lcd_load_byte aussehen
muss? Muss ich dsa ganze immer in s Register schreiben? ich bin
irgendwie verwirrt /verpeilt heute
Danke für die Hilfe
1 | #include <avr/io.h> |
2 | |
3 | #define LCD_PORT PORTC
|
4 | #define LCD_ENABLE_PIN 2
|
5 | #define LCD_RW_PIN 1
|
6 | #define LCD_RS_PIN 0
|
7 | #define LCD_D4_PIN 3
|
8 | #define LCD_D5_PIN 4
|
9 | #define LCD_D6_PIN 5
|
10 | #define LCD_D7_PIN 6
|
11 | |
12 | |
13 | #defune FUNCTION_SET
|
14 | #define ENTRY_MODE_SET
|
15 | #define LCD_CMD_ON
|
16 | #define LCD_CMD_OFF
|
17 | #define LCD_CMD_CLEAR
|
18 | |
19 | |
20 | void _delay_ms(int msec); |
21 | void _delay_us(int usec); |
22 | |
23 | void lcd_init(); |
24 | void lcd_send_cmd(); |
25 | void lcd_strobe_E(); |
26 | void lcd_load_byte(int out_byte); |
27 | |
28 | int main (void) |
29 | {
|
30 | // PORTC Pin 0...7 Outputs fürs Display
|
31 | DDRC = (1 << DDC0) | (1 << DDC1) | (1 << DDC2) | (1 << DDC3) | (1 << DDC4) | (1 << DDC5) | (1 << DDC6) | (1 << DDC7); |
32 | |
33 | |
34 | while(true); |
35 | return 0; |
36 | }
|
37 | |
38 | void lcd_load_byte(int out_byte) |
39 | {
|
40 | |
41 | }
|
42 | |
43 | void lcd_strobe_E() |
44 | {
|
45 | // strobe E Signal */
|
46 | LCD_PORT |= _BV(LCD_ENABLE_PIN); |
47 | _delay_us(450); |
48 | LCD_PORT &= ~_BV(LCD_ENABLE_PIN); |
49 | }
|
50 | |
51 | void lcd_send_cmd() |
52 | {
|
53 | /* Befehl liegt an, so RS muss low (0) sein */
|
54 | LCD_PORT &= ~_BV(LCD_RS_PIN); |
55 | lcd_strobe_E(); |
56 | _delay_us(40); |
57 | }
|
58 | |
59 | void lcd_init() |
60 | {
|
61 | // 20ms delay ... LCD power
|
62 | _delay_ms(16); |
63 | LCD_PORT &= ~_BV(LCD_ENABLE_PIN); // E = 0 |
64 | LCD_PORT &= ~_BV(LCD_RW_PIN); // R/W = 0 |
65 | LCD_PORT &= ~_BV(LCD_RS_PIN); // RS = 0 |
66 | |
67 | //schreibe 0x30 -> LCD und warte 5 ms damit die Instruktion verarbeitet ist
|
68 | lcd_load_byte(0x30); |
69 | lcd_send_cmd(); |
70 | _delay_ms(5); |
71 | |
72 | //schreibe 0x30 -> LCD und warte 160 us damit die Instruktion verarbeitet ist
|
73 | lcd_load_byte(0x30); |
74 | lcd_send_cmd(); |
75 | _delay_us(160); |
76 | |
77 | //schreibe 0x30 -> LCD und warte 160 us damit die Instruktion verarbeitet ist
|
78 | lcd_load_byte(0x30); |
79 | lcd_send_cmd(); |
80 | _delay_us(160); |
81 | |
82 | // Function Set und 40 us warten
|
83 | lcd_load_byte(FUNCTION_SET); |
84 | lcd_send_cmd(); |
85 | _delay_us(40); |
86 | |
87 | // Display OFF 40 us warten
|
88 | lcd_load_byte(LCD_CMD_OFF); |
89 | lcd_send_cmd(); |
90 | _delay_us(40); |
91 | |
92 | // Clear Display und 2 ms warten
|
93 | lcd_load_byte(LCD_CMD_CLEAR); |
94 | lcd_send_cmd(); |
95 | _delay_ms(2); |
96 | _delay_us(40); |
97 | |
98 | // Entry Mode Set und 40 us warten
|
99 | lcd_load_byte(ENTRY_MODE_SET); |
100 | lcd_send_cmd(); |
101 | |
102 | // Display ON und 40 us warten
|
103 | lcd_load_byte(LCD_CMD_ON); |
104 | lcd_send_cmd(); |
105 | _delay_us(40); |
106 | }
|
107 | |
108 | |
109 | void _delay_ms(int msec) |
110 | {
|
111 | for (int s=0; s<msec; s++) { |
112 | for (long int i=0; i<2403; i++) { |
113 | asm volatile("nop"); |
114 | }
|
115 | }
|
116 | }
|
117 | |
118 | void _delay_us(int usec) |
119 | {
|
120 | for (int s=0; s<usec; s++) { |
121 | for (long int i=0; i<2; i++) { |
122 | if(true) |
123 | asm volatile("nop"); |
124 | }
|
125 | }
|
126 | }
|
Setze es erst 2x hintereinander in den 8-Bit-Modus und dann in den 4-Bit-Modus. Damit bist Du auf der sicheren Seite. Sonst weßt Du ja gar nicht, ob das Display gerade das obere oder das untere Halb-Byte erwartet.
1 | void lcd_load_byte(int out_byte) |
2 | { |
3 | |
4 | } |
macht evtl. etwas wenig ... ... so wie eigentlich das ganze Programm ... Du benötigst im 4-Bit-Mode zwei Schreibvorgänge pro Byte ... (hint) Gruß Jobst
void lcd_load_byte( char byte , uint8_t mode) { // daten oder befehlsmodus auswählen // also die jeweiligen leitungen setzen/ löschen //obere 4 bit des char out_byte an die 4 datenleitungen anlegen // enable pin vom LCD an .... 80µs warten ... aus //untere 4 bit an die datenleitungen anlegen // enable pin vom LCD an .... 80µs warten ... aus } um das ganze universell zu halten kann man die pins direkt vorher undefinieren if(byte & 0x80) LCDPORTD7 |= (1<<LCD_D7); if(byte & 0x40) LCDPORTD6 |= (1<<LCD_D6); if(byte & 0x20) LCDPORTD5 |= (1<<LCD_D5); if(byte & 0x10) LCDPORTD4 |= (1<<LCD_D4); dann enable togglen dann entweder bitschieben byte<<=4 ; und nochmal das ganze (in einer schleife schnell machbar) oder man schreibt das ganze nochmal hin if(byte & 0x08) LCDPORTD7 |= (1<<LCD_D7); if(byte & 0x04) LCDPORTD6 |= (1<<LCD_D6); if(byte & 0x02) LCDPORTD5 |= (1<<LCD_D5); if(byte & 0x01) LCDPORTD4 |= (1<<LCD_D4); enable togglen kann man sowas nit mit in das tut aufnehmen ??? alle 2 tage kommt sone frage
Cyb3r schrieb: > holger schrieb: >> Und zählen lernen;) 0x20 sieht bei mir anders aus. > > omg Liese doch mal den Quellcode ich hab doch oben definiert wie meine > Pinbelegung ist auch wenn ichs zu dem Zeitpunkt nicht nutze omg Lies doch bitte das Tutorial. Da gibt es einen ganzen Abschnitt über LCD. http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung omg benutz doch bitte google. LCD Libraries gibt es für den HD44780 wie Sand am Meer.
LCD schrieb: > um das ganze universell zu halten kann man die pins direkt vorher > undefinieren > > if(byte & 0x80) LCDPORTD7 |= (1<<LCD_D7); Das ist leider nur die halbe Miete if(byte & 0x80) LCDPORTD7 |= (1<<LCD_D7); else LCDPORTD7 &= ~(1<<LCD_D7); > kann man sowas nit mit in das tut aufnehmen ??? Kann man. Warum nicht du?
Ich habe auch alle fertigen Librarys jetzt durchgetestet das tut sich bei mir auch absolut garnichts und die Pinbelegung, sowie die Leitungen überprüft alles einwandfrei. Aber trotzdem habe ich noch ein grundlegendes verständiss Problem unzwar wenn ich im 4bit modus bin werden immer zuerst die 4 höherwertigen bits gesendet? und ich sende 4bit (hbit) erzeuge die negative flanke mit enable und dann wieder 4bit(lbit) und flanke ?? die wartezeit zwiscehn den bits kann beliebig lang sein?
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.