Forum: Mikrocontroller und Digitale Elektronik [PIC] LCD verwenden


von Andreas R. (blackpuma)


Lesenswert?

Guten Abend!

Ich habe Probleme mit meinem LCD Display von ANAG VISION AV1624. 
Controller auf dem Display ist ein KS0066 oder Ähnliches steht im 
Datenblatt.

Ich habe es soweit fertig bekommen das ich einen Cursor habe der blinkt 
und "Zeichen" ausgeben kann. Das Problem an den Zeichen ist nur das es 
meistens nur schwarze Blöcke sind.

Hier ist mein Code:
1
/** D E C L A R A T I O N S ************************/
2
#pragma code
3
4
#define LCD_data LATD
5
#define LCD_enable LATDbits.LATD5
6
#define LCD_rw LATDbits.LATD6
7
#define LCD_rs LATDbits.LATD7
8
9
void lcd_init();
10
void Delay_ms(int ms);
11
void LCD_WriteRegister(char x);
12
13
// **********************************************
14
//
15
//
16
// Delay
17
//
18
//
19
//***********************************************
20
void Delay_ms(int ms)
21
{
22
int i, e;
23
for( e = 0; e <= ms; e++)
24
{
25
  for( i = 0; i <= 80; i++ ) 
26
  {
27
    Delay10TCYx(18);
28
  }
29
}
30
}
31
32
// **********************************************
33
//
34
//
35
//Befehlsübergabe
36
//
37
//
38
// **********************************************
39
void lcd_enable(void)
40
{
41
LCD_enable = 1;
42
Delay10TCYx(100); //Verzögerung
43
LCD_enable = 0;
44
}
45
46
// **********************************************
47
//
48
//
49
//LCD Initialisieren
50
//
51
//
52
// **********************************************
53
void lcd_init(void)
54
{
55
  PORTD = 0x00;
56
57
// Nach Power on ein wenig warten
58
// Ininitlisierung nach dem Reset
59
  Delay_ms(15);
60
  PORTD = 0x03; 
61
  lcd_enable();
62
63
  Delay_ms(5);
64
  lcd_enable();
65
66
  Delay_ms(1);
67
  lcd_enable();
68
69
// 4 Bit Interface
70
  LCD_WriteRegister(0x02);
71
72
// 2 Zeilig, 5x7
73
//
74
// N = 1 2 Zeilen Display
75
//   = 0 1 Zeilen Display
76
// F = 1 5x10 Zeichen
77
//   = 0 5x7 Zeichen
78
  LCD_WriteRegister(0x28);  
79
80
// Display an
81
// D = 1 Display ein
82
//   = 0 Display aus
83
// C = 1 Curor Unsichtbar
84
//   = 0
85
// B = 1 Cursor Blinkt
86
//   = 0
87
  LCD_WriteRegister(0x0F);  
88
89
// Display Löschen
90
  LCD_WriteRegister(0x01);
91
92
// Entry Mode
93
  LCD_WriteRegister(0x06);
94
}
95
96
// **********************************************
97
// Wird für die Initialisierung verwendet.
98
//
99
// 
100
// Status: Funktioniert
101
// **********************************************
102
void LCD_WriteRegister(char z)
103
{
104
  char x;
105
  Delay_ms(1);
106
107
  x = z & 0x0f;
108
  PORTD = x;
109
  lcd_enable();
110
111
  Delay_ms(1);
112
  x = (x<<4)& 0x0f;
113
  PORTD = x;
114
  lcd_enable();
115
}
116
117
// **********************************************
118
// Schreibt ein Zeichen auf das Display.
119
//
120
//
121
// Status: Nicht komplett
122
// **********************************************
123
void LCD_WriteChar(unsigned char data)
124
{
125
PORTD = 0x00;
126
LCD_data =(data<<4)&0x0f;
127
LCD_rs = 1;
128
lcd_enable();
129
130
LCD_data = 0x00; // Clear Low.nibble
131
LCD_data = data&0x0f;
132
LCD_rs = 1;
133
lcd_enable();
134
}
135
136
// **********************************************
137
//
138
// Hauptprogramm
139
//
140
//
141
// **********************************************
142
void main(void)
143
{
144
//Einstellen der Ports
145
// 0 = Output
146
// 1 = Input
147
TRISD = 0x00; //PORT D Ausgang
148
PORTD = 0x00;
149
150
//Initialisierung LCD
151
lcd_init();
152
153
LCD_WriteChar(0b01100001);
154
LCD_WriteChar('0');
155
LCD_WriteChar('1');
156
LCD_WriteChar('b');
157
LCD_WriteChar('5');
158
LCD_WriteChar('j');
159
160
while(1);

Die Ausgabe am Display ist: "Block" "Space" "Block" "Space" "Space" "P"

Hoffe ihr könnt mir helfen. Ich ärgere mich schon seit 2 Tagen mit dem 
rum.

LG
Andreas

von TK (Gast)


Lesenswert?

Ich hab den Code jetzt nicht durchgesehen, aber meistens handelt es sich 
bei diesem "Phänomen" um ein Initialisierungsproblem. Was sagt denn das 
Datenblatt zum LCD. Da ist doch bestimmt eine Init-Routine beschrieben??
Mach mal am Anfang ein Delay von mindestens 150ms rein!!!
Ich glaube, die Initialisierung für 4bit Modus geht auch anders!
Da muß der "FUNCTION MODE" nämlich 2mal hintereinander gesendet werden.

So weit

Gruß
TK

von Andreas R. (blackpuma)


Lesenswert?

Also an die Initialisierungs Routine im Datenblatt hab ich mich 
gehalten. Hab am Anfang 15ms Wartezeit eingebaut.

Die Initialisierung funktioniert denke ich. Blinkender Cursor, Display 
an und aus, kein Cursor... Das Funktioniert soweit.

Nur wenn ich Zeichen ausgeben will kommt Müll raus.

LG
Andreas

von Εrnst B. (ernst)


Lesenswert?

1
void LCD_WriteRegister(char z)
2
// Nebenbei: Warum hier "char", und nicht "unsigned char", sind doch
3
// "Befehls-Bytes"
4
{
5
...
6
x = z & 0x0f;  PORTD = x; // Zuerst LOW Nibble,
7
...
8
x = (x<<4)& 0x0f; // Dann HIGH-Nibble
9
...
10
11
12
void LCD_WriteChar(unsigned char data)
13
// Warum hier "unsigned char", sind doch "Buchstaben", also "char"
14
{
15
...
16
LCD_data =(data<<4)&0x0f;
17
// Zuerst High-Nibble
18
...
19
LCD_data = 0x00; // Clear Low.nibble <== WARUM?
20
...
21
LCD_data = data&0x0f;
22
// Dann Low-Nibble
23
...

Sicher dass die Nibble-Reihenfolge hier stimmt? Im WriteRegister machst 
du es genau anders herum!

Und gewöhn dir das ständige hin- und herwechseln zwischen PORTD und LATD 
ab, entscheid dich für eine Variante.

von Andreas R. (blackpuma)


Lesenswert?

Ich habe es bei LCD_WriteChar auch anders rum versucht mit den Nibbles. 
Gleiches Ergebnis. Zwar andere Zeichen aber noch nicht das was ich 
ausgeben will.

Das mit PORTD und LATD hab ich noch nicht ganz ausgebessert. Ich habe 
das von einem anderen Programm abgeschrieben und da war PORTD.

von holger (Gast)


Lesenswert?

>Ich habe es bei LCD_WriteChar auch anders rum versucht mit den Nibbles.

Du scheinst dir selber nicht im klaren darüber
zu sein wo denn die Datenleitungen vom Display
angeschlossen sind. Ich rate mal PORTD0..3
Links schieben geht da schon mal gar nicht.
Dann überschreibst du deine Steuerleitungen.
Rechts schieben ist also die richtige Richtung.

Und das hier z.B. ergibt genau 0.

  x = (x<<4)& 0x0f;

von Andreas R. (blackpuma)


Lesenswert?

Ich danke euch!

Die ganze hin und herschieberei war Schuld. Zuerst High und dann Low 
Nibble! Bei der Initialisierung hab ich zuerst Low und dann high 
geschickt und deshalb kam er da durcheinander. Genauer gesagt in der 
Funktion LCD_WriteRegister.

Danke euch allen!

LG
Andreas

von Sascha F. (sascha_focus) Benutzerseite


Lesenswert?

Hi,

was ist denn daraus geworden???

Beitrag "Probleme mit PIC18F4550"

Gruß Sascha

von Andreas R. (blackpuma)


Lesenswert?

Hab dort geschrieben das es mit der Config von dir nun funktioniert. Ich 
habe aber den Bootloader nocht nicht ausprobiert weil ich die USB Buchse 
noch nicht eingelötet habe.

LG
Andreas

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.