Forum: Compiler & IDEs Display zeigt falsch an


von saschisch (Gast)


Lesenswert?

Hallo Leute!

Wir arbeiten mit dem ATmega 32 mit der Taktfrequenz von 3,6864 Mhz und
versuchen ein Display Powerdip Pc1602d a anzusteuern. Dazu haben wir
uns ein Testprogramm heruntergeladen.

Wir lassen folgendes im Main.c ausgeben:

LCD_Print(0,0,"Servas");
_delay_ms(5000);


das ist das C File dazu
1
/*
2
 Copyright:      Radig Ulrich  mailto: mail@ulrichradig.de
3
 Author:         Radig Ulrich
4
 Remarks:        
5
 known Problems: none
6
 Version:        28.05.2004
7
 Description:    Programm zur Ansteuerung eines Standart LCD
8
         (HD44870),(SED1278F) und kompatible
9
*/
10
11
#include <lcd.h>
12
13
//Prototypes
14
void Write_LCD (char,char);
15
char Read_LCD (char);
16
void LCD_Init (void);
17
void LCD_Clear (void);
18
void LCD_Print (char,char,char *Buffer,...);
19
20
void LCD_Init (void)
21
{  
22
  char tmp = Init_LCD_Zeilen;
23
  //Set Port Direction Register to Output for LCD Databus und LCD
24
Steuerbus
25
  LCD_Port_DDR = LCD_DataOutput+(1<<LCD_RS | 1<<LCD_RW | 1<<LCD_E);
26
  //Wait a short Time afer Power on
27
  for (int a=0;a<3000;a++)
28
    {
29
    
30
    }  
31
  Write_LCD (0x22,0);  //Init in 4 Bit Mode
32
  //Wait a short Time afer Power on
33
  for (int a=0;a<3000;a++)
34
    {
35
    for (int b=0;b<100;b++);
36
    }  
37
  Write_LCD (0x22,0);  //Init in 4 Bit Mode (Zur Sicherheit nochmal)  
38
  if (tmp == 1)
39
    {
40
    Write_LCD (0x20,0);  //1 Zeilen
41
    }
42
    else
43
    {
44
    Write_LCD (0x28,0);  //mehrere Zeilen
45
    }
46
  Write_LCD (0x0C,0);  //Display On
47
  Write_LCD (0x80,0);  //Set DD-Ram Adresse = 0
48
}
49
50
void Write_LCD (char Data,char CD)
51
{
52
  //Set Port Direction Register to Output for LCD Databus und LCD
53
Steuerbus
54
  LCD_Port_DDR = LCD_DataOutput+(1<<LCD_RS | 1<<LCD_RW | 1<<LCD_E);
55
  //Soll ins Seuer oder Datenregister geschrieben werden?
56
  if (CD == 0)
57
    {
58
    cbi(LCD_Port_Write,LCD_RS); //RS = 0 Steuerregister
59
    }
60
    else
61
    {
62
    sbi(LCD_Port_Write,LCD_RS); //RS = 1 Dataregister
63
    }
64
  //Schreibsignal setzen
65
  cbi(LCD_Port_Write,LCD_RW); //Zum Schreiben RW-Pin = Low
66
  //Schreiben der 1. 4Bit an das LCD Display
67
  LCD_Port_Write = (LCD_Port_Write&0xF0) + ((Data&0xF0)>>4); //Write
68
Nibbel MSB
69
  sbi(LCD_Port_Write,LCD_E);
70
  cbi(LCD_Port_Write,LCD_E);
71
  //Schreiben der 2. 4Bit an das LCD Display  
72
  LCD_Port_Write = (LCD_Port_Write&0xF0) + (Data&0x0F); //Write Nibbel
73
LSB
74
  sbi(LCD_Port_Write,LCD_E);
75
  cbi(LCD_Port_Write,LCD_E);
76
  
77
  
78
}
79
80
char Read_LCD (char CD)
81
{
82
  char Data;
83
  //Set Port Direction Register to Output for LCD Databus und LCD
84
Steuerbus
85
  LCD_Port_DDR = LCD_DataInput+(1<<LCD_RS | 1<<LCD_RW | 1<<LCD_E);
86
  //Lesesignal setzen
87
  sbi(LCD_Port_Write,LCD_RW); //Zum Lesen RW-Pin = High
88
  //Soll ins Seuer oder Datenregister geschrieben werden?
89
  if (CD == 0)
90
    {
91
    cbi(LCD_Port_Write,LCD_RS); //RS = 0 Steuerregister
92
    }
93
    else
94
    {
95
    sbi(LCD_Port_Write,LCD_RS); //RS = 1 Dataregister
96
    }
97
  sbi(LCD_Port_Write,LCD_E); //Daten stehen an wenn Enable = High
98
  for (int a=0;a<100;a++)   //Wartet ein bisschen bis daten anliegen
99
  {
100
  }
101
  Data = (LCD_Port_Read&0x0F)<<4; //Lesen des 1. Nibble (MSB)
102
  cbi(LCD_Port_Write,LCD_E);  
103
  
104
  sbi(LCD_Port_Write,LCD_E); //Daten stehen an wenn Enable = High
105
  for (int a=0;a<100;a++)   //Wartet ein bisschen bis daten anliegen
106
  {
107
  }  
108
  Data += (LCD_Port_Read&0x0F); //Lesen des 2. Nibble (LSB)
109
  cbi(LCD_Port_Write,LCD_E);  
110
return(Data);
111
}
112
113
void LCD_Print (char zeile,char spalte,char *Buffer,...)
114
{
115
  // Hilfsvariable zum Zählen der ausgegebenen Zeichen
116
  char nFieldWidth = 0;
117
118
  struct {
119
    char     fLeftJust:1;   // Feldausrichtung links oder rechts
120
    char     fNegative:1;   // Auszugebende Zahl ist negativ.
121
  } flags;
122
123
  #define SCRATCH 16
124
  unsigned char scratch[SCRATCH];
125
  unsigned char format_flag;
126
  unsigned int u_val=0, base=0;
127
  unsigned char *ptr;
128
  char     hexA = 'a';
129
  char *p;
130
  int   n;
131
  int nLen;
132
  va_list ap;
133
    
134
  va_start (ap, Buffer);  
135
  //Berechnet Adresse für die Zeile und schreibt sie ins DD-Ram
136
  if (zeile >= Init_LCD_Zeilen) //wurden mehr Zeilen angegeben als
137
Initialisiert
138
    {
139
    zeile = Init_LCD_Zeilen - 1;
140
    }
141
  zeile = 0x80/Init_LCD_Zeilen*zeile;
142
  zeile += spalte;
143
  if (zeile >= 0x80) //ist der Wert ausserhalb des DD-Ram Adresse
144
    {
145
    zeile = 0x7F;
146
    }
147
  zeile += 0x80;
148
  Write_LCD (zeile,0);
149
  
150
  while (*Buffer != 0)
151
    {
152
    if (*Buffer == '%')
153
      {
154
      *Buffer++;
155
      switch (format_flag = *Buffer++){
156
 
157
        case 'c':
158
           format_flag = va_arg(ap,int);
159
           Write_LCD (format_flag++,1);
160
           
161
        case 'i':
162
        case 'd':
163
        case 'u':
164
                base = 10;
165
                goto CONVERSION_LOOP;
166
        case 'o':
167
                base = 8;
168
                goto CONVERSION_LOOP;
169
        
170
        case 'X':
171
                hexA = 'A';
172
                // Weiter wie 'x'
173
        case 'x':
174
                base = 16;
175
         }
176
177
        CONVERSION_LOOP:
178
                u_val = va_arg (ap, int);
179
        n = u_val;
180
                flags.fNegative = 0;
181
                if (format_flag == 'd' || format_flag == 'i') {
182
                    // Negative Werte auswerten
183
                    if (((int) u_val) < 0) {
184
                        flags.fNegative = 1;
185
                        u_val = -u_val;
186
                    }
187
                }
188
                // Der Scratchpuffer wird von rechts nach links
189
aufgefüllt
190
                // beginnend mit dem niederwertigsten Digit.
191
                ptr = scratch + SCRATCH;
192
                *--ptr = 0;     // Abschliessendes NULL-Byte eintragen
193
                do 
194
        {
195
          char ch = u_val % base + '0';
196
                    if (ch > '9') ch += hexA - '9' - 1;
197
                    *--ptr = ch;
198
          u_val /= base;
199
                } while (u_val);
200
        
201
        if (n < base) *--ptr = '0';
202
                if (flags.fNegative) *--ptr = '-';
203
          // Länge bestimmen
204
          p = ptr;
205
          nLen = 0;
206
          while (*p++) nLen++;
207
        // Feld bei Bedarf links auffüllen
208
        if (!flags.fLeftJust) {
209
        for (n=nLen; n < nFieldWidth; n++) Write_LCD (' ',1);
210
        }
211
        // Pufferinhalt schreiben
212
        for (n=0; n < nLen; n++) Write_LCD (*ptr++,1);
213
        // Feld bei Bedarf rechts auffüllen
214
        if (flags.fLeftJust) {
215
        for (n=nLen; n < nFieldWidth; n++) Write_LCD (' ',1);
216
        }        
217
      }        
218
    Write_LCD (*Buffer++,1);
219
    }
220
  va_end(ap);
221
}
222
223
void LCD_Clear (void)
224
{
225
  Write_LCD (1,0); //Clear Display
226
  Write_LCD (0x80,0);  //Set DD-Ram Adresse = 0
227
}

Die Header DAtei zum festelgen der Ports und so
1
//LCD_D0 - LCD_D3 connect to GND
2
//Im 4Bit Mode LCD_D4-->PORTx.0 ........ LCD_D7-->PORTx.3
3
//LCD_RS --> PORTx.4 | LCD_RW --> PORTx.5 | LCD_E --> PORTx.6 |
4
PORTx.7-->NotConnect
5
6
#define Init_LCD_Zeilen      2     //Anzahl der Zeilen 1,2 oder 4
7
8
#define LCD_Port_DDR      DDRA  //Port an dem das Display angeschlossen
9
wurde
10
#define LCD_Port_Write      PORTA
11
#define LCD_Port_Read      PINA
12
13
#define LCD_RS          4     //Pin für RS
14
#define LCD_RW          5    //Pin für Read/Write
15
#define LCD_E          6     //Pin für Enable
16
17
#define LCD_DataOutput      0x0f
18
#define LCD_DataInput      0x00
19
20
#define BusyBit          7


Das Programm funktioniert soweit, dass wir am Display was sehen, aber
es gibt folgendes aus:

evs<--<--0_HxWWt0__Unterstrich

<-- ist ein Zeichen und ein Pfeil nach links
_ist ein Abstand am Display
Unterstrich ist ein Unterstrich am Display

Danke für eure Hilfe

MfG

saschisch

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.