Forum: Mikrocontroller und Digitale Elektronik LCD diplay am AVR läuft nur jedes zweite Mal an


von Christoph R. (chroters)


Lesenswert?

Hallo,

ich habe folgenden Quelltext in eine ATmega 2560 (8Mhz int osc) am 
STK600 geflashed.
Das Display zeigt den Ausgabetext aber nur nach jedem zweiten Reset oder 
nach nochmaligem Programmieren (was ja auch einen neuen Reset auslöst) 
an.
Auch wenn ich nach dem Programmieren das Board resete, muss ich es immer 
zweimal machen.

Das LCD ist ein LTN211R.

Hat jemand eine Idee, was da falsch ist?


Nette Grüsse

Christoph
1
#include    <avr/io.h>
2
#include    <stdio.h>
3
#include    <string.h>
4
#include    <util/delay.h>
5
6
//  ************************************************************//
7
//  **********  LCD display Vereinbarungen *********************//
8
//  ************************************************************//
9
10
/* sample: lcd_cmd(LCD_DISP_OFF); */
11
#define LCD_DISP_OFF             0x08   /* display off                            */
12
#define LCD_DISP_ON              0x0C   /* display on, cursor off                 */
13
#define LCD_DISP_ON_BLINK        0x0D   /* display on, cursor off, blink char     */
14
#define LCD_DISP_ON_CURSOR       0x0E   /* display on, cursor on                  */
15
#define LCD_DISP_ON_CURSOR_BLINK 0x0F   /* display on, cursor on, blink char      */
16
/* move cursor/shift display */
17
#define LCD_MOVE_CURSOR_LEFT     0x10   /* move cursor left  (decrement)          */
18
#define LCD_MOVE_CURSOR_RIGHT    0x14   /* move cursor right (increment)          */
19
#define LCD_MOVE_DISP_LEFT       0x18   /* shift display left                     */
20
#define LCD_MOVE_DISP_RIGHT      0x1C   /* shift display right                    */
21
22
23
24
// Zuordnung der LCD-Eingängen zu den Atmega-Ausgängen 
25
// Wenn die Zuordnung geändert werden soll, so muss der Quelltext in dieser Datei geändert werden.
26
// Insbesonder die Routine LCD_init muss angepasst werden!!!!
27
// siehe Quelltextkommentare
28
// RS = PG2
29
// E  = PG3
30
// D4 = PG4
31
// D5 = PG5
32
// D6 = PG6
33
// D7 = PG7
34
35
36
#define clr_d7  PORTA &= ~(1<<7)
37
#define set_d7  PORTA |= (1<<7)
38
#define clr_d6  PORTA &= ~(1<<6)
39
#define set_d6  PORTA |= (1<<6)
40
#define clr_d5  PORTA &= ~(1<<5)
41
#define set_d5  PORTA |= (1<<5)
42
#define clr_d4  PORTA &= ~(1<<4)
43
#define set_d4  PORTA |= (1<<4)
44
45
46
#define clr_e  PORTA &= ~(1<<3)
47
#define set_e  PORTA |= (1<<3)
48
49
#define clr_rs  PORTA &= ~(1<<2)
50
#define set_rs  PORTA |= (1<<2)
51
52
//  ************************************************************//
53
//  **********  LCD display Vereinbarungen      ****************//
54
//  ************Ende *******************************************//
55
//  ************************************************************//
56
57
58
59
60
// Variablen deklaration
61
62
63
64
// main  Hauptprogramm
65
int main(void)
66
{
67
   double messung;
68
   float ek0,ek1,ek2;
69
   float b0,b1,b2;
70
   double y0,y1;
71
   float Kpr,Kir,Kdr;
72
   float T;
73
   double mess_c;
74
   double ausgabe;
75
   char  lcd_txt[17];
76
   char  txt[8];
77
   int i;
78
   int j;
79
   
80
  
81
   //warten bist LCD-Controller gebootet
82
     _delay_ms(20);   
83
  
84
  
85
   
86
  lcd_init();
87
     _delay_ms(20);   
88
89
90
91
   lcd_cmd(LCD_DISP_ON);
92
      _delay_ms(20);   
93
  lcd_clear();
94
     _delay_ms(20);   
95
  
96
  lcd_txt[0] = 0;
97
  
98
99
  strcat(lcd_txt, "Test v0.1");
100
  lcd_write_s(lcd_txt);
101
102
 
103
104
   while (1)
105
   {
106
   
107
  
108
109
110
  //Endlosschleife für Hauptprogramm
111
   }
112
   
113
 
114
} 
115
116
//////////////////////////////////////////////////////////////////////////////
117
//    lcd_send(..) - sendet ein Byte an LCD im 4-Bit-Modus ohne Busy
118
//    nicht direkt aufrufen sondern lcd_cmd oder lcd_write nutzen
119
//---------------------------------------------------------------------------
120
void lcd_send(char data)
121
{
122
  
123
  // High-Teil senden
124
    char tmp=data;
125
    
126
  tmp = data & 0x80;    // bit7 von data isolieren durch And mit "1000 0000"
127
    clr_d7;            //Löschen von D7
128
  if ( tmp == 0x80 ) {
129
  set_d7;
130
  }
131
  
132
  tmp = data & 0x40;    // bit6 von data isolieren durch And mit "0100 0000"
133
    clr_d6;            //Löschen von D6 
134
  if ( tmp == 0x40 ) {
135
    set_d6;            //setzen von D6  
136
  }
137
138
  tmp = data & 0x20;    // bit5 von data isolieren durch And mit "0010 0000"
139
    clr_d5;              //Löschen von D5 
140
  if ( tmp == 0x20 ) {
141
    set_d5;            //setzen von D5  
142
  }
143
144
  tmp = data & 0x10;    // bit4 von data isolieren durch And mit "0001 0000"
145
    clr_d4;            //Löschen von D4 
146
  if ( tmp == 0x10 ) {
147
    set_d4;          //setzen von D4  
148
  }
149
150
  // Schreibsignal mit fallender Flanke an E  
151
  set_e;            //setzen von E  
152
  clr_e;            //Löschen von E 
153
    
154
  _delay_ms(20);
155
  
156
  tmp = data & 0x08;    // bit3 von data isolieren durch And mit "0000 1000"
157
    clr_d7;            //Löschen von D7
158
  if ( tmp == 0x08 ) {
159
    set_d7;          //Setzen von D7
160
  }
161
   
162
  tmp = data & 0x04;    // bit2 von data isolieren durch And mit "0000 1000"
163
      clr_d6;          //Löschen von D6
164
  if ( tmp == 0x04 ) {
165
  set_d6;            //Setzen von D6
166
  }
167
168
  tmp = data & 0x02;    // bit1 von data isolieren durch And mit "0000 0010"
169
      clr_d5;          //Löschen von D5
170
  if ( tmp == 0x02 ) {
171
    set_d5;          //setzen von D5 
172
  }
173
174
  tmp = data & 0x01;    // bit0 von data isolieren durch And mit "0000 0001"
175
      clr_d4;          //Löschen von D4 
176
  if ( tmp == 0x01 ) {
177
    set_d4;          //setzen von D4 
178
  }
179
180
    
181
  // Schreibsignal mit fallender Flanke an E  
182
  set_e;            //E = 1 
183
  clr_e;            //E = 0 
184
185
    // verarbeiten lassen
186
    _delay_ms(20);
187
}
188
//---------------------------------------------------------------------------
189
//    lcd_cmd(..) - sendet ein Kommando an LCD
190
//---------------------------------------------------------------------------
191
void lcd_cmd(char cmd)
192
{
193
194
    clr_rs;             // RS löschen = Kommando
195
  _delay_ms(20);
196
    lcd_send(cmd);        // senden
197
}
198
//---------------------------------------------------------------------------
199
//    lcd_write(..) - sendet ein Zeichen (Daten) an LCD
200
//---------------------------------------------------------------------------
201
void lcd_write(char text)
202
{
203
    set_rs;        // RS setzen = Daten
204
  _delay_ms(20);
205
    lcd_send(text);        // senden
206
}
207
//---------------------------------------------------------------------------
208
//    lcd_write_s(..) - sendet eine Zeichenkette an LCD
209
//    Die Zeichenkette muss mit 0x00 abgeschlossen sein
210
//---------------------------------------------------------------------------
211
void lcd_write_s(char * pText)
212
213
{
214
215
    while(pText[0]!=0)
216
    {
217
    lcd_write(pText[0]); // diese Zeile stehenlassen, auch für norrmale LCD-Displays
218
    pText++;       // diese Zeile muss stehenbleiben, auch für norrmale LCD-Displays
219
    }
220
}
221
222
223
//---------------------------------------------------------------------------
224
//    lcd_home(..) - Cursor auf Position 1,1
225
//---------------------------------------------------------------------------
226
void lcd_home(void)
227
{
228
    lcd_cmd(0x02);
229
    _delay_ms(20);            // warten
230
}
231
//---------------------------------------------------------------------------
232
//    lcd_clear(..) - löscht die Anzeige im LCD
233
//---------------------------------------------------------------------------
234
void lcd_clear(void)
235
{
236
    lcd_cmd(0x01);
237
    _delay_ms(20);            // warten
238
}
239
//---------------------------------------------------------------------------
240
//    lcd_on(..) - schaltet das LCD an
241
//---------------------------------------------------------------------------
242
void lcd_on(void)
243
{
244
    lcd_cmd(0x0C);
245
   _delay_ms(20);            // warten
246
}
247
//---------------------------------------------------------------------------
248
//    lcd_off(..) - schaltet das LCD aus
249
//---------------------------------------------------------------------------
250
void lcd_off(void)
251
{
252
    lcd_cmd(0x08);
253
   _delay_ms(20);            // warten
254
}
255
//---------------------------------------------------------------------------
256
//    lcd_goto(..) - setzt die Cursorposition
257
//---------------------------------------------------------------------------
258
void lcd_goto(int row, int col)
259
{
260
    row--;                // Null-basierend
261
    row&=0x01;            // sicherheitshalber
262
    row*=0x40;            // Zeile nach Bit 6 bringen
263
    col--;                // Null-basierend
264
    col&=0x0f;            // sicherheitshalber
265
    char tmp=row|col;
266
    tmp|=0x80;            // Cursor setzen
267
    lcd_cmd(tmp);        // senden
268
}
269
270
//---------------------------------------------------------------------------
271
//    lcd_init(..) - Schaltet die Ports und Initialisiert das LCD
272
//---------------------------------------------------------------------------
273
void lcd_init(void)
274
{
275
 // Portx = Ausgang
276
 DDRA=0xff;
277
 PORTA=0x00;    // Pullup-Widerstände 
278
279
280
281
    // warten bist LCD-Controller gebootet
282
//    _delay_ms(200);        
283
    
284
  // 4-BitModus einschalten
285
    // 
286
    
287
  // x |= (1 << Bitnummer);  // Hiermit wird ein Bit in x gesetzt
288
  // x &= ~(1 << Bitnummer); // Hiermit wird ein Bit in x geloescht 
289
290
  
291
  
292
  set_d5;    //D5 auf High am LCD
293
294
295
  clr_rs;     // RS löschen = Kommando
296
  
297
  // Schreibsignal mit fallender Flanke an E  
298
  set_e;            //E auf 1 
299
  clr_e;            //E auf 0 
300
    
301
  
302
  _delay_ms(20);            // Zeit zum Umschalten lassen
303
    
304
  
305
  // ab hier im 4-Bit-Modus
306
     lcd_cmd(0x28);        // Funktions-Set: 1 Zeile, 5x7 Matrix, 4 Bit
307
  
308
     lcd_off();
309
  lcd_cmd(0x06);        // Entry Mode
310
  lcd_on();
311
  lcd_clear();
312
}
313
314
315
316
//---------------------------------------------------------------------------
317
//    lcd_charDef(..) - initialisiert benutzerdefinierte Zeichen für das LCD
318
//---------------------------------------------------------------------------
319
void lcd_charDef(void)
320
{
321
    // 1. Kommando CGRAM + Adresse setzen
322
    // 2. Punktmatrix-Daten laden
323
    unsigned char charSet[64]={    
324
                                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
325
                                0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,
326
                                0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,
327
                                0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
328
                                0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,
329
                                0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
330
                                0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
331
                                0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
332
                              };
333
    int i=0;
334
    for (i=0;i<64;i++)
335
    {
336
        lcd_cmd(0x40+i);              // cmd 0x40 + Adr
337
        lcd_write(charSet[i]);        // Pixel
338
    }
339
}
340
//---------------------------------------------------------------------------

von Anja (Gast)


Lesenswert?

Du solltest dich genau an die Reset-Sequenz im Datenblatt des 
LCD-Controllers halten.
Falls der Brown-Out Reset im ATMEGA nicht aktiv ist ist zu bedenken daß 
das dort angegebene Timing erst ab einer Spannung von 4,5 V gilt. (der 
1. Delay ist entsprechend anzupassen daß ab 4,5V sicher 15 ms für das 
Display bis zum 1. Reset-Befehl zur Verfügung stehen)

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.