Hi @ all
Ich will mit einem Microchip 16F818 ein 16x2 LCd ansteuern.
Ich bin ein super Neuling im bereich C.
Habe einen passenden code gesucht, denn ich auch verstehe, aber leider
nix passendes gefunden. Meine Variante ist ziemlich arm, aber bis jetzt
verstehe ich was ich da mache.
LCD:
http://www.reichelt.de/?ACTION=3;ARTICLE=31653;GROUPID=;SID=26UdltsKwQARoAAGBRH3M2ea74ad3aed975aa737531eaf9583acd
Wer viel Zeit hat kann mir ja gerne eine schönere Variante erklären. Wer
weniger Zeit hat einfach nur mein programm korrigieren damit es läuft.
Wenn ich was angezeigt komme, sei es auch nur ein Buchstabe/Zeichen,
dann wäre das erstmal ein großer erfolg.
Zur Zeit leuchtet nur die Zweite Zeile komplett auf.
Ich bedanke mich im vorraus für eure Antworten.
Hallo!
Was mir sofort bei deinem Code aufgefallen ist ist folgendes:
1
voidmain()
2
{
3
while(1)
4
{
5
LCD_INIT();
6
LCD_SCHREIBEN();
7
8
}
9
}
In deiner Endlosschleife wird das LCD dauern initialisiert und mit Daten
gefüttert. Da das LCD ein sehr langsames Bauteil ist, wirst Du nie was
sehen, da die Initialisation mit dem Befehl (display clear) die Zeilen
immer wieder löscht. Das Display muss man ja nur einmal initialisieren.
Um zumindest zu sehen, ob das LCD mit deinem Code irgendwas ausgibt
musst Du Deine Befehle aus der Endlosschleife nehmen. Denn das LCD zeigt
ja solange das gleiche an, bis Du wieder was neues sendest.
Nimm also Deine Befehle aus der Schleife.
1
voidmain()
2
{
3
LCD_INIT();
4
LCD_SCHREIBEN();
5
while(1)
6
{
7
Nop();
8
}
9
}
Was ich noch auf die schnelle gesehen hab. Die LCD Leitungen definierst
Du nirgends als Output, oder? Oder sind die bei einem Reset schon vom
PIC so geschaltet?
Versuch das mal und berichte, was das LCD dann macht. Für das durchsehen
der Initialisation hab ich momentan keine Zeit ;)
MfG Darkleon
Mit welchem takt läuft Dein PIC?
Wie hast Du den Pin am LCD für den Kontrast (glaub der heißt Vo)
beschalten?
In Deiner Init hast Du irgendwie nie delays drinnen. Glaub mich zu
erinnern, dass nach dem Function Set usw.. im Datenblatt jeweils eine
Mindestwartezeit drinnsteht. Muss ich später mal nachschauen.
Wegen der genauen Init kann ich auch erst etwas später nachschauen, aber
kontrollier mal das, dann hast diese Fehlerquellen auch ausgeschlossen
;)
MfG Darkleon
Also der Pic läuft mit 8MHZ.
Kontrast ist über einen 10 K Poti an 5V.
Also da wo im Datenblatt wartezeiten sind müssten welche drin sein.
Ich werde nochmal nach allen Befehlen so 100µs wartezeit einbauen.
Mal gucken was sich dann ergibt.
Ich denke aber nicht, dass das der Fehler ist.
Melde mich gleich nochmal.
Die eine "schwarze" Zeile, die andere leer kommt eigentlich dann, wenn
nicht mal die Initialisierung klappt. Ist das Display auch richtig
angeschlossen? Beim 4 Bit Interface werden D4-D7 verdrahtet, D0 - D3
sollten ... hmmm .... ja was denn ... pull up oder down ... weiß ich im
moment nicht auswendig.
Also an den Delays lag es nicht.
Als D4 bis D7 ist angeschlossen.
D0-D3 ist einfach frei. Oder sollte das lieber an GND, aber auch im
Tutorial hier auf der Seite steht, dass die einfach nicht angeschlossen
werden sollen.
Daran sollte es nicht liegen.
Wenn dann wohl eher an einem Fehler beim Initialisieren. Ich habe schon
mehr mals drüber geguckt, aber finde den Fehler leider nicht.
Den R/W PIN habe ich auf GND gelötet.
Da ich nur schreibe und nicht lese brauche ich den nicht.
Ich habe mal meine Funktion "LCD_SCHREIBEN" auskommentiert und dann
entshet keine "schwarze" zeile.
Jetzt ist die Frage ob der Fehler beim Schreiben oder beim
Initialisieren liegt.
Im Tutorial steht aber auch, dass es mit dem Timing bei Takten >= 8MHz
Probleme geben kann. Deshalb solltest Du beim Schreiben E im Auge
behalten, damit es nicht zu kurz wird.
Und nach dem schreiben - da du ja nicht liest kann dir das Display auch
nicht sagen, ob es mit einer Operation fertig ist - musst Du auch ca
50us warten ... Clear screen z.B. dauert noch länger und man sollte ca.
5ms warten. Das ist wohl in der Init noch nicht so.
habe leider alles versucht. Da stimmt irgendwas nicht.
Ich werde jetzt erstmal pause machen.
Morgen werde ich alles nochmal durchklingeln um zu gucken ob alles
richtig dran ist und dann versuche ich nochmal mein Glück.
Hallo!
Hab mir jetzt das Datenblatt angesehen.
Bei der Init wird eine Pause von mindestens 30ms nach erreichen von VDD
empfohlen.
In Deinem Code aus dem ersten Post wartest Du nur 15ms.
Das Function Set hast Du richtig initialisiert.
Danach kommt eine Mindestwartezeit von 39us. Die sehe ich in deinem Code
nicht.
Dann initialisierst Du "Display ON/OFF Control". In dieser
Initialisation schaltest Du das Display aber aus. Ist doch nicht so
gewollt, oder?
1
Daten(0,0,0,0);// ab hier, display aus, blinken aus und cursor aus
2
output_high(E);
3
output_low(E);
4
5
Daten(1,0,0,0);
6
output_high(E);
7
output_low(E);// bis hier
Richtig müsste es laut Datenblatt so sein:
1
Daten(0,0,0,0);// ab hier, display AN, blinken aus und cursor aus
2
utput_high(E);
3
output_low(E);
4
5
Daten(1,1,0,0);
6
output_high(E);
7
output_low(E);// bis hier
Mindestwartezeit von 39us.
Dann kommt richtigerweise "Display clear".
Mindestwartezeit von 1,53ms.
Dann kommt "Entry Mode Set"
Du sendest DB7 UND DB6 Low, im Datenblatt ist aber DB7 auf Low und DB6
jeden Fall High.
Danach initialisierst du mit "increment mode"(DB5) und "entire shift
off"(DB5).
Also Dein Code
1
Daten(0,0,0,0);// ab hier, kursor nach rechts
2
output_high(E);
3
output_low(E);
4
5
Daten(0,0,1,0);
6
output_high(E);
7
output_low(E);// bis hier
So sollte es aussehen:
1
Daten(0,0,0,0);// ab hier, kursor nach rechts
2
output_high(E);
3
output_low(E);
4
5
Daten(0,1,1,0);
6
output_high(E);
7
output_low(E);// bis hier
Danach ist die Initialisation zu Ende. Da würd ich auch nochmal ein paar
ms warten.
Die letzte Init mit dem "Display an..." würd ich weglassen, da das
Display wahrscheinlich nicht weiß wohin damit. Ich würd das Display
gleich an richtiger Stelle (wie oben beschrieben) einschalten.
Und warte nach jeder Pegeländerung von E und RS mind. eine us, da du
laut Datenblatt mit deinen 8Mhz Takt viel zu schnell bist und das
Display die Pegeländerung nicht korrekt mitbekommt.(Wurde aber schon vor
diesem Post beschrieben.
Änder mal Deinen Code und Füg die ganzen Wartezeiten hinzu. (Zwischen
den Initblöcken, bei RS und E und erhöhe die 15ms Wartezeit am Anfang).
Viel kann dann nicht mehr falsch sein.
So long.
Darkleon
Du musst den ersten Initialisierungsbefehl 3x (!) rüberschicken, danach
erst auf 4 bit umschalten (siehe http://www.sprut.de/electronic/lcd/),
bei manchen Displays muss man auch länger warten, also:
hi,
Danke für deine Zeit und Mühe.
Also ich habe jetzt alles geändert was du sagtest:
hier nochmal falls sich doch fehler reingeschlichen haben:
1
#define RS PIN_A2
2
#define E PIN_A3
3
#define DB4 PIN_A6
4
#define DB5 PIN_A7
5
#define DB6 PIN_A0
6
#define DB7 PIN_A1
7
8
voidDaten(inta,intb,intc,intd)//Funktion um 4 Bit Daten über 4 Leiten zu senden
9
{
10
if(a)
11
{
12
output_high(DB7);
13
}
14
else
15
{
16
output_low(DB7);
17
}
18
if(b)
19
{
20
output_high(DB6);
21
}
22
else
23
{
24
output_low(DB6);
25
}
26
if(c)
27
{
28
output_high(DB5);
29
}
30
else
31
{
32
output_low(DB5);
33
}
34
if(d)
35
{
36
output_high(DB4);
37
}
38
else
39
{
40
output_low(DB4);
41
}
42
}
43
44
voidLCD_INIT()
45
{
46
inti;
47
delay_ms(30);
48
output_low(RS);// Alle LCD-Steuerleitungen LOW
49
output_low(E);
50
delay_us(1);
51
52
for(i=0;i<3;i++)// Auf das BF warten
53
{
54
Daten(0,0,1,1);
55
output_high(E);// Befehl an LCD
56
delay_us(1);
57
output_low(E);// (durch toggeln der LCD-Enable-Leitung)
58
delay_ms(5);// mind. 4.1 ms warten
59
}
60
61
Daten(0,0,1,0);// Auf 4- Bit modus
62
output_high(E);// Befehl an LCD
63
delay_us(1);
64
output_low(E);// (durch toggeln der LCD-Enable-Leitung)
65
66
delay_us(40);
67
68
Daten(0,0,1,0);//ab hier 2 zeilig und 5x7 Matrix
69
output_high(E);
70
delay_us(1);
71
output_low(E);
72
73
Daten(1,0,0,0);
74
output_high(E);
75
delay_us(1);
76
output_low(E);// bis hier
77
78
delay_us(40);
79
80
Daten(0,0,0,0);// ab hier, display AN, blinken aus und cursor aus
81
output_high(E);
82
delay_us(1);
83
output_low(E);
84
85
Daten(1,1,0,0);
86
output_high(E);
87
delay_us(1);
88
output_low(E);// bis hier
89
90
delay_us(40);
91
92
Daten(0,0,0,0);// ab hier, display clear
93
output_high(E);
94
delay_us(1);
95
output_low(E);
96
97
Daten(0,0,0,1);
98
output_high(E);
99
delay_us(1);
100
output_low(E);// bis hier
101
102
delay_ms(2);
103
104
Daten(0,0,0,0);// ab hier, kursor nach rechts
105
output_high(E);
106
delay_us(1);
107
output_low(E);
108
109
Daten(0,1,1,0);
110
output_high(E);
111
delay_us(1);
112
output_low(E);// bis hier
113
114
delay_ms(5);
115
}
116
117
voidLCD_SCHREIBEN()
118
{
119
output_high(RS);// rs high um zu schreiben
120
delay_us(1);
121
output_low(E);
122
123
Daten(0,0,1,1);// die ersten 4 bit
124
output_high(E);
125
delay_us(1);
126
output_low(E);
127
128
Daten(0,0,0,1);// die letzen 4 bit
129
output_high(E);
130
delay_us(1);
131
output_low(E);
132
133
delay_us(1);
134
output_low(RS);
135
}
Leider kein Erfolg.
Die untere Zeile leuchtet komplett schwarz auf.
Ich werde morgen nochmal alles durchklingeln und schauen.
Ich hoffe dass nur da der Fehler ist und es nicht am Programm liegt.
Wie ist der momentane Status?
Funktioniert es jetzt?
Deinem Code entnehme ich folgende Pinbelegung:
RS -- RA2
E -- RA3
DB4 -- RA6
DB5 -- RA7
DB6 -- RA0
DB7 -- RA1
Im Datenblatt des PICs steht unter "5.0 I/O Ports", dass bei einem Reset
die Pins RA0 - RA4 als digitale Inputs konfiguiert sind.
Da du diese Pins für dein LCD als digitale Outputpins benötigst, musst
du dies natürlich dem Controller in das ADCON1 Register schreiben. Sonst
bleiben diese Pins analoge Inputs.
Ich weiß ja nicht, welchen Compiler du verwendest?! Macht der das
automatisch? Denke nicht.
Daher musst Du das ADCON1 Register mit dem Wert 0x06 beschreiben.
So werden die Pins RA0 - RA4 als digitale Pins definiert!
Denke an dem wirds liegen (sofern Du nichts falsch vedrahtet hast), denn
die Initialisierung stimmt soweit. Auch das Senden der Daten (In Deinem
Fall die Zahl eins!)
Melde Dich, sobald Du das überprüft hast. Würd mich interessieren.
So long,
Darkleon
Update:
Meinte natürlich, dass RA0 - RA4 ANALOGE und nicht digitale Inputs bei
einem Reset (und auch standarmäßig) Pins sind.
Die Hand war wieder schneller als das Hirn ;)
Gibts schon Neuigkeiten?
MfG Darkleon