Forum: Mikrocontroller und Digitale Elektronik PIC18F4620, PICDEM2 Plus und LCD


von Kevin J. (noway)


Lesenswert?

Moin Moin.

Ich sitze hier mit meinem PICDEM2 Plus Board und einem P18F4620 und 
versuche verzweifelt, dem LCD Leben einzuhauchen. Leider wehrt es sich 
noch.

Ich habe irgendwo in der Initialisierung (in C geschrieben) einen 
Fehler, den ich nicht lokalisieren kann. Nun muss ich dazu sagen, das 
ich ein C Anfänger bin und mich noch in die Materie einarbeiten muss. 
Aber genau aus diesem Grund suche ich hier Hilfe.

Hier meine Initialisierungssequenz:
Anmerkung: Die Datenleitungen 4-7 hängen an RD0-3
1
#include <p18F4620.h>
2
 
3
void main(void)
4
 
5
{
6
#define RW_PIN LATDbits.LATD5        /* PORT for RW */ 
7
#define TRIS_RW TRISDbits.TRISD5     /* TRIS for RW */ 
8
#define RS_PIN LATDbits.LATD4        /* PORT for RS */ 
9
#define TRIS_RS TRISDbits.TRISD4     /* TRIS for RS */ 
10
#define E_PIN LATDbits.LATD6         /* PORT for D */ 
11
#define TRIS_E TRISDbits.TRISD6      /* TRIS for E */
12
 
13
#define DATA_PORT PORTD /* PORT for Data */
14
#define TRIS_DATA_PORT TRISD /* TRIS for Data */
15
 
16
/*Start der Initialisierung*************/
17
TRIS_RW = 0;
18
TRIS_RS = 0;
19
TRIS_E = 0;
20
TRIS_DATA_PORT = 0;
21
 
22
/*INIT*/
23
Delay10KTCYx (6); // wait 24ms
24
DATA_PORT = 0x03;
25
E_PIN = 1;   // E-Leitung Pulsen lassen
26
Delay10TCYx (1);
27
E_PIN = 0 ;
28
 
29
Delay1KTCYx(13); // wait 5,2ms
30
DATA_PORT = 0x03;
31
E_PIN = 1;   // E-Leitung Pulsen lassen
32
Delay10TCYx (1);
33
E_PIN = 0 ;
34
 
35
Delay10TCYx(26); // wait 104us
36
DATA_PORT = 0x03;
37
E_PIN = 1;   // E-Leitung Pulsen lassen
38
Delay10TCYx (1);
39
E_PIN = 0 ;
40
 
41
/****4-BIT Initialisierung****/
42
DATA_PORT = 0x02;
43
E_PIN = 1;   // E-Leitung Pulsen lassen
44
Delay10TCYx(1);
45
E_PIN = 0 ;
46
Delay10KTCYx(6); // wait 24ms
47
 
48
DATA_PORT = 0x00;
49
Delay10KTCYx(30);
50
E_PIN = 1;   // E-Leitung Pulsen lassen
51
Delay10TCYx(1);
52
E_PIN = 0 ;
53
 
54
 
55
DATA_PORT = 0x02;
56
Delay10KTCYx(30);
57
E_PIN = 1;   // E-Leitung Pulsen lassen
58
Delay10TCYx(1);
59
E_PIN = 0 ;
60
 
61
DATA_PORT = 0x08;
62
Delay10KTCYx(30);
63
E_PIN = 1;   // E-Leitung Pulsen lassen
64
Delay10TCYx(1);
65
E_PIN = 0 ;
66
 
67
68
/***Function Set ***/
69
DATA_PORT = 0x00; // 0x0F Display on, Cursor on, Blinking
70
Delay10KTCYx(30);
71
E_PIN = 1;   // E-Leitung Pulsen lassen
72
Delay10TCYx(1);
73
E_PIN = 0 ;
74
 
75
DATA_PORT = 0x0F;
76
Delay10KTCYx(30);
77
E_PIN = 1;   // E-Leitung Pulsen lassen
78
Delay10TCYx(1);
79
E_PIN = 0 ;
80
 
81
82
}
Wenn ich dieses Programm auf den PIC lade, dann kann ich ganz schwach 
erkennen, wie die obere Zeile des LCD´s blinkt (die gesamte Zeile).
Eigentlich wollte ich aber nur einen blinkenden Cursor haben. Was hab 
ich da falsch gemacht?

von Sascha F. (sascha_focus) Benutzerseite


Lesenswert?

Hi,

deine main wird dauerhaft durchlaufen.
Es fehlt:
while(1)
{}

Gruß Sascha

von Kevin J. (noway)


Lesenswert?

Ja das hatte ich bereits versucht, allerdings ohne Erfolg, weswegen ich 
es aus dem Quelltext wieder entfernt hatte.

von Severino R. (severino)


Lesenswert?

Wo genau hattest Du es drin?

Ist der Watchdog ein- oder ausgeschaltet?

Kannst Du denn sonst z.B. eine Led auf dem PICDEM 2 Plus blinken lassen?

von Kevin J. (noway)


Lesenswert?

Die While-Schleife hatte ich am Ende eingefügt.
Ich kann auf dem Board ohne Probleme LED´s ansteuern. Ich hatte mit den 
LED´s experimentiert als ich mir die Delays.h mal zur Brust genommen 
hatte. Blinklichter waren kurz darauf keine Schwierigkeit.

Ich vermute, dass ich dem LCD in der Initialisierung die Bits falsch 
übermittle, aber ich komm´ einfach nicht dahinter.
Die Konfiguration, also Watchdog Timer etc. ist korrekt eingestellt (WDT 
aus etc.)
Muss man das LCD möglicherweise irgendwie seperat noch "einschalten"? 
Dem Schaltplan des PICDEM Boards entnahm ich, dass das LCD an RD7 seine 
Spannung bezieht. Das macht mich ehrlich gesagt etwas stutzig.

von Sascha F. (sascha_focus) Benutzerseite


Angehängte Dateien:

Lesenswert?

"Dem Schaltplan des PICDEM Boards entnahm ich, dass das LCD an RD7 seine
Spannung bezieht. Das macht mich ehrlich gesagt etwas stutzig."

Wo denn???? Ich sehe davon nichts. Siehe Anhang. Probiere doch zur Not 
mal die Application Maestro Software. Dort wird dir alles für das 
Display erzeugt.

Gruß Sascha

von Severino R. (severino)


Lesenswert?

Es gibt zwei Versionen des PICDEM 2 Plus:
Eine nicht-RoHS und eine RoHS-konforme.
Bei der RoHS-konformen ist das Display anders angeschlossen.
Du solltest das mal prüfen.

Sonst noch eine Idee:
Beim Hi-Tech C-Compiler PICC (für PIC16) sind Beispiele für die LCD 
Ansteuerung, auch auf dem PICDEM 2 Plus, dabei.
Die kannst Du wohl relativ einfach nach PIC18 portieren, oder schauen, 
ob die beim PIC18 Compiler auch dabei sind.
Beide Compiler gibt's in einer limitierten Version zum kostenlosen 
Download.
Du wirst verstehen, dass ich die Beispiel-Dateien aus 
Urheberrechtsgründen hier nicht posten kann.

von Severino R. (severino)


Lesenswert?

Sascha Focus wrote:
> "Dem Schaltplan des PICDEM Boards entnahm ich, dass das LCD an RD7 seine
> Spannung bezieht. Das macht mich ehrlich gesagt etwas stutzig."
>
> Wo denn???? Ich sehe davon nichts. Siehe Anhang.

Du hast den Schaltplan des "alten" Boards gepostet.
Beim neuen ist RD7 tatsächlich über einen NPN Transistor mit der 
Versorgungsspannung des LCD verbunden.

> Probiere doch zur Not
> mal die Application Maestro Software. Dort wird dir alles für das
> Display erzeugt.

Auch eine gute Idee.
In jedem Fall muss geprüft werden, ob es sich um eine "altes" oder neues 
Board handelt (E, R/W und RS anders angeschlossen).
Aber ich glaube nicht, dass der Application Maestro Code zum Einschalten 
von RD7 erzeugt.

von Kevin J. (noway)


Lesenswert?

So...aktueller Stand: Totale Verwirrung!
Ich habe jetzt diverse Belegungen gefunden und fühl mich etwas 
überfordert.
Mein Board ist rot und nennt sich PicDem 2 Plus Demo Board 2002. Wie ist 
denn nun die Belegung von exakt diesem Board? Ich finde scheinbar immer 
nur die von diesem grünen Board.

von Severino R. (severino)


Lesenswert?

Kevin J. wrote:
> So...aktueller Stand: Totale Verwirrung!
Ist ja super, dann kann's nur noch besser werden ;-)

> Ich habe jetzt diverse Belegungen gefunden und fühl mich etwas
> überfordert.
Welche denn? Link?

> Mein Board ist rot und nennt sich PicDem 2 Plus Demo Board 2002. Wie ist
> denn nun die Belegung von exakt diesem Board? Ich finde scheinbar immer
> nur die von diesem grünen Board.
Das dürfte das "alte" sein.
Hier alle Dokus:
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en010072&part=DM163022

von B. J. (bjue)


Lesenswert?

Könnte es was zu tun haben mit falsch gesetztem CMCON Register? Dort muß 
0x07 drinnen stehen. Ist normalerweise nach RESET richtig (also 0x07h), 
aber wird ja vielleicht überschrieben bei Dir. Siehe
http://www.mikroe.com/forum/viewtopic.php?p=78461
Trifft für P18F4620 auch zu.

von Kevin J. (noway)


Lesenswert?

Danke für den Link. Ich arbeite mich da mal durch ;)

Bzgl CMCON REGISTER:
hatte ich auch schon überlegt. Dies konnte ich aber ausschließen durch 
das testen der Ausgänge. Ich habe via Config Bits in MPLab die Ausgänge 
auf digitale Ein/Ausgänge geschaltet und mit einem kleinen Programm 
getestet (LEDs an/aus etc). Das hat soweit auch wunderbar geklappt, 
weswegen ich denke, dass dies nicht das Problem sein kann.


Eines ist mir bei der Simulation aufgefallen:
Die E-Leitung wird gepulst, allerdings nur im LAT Register. Ich hatte 
daraufhin versucht mir die notwendigen Informationen über LAT und PORT 
Register anzueignen, verstehe aber irgendwie immer noch nicht, in 
welchem Zusammenhang die beiden stehen. Durch ausprobieren hatte ich 
herausgefunden, das ich mit LAT Registern den PORT setzen kann (LED 
Test, wie üblich^^). Wieso bleibt das PORT Register dann leer, bzw 
unbeschrieben wenn ich mir das in der Simulation anschaue? Könnte da ein 
Zusammenhang bestehen, weswegen ich keinen Fortschritt erziele?

von Kevin J. (noway)


Lesenswert?

So ich habs hinbekommen. Was genau der Fehler jetzt war, kann ich nicht 
sagen. Aber ich habe jetzt die Pinbelegungen überprüft, die zu 
übermittelnden Nibble etc und das Timing noch einmal überarbeitet. Die 
Kommentare sollten stimmen. Das ganze sieht jetzt so aus:
1
#include <p18F4620.h>
2
#include <stdio.h>
3
4
void main(void)
5
6
{
7
#define E_PIN    LATAbits.LATA1    /* PORT for D  */ 
8
#define TRIS_E   TRISAbits.TRISA1  /* TRIS for E  */
9
10
#define RW_PIN PORTAbits.LATA2 /* PORT for RW */ 
11
#define TRIS_RW TRISAbits.TRISA2 /* TRIS for RW */ 
12
13
#define RS_PIN LATAbits.LATA3 /* PORT for RS */ 
14
#define TRIS_RS TRISAbits.TRISA3 /* TRIS for RS */ 
15
16
17
#define DATA_PORT PORTD /* PORT for Data */
18
#define TRIS_DATA_PORT TRISD /* TRIS for Data */
19
20
#define Delay1TCY() Nop() ;
21
22
23
/*Start der Initialisierung*************/
24
TRIS_RW = 0;
25
TRIS_RS = 0;
26
TRIS_E = 0;
27
TRIS_DATA_PORT = 0;
28
ADCON1 = 0x0F; //als digitale Ein und ausgänge schalten
29
30
31
32
  //Initialisierung des LCD-Displays
33
Delay10KTCYx (25); // wait 250ms nach dem Einschalten
34
35
  
36
  /*Schritt 1 : Zuerst das Obere Display initialisieren */ 
37
DATA_PORT = 0x03;  //Das ist nötig, weil Port D0..D3 => LCD_Display D4..D7
38
E_PIN = 1;   // E-Leitung Pulsen lassen
39
Delay1TCY();
40
E_PIN = 0 ;
41
42
43
  /*2. Schritt nochmal 0x30 senden*/
44
Delay1KTCYx(50); // wait 50ms
45
DATA_PORT = 0x03;
46
E_PIN = 1; // E-Leitung Pulsen lassen
47
Delay1TCY();
48
E_PIN = 0 ;
49
Delay1KTCYx(25); // wait 25ms
50
51
  // 3. Schritt nochmal 0x30 senden ohne Pause zwischen Schritt 2 und 3
52
Delay1KTCYx(25); // wait 25ms
53
DATA_PORT = 0x03;
54
E_PIN = 1; // E-Leitung Pulsen lassen
55
Delay1TCY();
56
E_PIN = 0 ;
57
Delay1KTCYx(25); // wait 25ms
58
59
/****4-BIT Initialisierung****/
60
//4. Schritt diesmal 0x20 senden, damit wird umgeschaltet in den 4 bit Modus
61
DATA_PORT = 0x02;
62
E_PIN = 1; // E-Leitung Pulsen lassen
63
Delay1TCY();
64
E_PIN = 0 ;
65
Delay1KTCYx(25); // wait 25ms
66
67
/*5. Schritt nun müssen alle Bytes in zwei Blöcken übertragen werden  
68
    zuerst das Obere Nibble dann das untere Nibble
69
    im simpel LCD-Initaialisierungs Programm sortiere ich die Nibbles selber
70
    möchte ich den Wert b'abcdefgh' übertragen dann schicke ich zuersz
71
    movlw B'0000abcd' und dann movlw b'0000efgh' 
72
    das ist zum ersten Verständnis hilfreich, und sollte später verbessert werden.
73
74
 zuerst muss der Befehl Function Set erfolgen. Hierzu das RS-Bit
75
 muss 0 sein, weil ein Systembyte übertragen wird Das ist es aber immer noch  denn  PORTA =0
76
 Das Byte für Systemset 0x28 function set, 4-bit  2-zeilig,  5x7 heißt
77
 B'00101000' also zuerst B'00000010'  und dann B'00001000' schicken
78
*/
79
Delay10KTCYx(10); // wait 100ms, pauschale Wartezeit ist einfacher als das Busyflag abzufragen
80
DATA_PORT = 0x02; 
81
82
E_PIN = 1; // E-Leitung Pulsen lassen
83
Delay1TCY();
84
E_PIN = 0 ;
85
86
Delay10KTCYx(10); // wait 100ms, pauschale Wartezeit ist einfacher als das Busyflag abzufragen
87
DATA_PORT = 0x08;
88
89
E_PIN = 1; // E-Leitung Pulsen lassen
90
Delay1TCY();
91
E_PIN = 0 ;
92
93
94
/*  so jetzt schalten wir mal das Display ein und lassen den Cursor Blinken.
95
 dazu brauchen wir den Befehl B'00001111'  ; 0xF display on, cursor on, cursor flash on
96
 wie oben zwerlegen in B'00000000'  und B'00001111'  !
97
*/
98
DATA_PORT = 0x00;
99
Delay10KTCYx(10); // wait 100ms, pauschale Wartezeit ist einfacher als das Busyflag abzufragen
100
E_PIN = 1; // E-Leitung Pulsen lassen
101
Delay1TCY();
102
E_PIN = 0 ;
103
104
105
DATA_PORT = 0x01;
106
Delay10KTCYx(10); // wait 100ms, pauschale Wartezeit ist einfacher als das Busyflag abzufragen
107
E_PIN = 1; // E-Leitung Pulsen lassen
108
Delay1TCY();
109
E_PIN = 0 ;
110
111
112
113
114
DATA_PORT = 0x00;
115
Delay10KTCYx(10); // wait 100ms, pauschale Wartezeit ist einfacher als das Busyflag abzufragen
116
E_PIN = 1; // E-Leitung Pulsen lassen
117
Delay1TCY();
118
E_PIN = 0 ;
119
120
121
DATA_PORT = 0x0F;
122
Delay10KTCYx(10); // wait 100ms, pauschale Wartezeit ist einfacher als das Busyflag abzufragen
123
E_PIN = 1; // E-Leitung Pulsen lassen
124
Delay1TCY();
125
E_PIN = 0 ;
126
127
/*
128
wenn wir jetzt hier stoppen würden mit den Befehl
129
dann müssste der Cursor des LCD_Displays jetzt blinken
130
Blinkt der Cursor ein der Ecke, dann ist das LCD richtig initialisiert und nun kann man darangehen es mit Text zu füttern
131
Neu ist jetzt, dass die RS-Leitung immer 1 sein muss, 
132
weil wir ab jetzt nicht mehr das LCD-Systembeeinflussen wollen sondern 
133
den Textspeicher.
134
*/
135
136
137
// Buchstaben H schreiben 
138
RS_PIN = 1;
139
140
141
142
DATA_PORT = 0x04;
143
Delay10KTCYx(10); // wait 100ms, pauschale Wartezeit ist einfacher als das Busyflag abzufragen
144
E_PIN = 1; // E-Leitung Pulsen lassen
145
Delay1TCY();
146
E_PIN = 0 ;
147
148
DATA_PORT = 0x08;
149
Delay10KTCYx(10); // wait 100ms, pauschale Wartezeit ist einfacher als das Busyflag abzufragen
150
E_PIN = 1; // E-Leitung Pulsen lassen
151
Delay1TCY();
152
E_PIN = 0 ;
153
154
155
156
157
RS_PIN = 0;
158
159
160
161
while(1);
162
{}
163
164
}

Das Display liefert mit diesem Wert ein großes H. Nicht mehr und nicht 
weniger. Ich werd mich jetzt dran setzen und damit etwas 
experimentieren.

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.