Forum: Mikrocontroller und Digitale Elektronik LCD_Ansteuerungsproblem_im_Multitasking_Betrieb


von caler (Gast)


Lesenswert?

Hallo!
Ich benutze einen atmega32 und 1 displaytech 162 LCD-Modul.
Möchte dieses dann direkt über PORTC des avrs ansteuern.
Gleichzeitig sind an PORTC 4 Tasten angehängt. Dies bedeutet 
automatisch, dass diese PINS auf high sind.
Habe folgendes Problem:
Mein Programm sollte durch Betätigen einmalig ein "H" ausgeben.
Wenn ich "H" auf dem Display ausgeben möchte, gibt er eine 0 
(irgendwo)aus.
 siehe Code:
1
#include<avr/signal.h>
2
/// Includes //////////
3
#include <avr/io.h>
4
#include "os.h"
5
#include <stdbool.h>
6
#include <avr/interrupt.h>
7
#define LCD_PORT_w    PORTC
8
#define LCD_PORT_DDR  DDRC
9
#define DISPLAY_RS  (1<<3)
10
#define DISPLAY_EN  (1<<2)
11
12
//LCD
13
void    _long_delay(void);
14
void    _lcd_write_command(unsigned char);
15
void    LCD_Write(unsigned char *);
16
void    LCD_Init(void);
17
char    LCD_Putchar(char);
18
#define LCD_Clear  {_lcd_write_command(0x01); _long_delay();_long_delay();}
19
void    LCD_Gotoxy(unsigned char  , unsigned char );
20
void    LCD_Gotoxy2(unsigned char  , unsigned char );
21
void    LCD_DezAusgabe(unsigned long wert , char stellen , unsigned char punkt);
22
void LCD_Puts(const char *s);
23
 bool akku;
24
 float realakku;
25
 int intakku;
26
27
//Uservariablen
28
 
29
/// Data 
30
bool lcd;
31
///Data Types /////////
32
typedef unsigned char u8;
33
typedef unsigned int u16;
34
typedef struct task
35
{
36
   // pointer to a function
37
   void (*pfunc) (void);
38
   // delay before the first call
39
   u16 delay;
40
   // interval between subsequent runs
41
   u16 period;
42
   // flag indicating time to run
43
   u8 run;
44
}task;
45
46
/// Defines ///////////
47
// 25msec period 256-180 
48
// 7.3728MHz and /1024 prescaler
49
#define StartFrom       76
50
// maximum number of tasks
51
#define MAXnTASKS       20
52
53
/// Globals ///////////
54
volatile task TaskArray[MAXnTASKS];
55
56
/// Prototypes ////////
57
void InitUART (u16 baud);
58
void TransmitByte (u8 data);
59
void InitScheduler (void);
60
void UpdateScheduler(void);
61
void DeleteTask (u8 index);
62
void AddTask (void (*taskfunc)(void), u16 taskdelay, u16 taskperiod);
63
void DispatchTask (void);
64
65
void SPSTASK (void);
66
void LCDTASK (void);
67
void SERKOMTASK (void);
68
69
/// Main //////////////
70
int main(void)
71
{
72
   InitUART (23);
73
   InitScheduler();
74
   DDRB=0xFF;     
75
   // populate task array       
76
   AddTask (t0, 0, 3);
77
   AddTask (t1, 1, 4);
78
   AddTask (t2, 4, 0);
79
      LCD_Init();
80
  LCD_Clear;
81
  LCD_Gotoxy(0,0);
82
  
83
   // enable interrupts
84
   sei();
85
        
86
   while (1) 
87
   {
88
      DispatchTask();
89
   }            
90
}
91
92
void InitUART (u16 baud)
93
{
94
unsigned char x;
95
   UBRRH = (u8)(baud>>8);                                                        
96
   UBRRL = (u8)baud;
97
   UCSRB = (1<<RXEN)|(1<<TXEN);              
98
   UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
99
   UART.Betriebsart=true;
100
 // UCSRB|=(1<<RXCIE);
101
x=UDR;
102
}
103
104
void TransmitByte (u8 data)
105
{
106
   while ( !( UCSRA & (1<<UDRE)) );
107
   UDR = data;
108
}
109
110
void InitScheduler (void)
111
{
112
   u8 i;
113
   
114
   // timer prescaler clock/1024
115
   TCCR0 |= (1<<CS01)|(1<<CS00);
116
   // clear pending interrupts
117
   TIFR = 1<<TOV0;
118
   // enable timer0 overflow interrupt
119
   TIMSK |= 1<<TOIE0;
120
    // load timer0
121
   TCNT0 = StartFrom;
122
123
   // clear task array
124
   for (i=0; i<MAXnTASKS; i++) DeleteTask(i);
125
}
126
127
void DeleteTask (u8 j)
128
{
129
   TaskArray[j].pfunc = 0x0000;
130
   TaskArray[j].delay = 0;
131
   TaskArray[j].period = 0;
132
   TaskArray[j].run = 0;
133
}
134
135
void AddTask (void (*taskfunc)(void), u16 taskdelay, u16 taskperiod)
136
{
137
   u8 n=0;
138
139
   // find next available position
140
   while ((TaskArray[n].pfunc != 0) && (n < MAXnTASKS)) n++;
141
142
   // place task
143
   if (n < MAXnTASKS)
144
   {
145
      TaskArray[n].pfunc = taskfunc;
146
      TaskArray[n].delay = taskdelay;
147
      TaskArray[n].period = taskperiod;
148
      TaskArray[n].run = 0;   
149
   }
150
}
151
152
SIGNAL(SIG_OVERFLOW0)
153
{
154
   u8 m;
155
156
   // testing
157
  // TransmitByte(45); // (-)
158
   
159
   // load timer
160
   TCNT0 = StartFrom;
161
   
162
   for (m=0; m<MAXnTASKS; m++)
163
   {
164
      if (TaskArray[m].pfunc)
165
      {   
166
         if (TaskArray[m].delay == 0) 
167
         {
168
            TaskArray[m].run = 1;
169
            TaskArray[m].delay = TaskArray[m].period;
170
         }
171
         else TaskArray[m].delay--;
172
      }
173
   }
174
}
175
176
void DispatchTask (void)
177
{
178
   u8 k;
179
   
180
   for (k=0; k<MAXnTASKS; k++)
181
   {
182
      if (TaskArray[k].run == 1)
183
      {
184
         // run task
185
         (*TaskArray[k].pfunc)();
186
         // clear run flag
187
         TaskArray[k].run = 0;
188
      }
189
   }
190
191
}
192
193
void t0(void)
194
195
{ //nicht wichtig für diese Betrachtungen
196
197
              }
198
void t1(void)
199
200
{
201
//nicht wichtig für diese Betrachtungen
202
  
203
204
              }
205
206
207
void t2(void){
208
DDRC=0x00; //PORTC EINGANG-UmTasten herauszulesen
209
if(!(PINC&0x80)&&!lcd){LCD_Init();
210
LCD_Gotoxy(0,0);
211
LCD_Write("H");
212
lcd=true;
213
}
214
}
215
216
217
void _long_delay(void)
218
{
219
int t = 50000;
220
while (t--);
221
}
222
223
void _short_delay(void)
224
{
225
int t = 20000;
226
while (t--);
227
}
228
229
230
void _lcd_write_command(unsigned char data)
231
{
232
  DDRC |= (0x80+0x40+0x20+0x10+0x08);
233
  LCD_PORT_w = (data & 0xf0) | DISPLAY_EN;
234
  LCD_PORT_w = (data & 0xf0) | DISPLAY_EN;
235
  LCD_PORT_w = (data & 0xf0) | DISPLAY_EN;
236
  LCD_PORT_w = (data & 0xf0);
237
  LCD_PORT_w = (data & 0xf0);
238
  LCD_PORT_w = (data & 0xf0);
239
  LCD_PORT_w = (data << 4) | DISPLAY_EN;
240
  LCD_PORT_w = (data << 4) | DISPLAY_EN;
241
  LCD_PORT_w = (data << 4) | DISPLAY_EN;
242
  LCD_PORT_w = (data << 4);
243
    DDRC &= ~(0x80+0x40+0x20+0x10+0x08);
244
   PORTD &= ~0x08;
245
 
246
}
247
248
void _lcd_write_4bit(unsigned char data)
249
{
250
 DDRC |= (0x80+0x40+0x20+0x10+0x08);
251
  LCD_PORT_w = (data << 4) | DISPLAY_EN;
252
  LCD_PORT_w = (data << 4) | DISPLAY_EN;
253
  LCD_PORT_w = (data << 4) | DISPLAY_EN;
254
  LCD_PORT_w = (data << 4);
255
  LCD_PORT_w = (data << 4);
256
    DDRC &= ~(0x80+0x40+0x20+0x10+0x08);
257
 PORTD &= ~0x08;
258
 
259
}
260
261
void lcd_write_byte(unsigned char data)
262
{
263
 DDRC |= (0x80+0x40+0x20+0x10+0x08);
264
  LCD_PORT_w = (data & 0xf0) | DISPLAY_EN | DISPLAY_RS;
265
  LCD_PORT_w = (data & 0xf0) | DISPLAY_EN | DISPLAY_RS;
266
  LCD_PORT_w = (data & 0xf0) | DISPLAY_RS;
267
  LCD_PORT_w = (data & 0xf0) | DISPLAY_RS;
268
  LCD_PORT_w = (data << 4)   | DISPLAY_EN | DISPLAY_RS;
269
  LCD_PORT_w = (data << 4)   | DISPLAY_EN | DISPLAY_RS;
270
  LCD_PORT_w = (data << 4)   | DISPLAY_RS;
271
    DDRC &= ~(0x80+0x40+0x20+0x10+0x08);
272
 PORTD &= ~0x08;
273
 
274
}
275
276
277
int my_pput(int zeichen)
278
{
279
 lcd_write_byte((char) zeichen);
280
 return(1);
281
}
282
283
284
285
// getch.c
286
unsigned char getch(void)   // warten und Zeichen abholen
287
{
288
 loop_until_bit_is_set(UCSRA, RXC);    // warte bis Zeichen da
289
290
 return UDR;                           // Zeichen abholen
291
}
292
293
// getche.c warten, Zeichen abholen und im Echo senden
294
void getche(void)
295
{
296
 unsigned char x;
297
 loop_until_bit_is_set(UCSRA, RXC);
298
 x = UDR;
299
 loop_until_bit_is_set(UCSRA, TXC);
300
 UDR = x;
301
}
302
// initialize the LCD controller
303
void LCD_Init(void)
304
{
305
306
LCD_PORT_DDR = 0xff;// - (0x01 + 0x02) ;//0xf0 | DISPLAY_RS | DISPLAY_EN;
307
_long_delay();
308
_long_delay();
309
_lcd_write_4bit(0x03);     // noch 8 Bit
310
_long_delay();
311
_lcd_write_4bit(0x03);     // noch 8 Bit
312
_long_delay();
313
_lcd_write_4bit(0x03);     // noch 8 Bit
314
_long_delay();
315
_lcd_write_4bit(0x02);     // jetzt 4 Bit
316
_long_delay();
317
318
_lcd_write_command(0x28);     // 4 Bit Zweizeilig
319
//-
320
_long_delay();
321
_long_delay();
322
_lcd_write_command(0x1C);     
323
_long_delay();
324
_lcd_write_command(0x74);     
325
_long_delay();
326
_lcd_write_command(0x52);     // 
327
_long_delay();
328
_lcd_write_command(0x69);     // Contrast 
329
330
// ----------------------------
331
//-
332
_long_delay();
333
_lcd_write_command(0x08);     // Display aus
334
_long_delay();
335
_lcd_write_command(0x01);     // Clear
336
_long_delay();
337
_lcd_write_command(0x06);     //Entry mode
338
_long_delay();
339
_lcd_write_command(0x08 + 4); // Display an
340
_long_delay();
341
}
342
343
344
void LCD_Gotoxy(unsigned char x , unsigned char y)
345
 {
346
  _short_delay();
347
  switch(y)
348
  { case 0 : _lcd_write_command(x + 0x80); break;
349
    case 1 : _lcd_write_command(x + 0xC0); break;
350
    case 2 : _lcd_write_command(x + (0x80 + 20)); break;
351
    case 3 : _lcd_write_command(x + (0xC0 + 20)); break;
352
  }
353
  
354
}
355
356
357
void LCD_Write(unsigned char *this_text)
358
{
359
 unsigned char i = 0;
360
  
361
 while(this_text[i] != 0) 
362
  {
363
   lcd_write_byte(this_text[i++]);
364
   _long_delay();
365
   
366
  }
367
    
368
  
369
}
370
371
char LCD_Putchar(char zeichen)
372
{
373
_short_delay();
374
 lcd_write_byte((char) zeichen);
375
 return(1);
376
}
Bitte um jede Art von Hilfe.

Gruß

von holger (Gast)


Lesenswert?

>void t2(void){
>DDRC=0x00; //PORTC EINGANG-UmTasten herauszulesen

Was soll der Blödsinn hier das DDR für den kompletten Port
zu setzen? Und wieso wird das DDR für die Tasten erst hier
gesetzt? Einmal reicht. Muß man nicht dauernd machen.

>if(!(PINC&0x80)&&!lcd){LCD_Init();

Was soll der Schwachsinn mit dem LCD_Init() hier?
Einmal reicht.

>LCD_Gotoxy(0,0);
>LCD_Write("H");
>lcd=true;
>}
>}

>void LCD_Init(void)
>{
>
>LCD_PORT_DDR = 0xff;// - (0x01 + 0x02) ;//0xf0 | DISPLAY_RS | DISPLAY_EN;

Was soll der Blödsinn hier das DDR für den kompletten Port
zu setzen? Setz die Bits die du brauchst und gut.

Alles Blödsinn was du da machst. Und dann mit
Multitasking rumspielen. Ich schmeiß mich weg;)

von caler (Gast)


Lesenswert?

Hallo. Nein reicht nicht, denn PORTC muss zugleich Tasteneingänge und 
als LCD-port dienen.
Das andere ist nur figurativ gesehen.
Meine Frage war andersrum, ob nämlich etwas an den LCD-funktionen falsch 
ist

gruß

von Hannes L. (hannes)


Lesenswert?

JTAG-Interface deaktiviert?

...

von Zacc (Gast)


Lesenswert?

Alles Falsch. Alles in die Tonne. Ein LCD dauert seine Zeit zum 
Initialisieren. Und die Tasten duerfen die Bits kaputtmachen... Und 
Multitasking... heul. Das bringt nichts, mach was anderes.

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.