Forum: Mikrocontroller und Digitale Elektronik Initalisierung eines LCD Displays


von Sabi (Gast)


Lesenswert?

Hallo Jungs,
ich hab ein Problem mit der Initalisierung eines einfachen 2*16 
LCD-Displays. Habe auch schon das halbe Forum durchforstet und einige 
Dinge ausprobiert.

Bin schon 2 Tage dran um rauszubekommen wieso sich  das schöne Ding 
nicht richtig ansteuern läßt. :) Das Display ist aufjedenfall super in 
Ordnung, konnte es mit einem Arduino ohne Probleme ansteuern.

Folgendes Display wird verwendet:

http://www.watterott.com/de/RGB-backlight-positive-LCD-16x2-extras-black-on-RGB

Aber jetzt benutze ich einen Infineon XC888 und bekomme einfach keinen 
Text darauf. Ich werde euch meinen Code mal anhängen.

Wäre super wenn mal einer von euch da drüber schauen könnte und mir 
meinen Fehler aufzeigt.

Grüßle
1
#include <xc888.h>
2
//Function declarations
3
void port_init(void);
4
void delay(int);
5
void lcdinit(void);
6
void writecmd(int);
7
void writedata(char);
8
void ReturnHome(void);
9
void wait(unsigned int time);
10
//*******************
11
//Pin description
12
/*
13
P4.4 to P4.7 is data bus
14
P4.0 is RS
15
P4.1 is R/W 
16
P4.2 is E
17
*/
18
//********************
19
// Defines Pins
20
sbit RS = 0xC9; // Command or Data
21
sbit E  = 0xCA; // Enable Port
22
// R/W dauerhaft auf Masse
23
// ***********************************************************
24
// Main program
25
//
26
#define P4 P4_DATA
27
void main(void)
28
{
29
   port_init();                                     //Make all ports zero
30
   lcdinit();                                      //Initilize LCD
31
   writedata('H');                                 //write
32
   writedata('e');                                 //write
33
   writedata('l');                                 //write
34
   writedata('l');                                 //write
35
   writedata('o');                                 //write
36
   ReturnHome();                                   //Return to 0 position      
37
  while(1)
38
  {;  
39
  }
40
}
41
void lcdinit(void)
42
{
43
  ///////////// Reset process from datasheet /////////
44
   wait(450);
45
46
   P4 &= 0x0F;       // Make P2.4 to P2.7 zero
47
   P4 |= (0x30&0xF0);    // Write 0x3
48
  
49
   E  = 1;               // => E = 1
50
   delay(250);
51
  
52
   E  = 0;               // => E = 0
53
   delay(250);
54
55
   P4 &= 0x0F;       // Make P2.4 to P2.7 zero
56
   P4 |= (0x30&0xF0);    // Write 0x3
57
  
58
   E  = 1;               // => E = 1
59
   delay(250);
60
  
61
   E  = 0;               // => E = 0
62
   delay(250);
63
   delay(300);
64
   
65
   P4 &= 0x0F;       // Make P2.4 to P2.7 zero
66
   P4 |= (0x30&0xF0);    // Write 0x3
67
  
68
   E  = 1;               // => E = 1
69
   delay(250);
70
   E  = 0;               // => E = 0
71
   delay(250);
72
73
     delay(650);
74
75
   P4 &= 0x0F;       // Make P2.4 to P2.7 zero
76
   P4 |= (0x20&0xF0);    // Write 0x2
77
  
78
   E  = 1;               // => E = 1
79
   delay(250);
80
   E  = 0;               // => E = 0
81
   delay(250);
82
   delay(650);
83
84
  /////////////////////////////////////////////////////
85
   wait (1);
86
   writecmd(0x28);    //function set
87
   wait (1);
88
   writecmd(0x0c);    //display on,cursor off,blink off
89
   wait (1);
90
   writecmd(0x01);    //clear display
91
   wait (3);
92
   writecmd(0x06);    //entry mode, set increment
93
   wait (30);
94
}
95
96
void port_init(void)
97
{
98
P4_DIR = 0xFF;
99
PORT_PAGE=1;  
100
P4_PUDEN=0x00;
101
P4_PUDSEL=0xFF;  
102
PORT_PAGE=0;
103
}
104
105
void delay(int a)
106
{
107
   int i;
108
   for(i=0;i<a;i++);
109
   i=0;
110
}
111
112
void writedata(char t)
113
{
114
   RS = 1;             // This is data
115
   delay(250);
116
   P4 &= 0x0F;       // Make P2.4 to P2.7 zero
117
   P4 |= (t&0xF0);  // Write Upper nibble of data
118
119
   E  = 1;             // => E = 1
120
   delay(250);
121
   
122
   E  = 0;             // => E = 0
123
   delay(250);
124
  
125
   P4 &= 0x0F;       // Make P2.4 to P2.7 zero
126
   P4 |= ((t<<4)&0xF0);// Write Lower nibble of data
127
128
   E  = 1;             // => E = 1
129
   delay(250);
130
   E  = 0;             // => E = 0
131
   delay(250);
132
}
133
134
void writecmd(int z)
135
{
136
   RS = 0;             // This is command
137
138
   P4 &= 0x0F;       // Make P2.4 to P2.7 zero
139
   P4 |= (z&0xF0);     // Write Upper nibble of data
140
141
   E  = 1;             // => E = 1
142
   delay(250);
143
  
144
   E  = 0;             // => E = 0
145
   delay(250);
146
   
147
148
   P4 &= 0x0F;       // Make P2.4 to P2.7 zero
149
   P4 |= ((z<<4)&0xF0);// Write Lower nibble of data
150
151
   E  = 1;             // => E = 1
152
   delay(250);
153
   
154
   E  = 0;             // => E = 0
155
   delay(250);
156
}
157
158
void ReturnHome(void)     //Return to 0 location
159
{
160
  writecmd(0x02);
161
    delay(1500);
162
}
163
164
void wait(unsigned int time)
165
{
166
unsigned int zaehler = 0;
167
TMOD = 1;
168
TL0 = 0x50;
169
TH0 = 0xFB;
170
TCON = 0x10;
171
while(time != zaehler)
172
  {
173
    if(TF0)
174
    {
175
      TF0=0;
176
      TL0=0x20;
177
      TH0=0xD1; //Reload Wert von 65536-12000 = 53536 => 0xD120 => 1ms timer (12000*83.33 = 999960ns)
178
      zaehler++;
179
    }
180
  }
181
    
182
}

von Johannes M. (johannesm)


Lesenswert?

Das Datenblatt gibt ziemlich genaue Angaben zum Timing bei der 
Initialisierung. Mit deiner delay Funktion sieht es aber so aus, als 
wenn du ins blaue einfach mal 250 Takte wartest. Gibt es da vielleicht 
eine besser geeignete delay Funktion bei deinem Compiler die für deinen 
uC passt?

von troll (Gast)


Lesenswert?

Johannes M. schrieb:
> Gibt es da vielleicht
> eine besser geeignete delay Funktion bei deinem Compiler die für deinen
> uC passt?

Das selbe wollte ich gerade fragen. Den for-Mist da wird der Optimizer 
wegschmeißen, ergo: Keine Wartezeit.

von Sabi (Gast)


Lesenswert?

Hey Johannes, vielen Dank für die Antwort.

Ja, das mit der Timing Funktion stimmt, das habe ich einfach grob 
überschlagen.
Aber ich habe gelesen, dass es ziemlich egal ist wenn man die Pausen 
länger macht, und nach meinen groben Berechnungen kommt folgendes raus:

24mhz = 0.041us pro Takt
250*0.041 = 10,25us Wartezeit

... Ach, da hab ich wohl falsch überschlagen, okay das werde ich mal 
ausprobieren.

Für die längeren Wartezeiten habe ich ja die wait Funktion geschrieben.

Aber ansonsten müsste das so doch hinhauen oder?

Grüßle

von Sabi (Gast)


Lesenswert?

Okay, das mit dem Optimizer wäre ja blöd.

Dann werd ichs mal versuchen das alles über den Timerdelay zu 
realisieren.

Benutze Keil 4.0, habe sonst jetzt keine Idee wie ich da einen delay 
hinbekomme ohne Timer oder die for Schleife. Ihr vielleicht? :)

Grüßle

von Cyblord -. (cyblord)


Lesenswert?

Im Grunde sind alle delays natürlich auch nur loops. Du musst halt die 
RICHTIGE Anzahl Befehle ermitteln um die korrekte Wartezeit zu bekommen 
und du musst gucken dass das nicht wegoptimiert wird. Auf Timer würd ich 
da nicht gehen, viel zu aufwendig. Gibt doch auch 
Delay-Loop-Calculators. Oder rechne dirs selber aus und überprüfe im 
Output ob die Schleife auch da bleibt oder wegoptimiert wird. Kann man 
nicht trotzdem die delay Funktionen des GCC als Vorlage hernehmen wie 
man sowas macht? Vor allem sind das doch sowieso Assemblerbefehle. Also 
guck dir an wie das da gemacht wird.

gruß cyblord

von Sabi (Gast)


Lesenswert?

Ihr hattet recht, der Compiler hat die for Schleifen immer wegoptimiert.
Wenn ich die nop (); aufrufe bleibt die for Schleife drin, top das 
werd ich morgen gleich ausprobieren. Vielen Dank euch schonmal :)

1
int i;
2
for(i=0;i<a;i++)
3
{_nop_ ();}
4
i=0;

von Sabi (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute, irgendwie tut sich immer noch nichts bei dem LCD, d.h ich 
muss die Delay Zeit wohl doch noch einmal richtig berechnen. Aber 
irgendwie versteh ich nicht wie ich raussfinde wie lange die Ausführung 
des nop (); Befehls geht, geschweige denn der gesamten for Schleife 
dauert.

Könnt ihr mir einen Tip geben?

Wenn ich debugge und bis zu dieser for-Schleife komme sieht der Assembly 
so aus wie im Anhang.

Wie gesagt die CPU Clock läuft mit 24 Mhz

von Nun (Gast)


Lesenswert?

Nochwas. viele LCD wollen nach dem Reset speziell lang warten. ZB 
Millisekunden.

von Sabi (Gast)


Lesenswert?

Ja, dafür wird die Funktion wait(450) in der lcd_init aufgerufen. Somit 
wartet der Microcontroller 45ms.

Grüßle

von waf (Gast)


Lesenswert?

Zwei Dinge fallen mir auf:
1) R/W muss auf 0
2) Init mit 0x28 zwei mal senden, dazwischen 10ms warten
WAF

von waf (Gast)


Lesenswert?

Noch ein Hinweis, RS muss wie RW vor und während der Initialisierung auf 
0 (Low)

Gruß
WAF

von Sabi (Gast)


Angehängte Dateien:

Lesenswert?

Hey Leute, habs leider immer noch nicht zum laufen bekommen. Hab nochmal 
alle Leitungen durchgepinnt und musste feststellen das alles richtig 
angeschlossen ist^^.
Danke für den Hinsweis mit dem RS bit, werde ich morgen ausprobieren.


Ich habe immernoch die Vermutung, dass es doch am Timing liegt, aber 
werde aus dem Datenblatt irgendwie nicht schlau, hab es mal als Datei 
angehängt. Welche Frequenz gilt den jetzt hier für meine Befehle, mit 
welcher Frequenz werden diese abgearbeitet? Will daraus ja einen delay 
kreieren.

Danke schonmal im Vorraus

Grüßle

von Karl H. (kbuchegg)


Lesenswert?

Du kannst ja als erstes einfach mal alle delays durch deine wait 
Funktion ersetzen und da so in der Größenordnung von 30 Millisekunden 
einstellen. Jedenfalls trau ich dieser wait Funktion eher über den Weg, 
als das was du da mit dem delay angestellt hast.

Wenn deine Wartezeiten erst mal zu lange sind, dann ist das nicht weiter 
schlimm. Du könntest auch Sekunden machen damit du extern an den pins 
messen kannst, bzw. mit ein paar LED nachverfolgen kannst in welcher 
Reihenfolge sich welche Pins am LCD ändern. Langsamer darfst du. Aber 
schneller darfst du nicht.

Zum jetzigen Zeitpunkt ist erst mal wichtig, dass die Initialisierung 
überhaupt klappt. Schneller machen kannst du sie immer noch.

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.