[PIC] LCD verwenden

#1251976
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
Gast #1252407
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
#1252513
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.
Gast #1252675
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;

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren