Forum: Mikrocontroller und Digitale Elektronik lcd display zeigt nur schwarze kästchen


von Johannes (Gast)


Lesenswert?

Hallo
ich habe ein dsPICDEM 2 Board mit einem dsPIC30F4011 drauf. Damit möchte 
ich ein externes LCD-display ansteuern. Dies bereitet mir jedoch einige 
Probleme.
Den Code habe ich von
https://www.pantechsolutions.net/microcontroller-boards/lcd-interfacing-with-dspic-primer
und auf meine pins angepasst.
In der Funktion configure_pin() werden die Pins auf digital und ausgang 
gesetzt.
Da ich als Datenleitung RE0-RE3 benutze, habe ich bei der 
DATA-generierung hinten noch >>4 drangehängt.
1
#include <p30fxxxx.h>
2
#include "system.h"
3
#include <stdio.h>
4
5
_FOSC(CSW_FSCM_OFF & XT_PLL8);  //Run this project using an external crystal routed via the PLL in 8x multiplier mode
6
_FWDT(WDT_OFF);                 //Turn off the Watch-Dog Timer.
7
_FBORPOR(MCLR_EN & PWRT_OFF);   //Enable MCLR reset pin and turn off the power-up timers.
8
_FGS(CODE_PROT_OFF);            //Disable Code Protection
9
10
#define RS   LATBbits.LATB2
11
#define EN   LATBbits.LATB4
12
#define DATA LATE
13
14
void lcd_init(void);
15
void lcd_command(unsigned char);
16
void lcd_data(unsigned char);
17
18
void Delay5ms(unsigned int a);
19
void Delay5us(unsigned int a);
20
21
unsigned char text[8] = "Johannes";
22
unsigned int i;
23
24
25
int main (void)
26
{
27
    configure_pin();
28
    lcd_init();
29
    while (1) {
30
        lcd_command(0x01);
31
        Delay5ms(200);
32
        lcd_command(0x80);
33
        for( i=0; text[i]!='\0'; i++)
34
        {
35
            lcd_data(text[i]);
36
            Delay5ms(500);
37
        }
38
39
   }
40
    return 0;
41
}
42
43
void lcd_init()
44
{
45
    lcd_command(0x33);
46
    lcd_command(0x32);
47
    lcd_command(0x28);
48
    lcd_command(0x0C);
49
    lcd_command(0x06);
50
    lcd_command(0x01);
51
}
52
53
void lcd_command(unsigned char cmd)
54
{
55
    RS = 0;
56
57
    DATA = (cmd & 0xF0)>>4;
58
    EN = 1;
59
    EN = 0;
60
61
    DATA = ((cmd << 4) & 0xF0)>>4;
62
    EN = 1;
63
    EN = 0;
64
65
    Delay5ms(4);
66
}
67
68
void lcd_data(unsigned char data)
69
{
70
    RS = 1;
71
    
72
    DATA = (data & 0xF0)>>4;
73
    EN = 1;
74
    EN = 0;
75
76
    DATA = ((data << 4) & 0xF0)>>4;
77
    EN = 1;
78
    EN = 0;
79
80
    Delay5ms(4);
81
}
82
83
void Delay5ms(unsigned int a)//when a= 1, delay ca. 5ms
84
{
85
    unsigned int i;
86
    unsigned int j;
87
    for (j = 0; j < 20; j++)
88
        for (i = 0; i < 500 * a; i++);
89
}
90
91
void Delay5us(unsigned int a)//when a= 1, delay ca. 5us
92
{
93
    unsigned int i;
94
    unsigned int j;
95
    for (j = 0; j < 2; j++)
96
        for (i = 0; i < 5 * a; i++);
97
}

Auf meinem Display ist allerdings nur die erste Zeile mit schwarzen 
Kästchen gefüllt. ist da noch ein Fehler im Code? oder liegt es an der 
Verbindung?

Display (pin) -> Board
GND(1) -> GND
Vdd(2) -> Vdd
Vo (3) -> GND
RS (4) -> RB2
R/W(5) -> GND
E  (6) -> RB4
DB0-DB3 (7-10) -> GND
DB4-DB7 (11-14) -> RE0-RE3
LED+/LED- nicht verbunden


Johannes

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Johannes schrieb:
>  Damit möchte ich ein externes LCD-display ansteuern.
Welches denn? Es gibt mehrere...

> Auf meinem Display ist allerdings nur die erste Zeile mit schwarzen
> Kästchen gefüllt. ist da noch ein Fehler im Code? oder liegt es an der
> Verbindung?
An dieser Stelle wäre ein Oszilloskop oder ein Logikanalyzer Gold wert. 
Hast du sowas?

> Vo (3) -> GND
Das ist die Spannung zur Kontrasteinstellung. Weniger mutige 
Zeitgenossen machen da ein Poti hin, schließen das zwischen Vcc und GND 
an und gehe mit dem Schleifer auf Vo...

: Bearbeitet durch Moderator
von Old P. (Gast)


Lesenswert?

Mit Deinem Code kann ich zw nix anfangsn (ich kann kein C), doch 
schwarze Kästchen bedeuten, das Display ist jungfräulich und nicht 
initialisiert. Die zeigt es auch, wenn Du nur Spannung ans Display 
legst.

Verdrahtung oder Code ist gaga.

Old-Papa

von Teo D. (teoderix)


Lesenswert?

Du hast das falsche Display!
Du musst Baureihe 42 benutzen.

Na mal im Ernst.
Nach dem anlegen der Stromversorgung, braucht DAS(?) LCD 15mS, um wach 
zu werden. Das seh ich nirgends.

von Johannes (Gast)


Lesenswert?

Das display ist ein LCD-MODUL 16x2 illuminated von Reichelt. Ich habe 
gedacht, dass das so ein standard-Display ist und habe es deswegen oben 
vergessen zu erwähnen.
Auch mit einer langen pause vor lcd_init() werden mir nur schwarze 
kästchen angezeigt.
Habe eine eigene Funktion geschrieben, mit der ich das display löschen 
möchte. Laut Datenblatt muss (L=Low; H=High)
RS->L
R/W->L
DB7-DB1->L
DB0->H
1
int main(void)
2
{
3
  configure_pin();
4
  Delay5ms(10);
5
  lcd_init();
6
  Delay5ms(10);
7
  while(1)
8
  {
9
    lcd_clear();
10
  }
11
  return 0;
12
}
13
14
15
void lcd_clear()
16
{
17
    RS = 0;
18
    DATA = 0x00;
19
    EN = 1;
20
    EN = 0;
21
    
22
    DATA = 0x00;
23
    EN = 1;
24
    EN = 0;
25
    Delay5ms(10);
26
}

aber auch das bring keine besserung

von DJ T. (Gast)


Lesenswert?

1. Verdacht:
Funktionieren die Delay-Loops oder werden die vom Compiler wegoptimiert?

2. Verdacht:
Du hast einen 4-Bit-Port, richtig?
Du mußt zur Initialisierung 0x3 senden, 5ms warten, und dann nochmal 0x3 
senden. Du schickst aber zweimal 0x3 direkt hintereinander (ohne Pause).

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Johannes schrieb:
> aber auch das bring keine besserung
Es sind eben nicht alle Displays gleich. Besonders nicht, was den Vo 
Anschluss angeht. Und die Frage nach den Messgeräten ist irgendwie auch 
noch offen...

> Habe eine eigene Funktion geschrieben, mit der ich das display löschen
> möchte. Laut Datenblatt muss (L=Low; H=High)
> RS->L
> R/W->L
> DB7-DB1->L
> aber auch das bring keine besserung
Vorher muss das Display erst mal korrekt initialisiert sein. Sonst 
laufen alle Kommandos ins Leere...

von Teo D. (teoderix)


Lesenswert?

So weit ich mich erinnere, braucht man 8Schritte um so ein LCD mit 
4DatenBits zu initialisieren. Bei Dir seh ich nur 6.

von Blinky (Gast)


Lesenswert?

Ok, ist für AVR aber ansonsten beschreibt es die Ansteuerung eines LCD 
sehr schön:
https://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Teo Derix schrieb:
> So weit ich mich erinnere, braucht man 8Schritte um so ein LCD mit
> 4DatenBits zu initialisieren. Bei Dir seh ich nur 6.
Naja, die ersten 4 sind zusammengepackt und werden ohne vernünftige 
Zeiten blitzartig nacheinander abgearbeitet:
1
    lcd_command(0x33);
2
    lcd_command(0x32);
Das müsste eigentlich sein
warte 150ms
sende 3
warte 10ms
sende 3
warte 10ms
sende 3
warte 10ms
sende 2
warte 10ms
:
:

: Bearbeitet durch Moderator
von Johannes (Gast)


Lesenswert?

Laut meinem Datenblatt werden 7 schritte benötigt und ich bin dabei, 
jeden einezlnen schritt alleine auszuführen (mit den pausen)
Aber es ist doch so, dass beim ersten mal senden von DATA DB7-DB4 
gesendet werden und beim zweiten mal DB3-DB0 oder?
jetzt steht ja z.B. beim ersten Initialisierungs-Schritt
DB7=0
DB6=0
DB5=1
DB4=1
DB3-DB0=*

DB3-DB0 werden ja in den letzteren schritten ebenfalls benutzt.
Aber was erwartet er bei den sternchen?
hnten wird ja z.B:
DB3 = N
DB2 = F
DB1, DB0 = *

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Johannes schrieb:
> Aber was erwartet er bei den sternchen?
Gar nichts. Es ist "ihm" egal...

> Aber es ist doch so, dass beim ersten mal senden von DATA DB7-DB4
> gesendet werden und beim zweiten mal DB3-DB0 oder?
Schon, aber es wird dazwischen nicht gewartet...

von DJ T. (Gast)


Lesenswert?

Johannes schrieb:
> Laut meinem Datenblatt werden 7 schritte benötigt und ich bin dabei,
> jeden einezlnen schritt alleine auszuführen (mit den pausen)
> Aber es ist doch so, dass beim ersten mal senden von DATA DB7-DB4
> gesendet werden und beim zweiten mal DB3-DB0 oder?

Nach der Initialisierung schon, aber während der Initialisierung ist das 
etwas anders. Das LCD weiß zu Beginn nicht, wieviele Datenleitungen Du 
angeschlossen hast, sondern Du musst ihm das ja erst mitteilen.

Die 0x33 0x32 mußt Du also also als 0x3 0x3 0x3 0x2 schicken und jeweils 
die Pausenzeiten einhalten.

PS: Bitte denk daran, dass die Kommandos unterschiedliche Pausenzeiten 
haben. Ein DisplayClear braucht länger als ein DisplayOn.

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.