Forum: Mikrocontroller und Digitale Elektronik Problem Intialisierung LCD MSP430


von Johannes (Gast)


Lesenswert?

Ich habe ein Problem mit der Intialisierung eines LCD-Display mit
dem MSP430.
Ich möchte das Display im 4-Bit Modus betreiben, was bedeutet das zuerst
das High-Nibble und dann das Low-Nibble gesendet werden.
Ich habe die 3,6V an den Pins D5 und D4 anliegen (habe ich mit dem
Multimeter geprüft) und das Enable-Signal für das Display kommt auch 3
mal mit einer High-Flanken (schön auf dem Oszi zusehen). Die Zeit des
Enable-Pulses liegt bei 20ms und die Wartezeiten auf das Display werden
mit 250ms, 20ms und 30ms auch mehr als eingehalten.
Nur nach dem 3ten Enable-Puls ist immer noch die typische
unintialisierte Ansicht (obere Zeile an; untere Zeite aus) zu sehen.

Hat jemand eine Idee für mich?
Danke :)

von Silvan K. (silvan) Benutzerseite


Lesenswert?

Quellcode? Schaltplan?

Verwendest du die richtigen Datenleitungen (D7-D4)?

Hast du versucht das Display zu löschen?

Kontrast richtig eingestellt? (Foto)

von Johannes (Gast)


Lesenswert?

Ja ich verwende die Datenleitungen D4 bis D7 und habe auch den Kontrast 
richtig eingestellt, da ich ja die zwei verschieden Zeilen sehen kann.
Vcc und GND sowie die Kontrast und die Hintergrundbeleuchtung 
funktioniert alles einwandfrei.

P2.0 ---> RS
P2.1 ---> E
P2.2 ---> D4
P2.3 ---> D5
P2.4 ---> D6
P2.5 ---> D7

Löschen bringt auch nichts.
Aber eigentlich müsste das Display ja nach den 3 Pulsen ein anderes Bild 
z.B. ein Cursor bzw. kein Cursor anzeigen? Aber es tut sich einfach 
garnichts.

1
void LCD_Init(void)          // Initialisierung  
2
{
3
  LCD_OUT &= ~LCD_mask;            // Enable, RW und RS auf 0 und D4 - D7 = 0
4
  delay_ms(250);               // 250ms Delay
5
 
6
  LCD_OUT |= LCD_PIN_D5 + LCD_PIN_D4;    // Befehlssatz: Funktioen
7
  LCD_Clock(1);                       // befehl ausfuehren  
8
  delay_ms(250);              // warten
9
  
10
  LCD_Clock(1);                       // befehl ausfuehren  
11
  delay_ms(200);              // warten
12
  
13
  LCD_Clock(1);                       // befehl ausfuehren  
14
  delay_ms(30);                // warten
15
  
16
  LCD_OUT |= LCD_D5 
17
//      + LCD_D4;            // 0 = 4-Bit Interface; 1 = 8-Bit Interface
18
        ;
19
  LCD_Clock(1);                       // befehl ausfuehren  
20
  delay_ms(30);                // warten
21
//LCD_Clear();
22
23
//lcd_command(LCD_D2 + LCD_D1);         // Befehlssatz: Modus festlegen   --> Cursor inkrementieren(rechts)
24
//lcd_command(LCD_D3 + LCD_D2 + LCD_D1 );  // Befehlssatz: Display/Cursor --> Display an; Cursor an
25
//lcd_command(LCD_D4 + LCD_D2 );       // Befehlssatz: Cursor/Display schieben --> Cursor rechts schieben
26
//lcd_command(LCD_D5 + LCD_D3 );       // Befehlssatz: Funktionen --> 2/4 Zeilen, 
27
28
}

von holger (Gast)


Lesenswert?

>  LCD_OUT &= ~LCD_mask;            // Enable, RW und RS auf 0 und D4 - D7 = 0

Was ist LCD_MASK?
Wie sieht LCD_Clock(1) aus?

Sollen wir uns deinen Scheiss aus den Fingern saugen oder was?

von Johannes (Gast)


Lesenswert?

1
#ifndef LCDROUTINE_H_
2
#define LCDROUTINE_H_
3
4
/************************************************************
5
* definations test
6
************************************************************/
7
//LCD Port
8
9
#define LCD_DIR        P2DIR
10
#define LCD_OUT       P2OUT
11
12
13
#define LCD_D0      BIT0      // Befehlsatz D7
14
#define LCD_D1      BIT1      // Befehlsatz D4
15
#define LCD_D2      BIT2      // Befehlsatz D5
16
#define LCD_D3      BIT3      // Befehlsatz D6
17
#define LCD_D4      BIT4      // Befehlsatz D7
18
#define LCD_D5      BIT5      // Befehlsatz D4
19
#define LCD_D6      BIT6      // Befehlsatz D5
20
#define LCD_D7      BIT7      // Befehlsatz D6
21
22
23
//Ausgabe Pins
24
#define LCD_PIN_RS    BIT0      // Befehlsatz D4
25
#define LCD_PIN_E    BIT1      // Befehlsatz D5
26
#define LCD_PIN_D4    BIT2      // Befehlsatz D4
27
#define LCD_PIN_D5    BIT3      // Befehlsatz D5
28
#define LCD_PIN_D6    BIT4      // Befehlsatz D6
29
#define LCD_PIN_D7    BIT5      // Befehlsatz D7
30
31
32
33
34
35
/************************************************************
36
* declarations
37
************************************************************/
38
void delay_ms(unsigned int uint_delay);      // Verzögerung
39
void LCD_Clock(unsigned int loops);            // erzeugt ein Clock-Singal
40
void lcd_command(unsigned char uch_command); //sendet command
41
void LCD_Init(void);            // Initialisierung
42
void LCD_Clear(void);            // löscht das Display und setzt Cursor den Anfang zurück
43
void LCD_CursorHome(void);          // Cursor auf Startpostion 0    
44
void LCD_OutChar(char ch_data);  // gibt einen Character aus
45
void LCD_OutString( const char* c );    // gibt einen String aus
46
47
unsigned short ush_test_array = 0;
48
unsigned short i = 0;
49
50
/************************************************************
51
* functions
52
************************************************************/
53
54
void delay_ms(unsigned int uint_delay)
55
{
56
  while (uint_delay--)            // Loop für Delay 
57
  {
58
    __delay_cycles(1000);          // Delay Masterclock
59
  }
60
}
61
62
void LCD_Clock(unsigned int loops)            // erzeugt ein Clock-Singal
63
{
64
 while(loops--)
65
  {
66
    LCD_OUT &= ~LCD_PIN_E;                 // zuerst das clock-bit sicherheitshalber auf low
67
    delay_ms(20);               // 20ms Delay
68
    LCD_OUT |= LCD_PIN_E;                  // clock-bit auf high 
69
    delay_ms(20);               // 20ms Delay
70
    LCD_OUT &= ~LCD_PIN_E;                 // und jetzt wieder auf low
71
    delay_ms(20);               // 20ms Delay
72
  }  
73
}
74
75
void LCD_Init(void)          // Initialisierung  
76
{
77
  LCD_OUT &= ~LCD_mask;            // Enable, RW und RS auf 0 und D4 - D7 = 0
78
  delay_ms(250);               // 250ms Delay
79
 
80
  LCD_OUT |= LCD_PIN_D5 + LCD_PIN_D4;    // Befehlssatz: Funktioen
81
  LCD_Clock(1);                       // befehl ausfuehren  
82
  delay_ms(250);              // warten
83
  
84
  LCD_Clock(1);                       // befehl ausfuehren  
85
  delay_ms(200);              // warten
86
  
87
  LCD_Clock(1);                       // befehl ausfuehren  
88
  delay_ms(30);                // warten
89
  
90
  LCD_OUT |= LCD_D5 
91
//      + LCD_D4;            // 0 = 4-Bit Interface; 1 = 8-Bit Interface
92
        ;
93
  LCD_Clock(1);                       // befehl ausfuehren  
94
  delay_ms(30);                // warten
95
//LCD_Clear();
96
97
//lcd_command(LCD_D2 + LCD_D1);         // Befehlssatz: Modus festlegen   --> Cursor inkrementieren(rechts)
98
//lcd_command(LCD_D3 + LCD_D2 + LCD_D1 );  // Befehlssatz: Display/Cursor --> Display an; Cursor an
99
//lcd_command(LCD_D4 + LCD_D2 );       // Befehlssatz: Cursor/Display schieben --> Cursor rechts schieben
100
//lcd_command(LCD_D5 + LCD_D3 );       // Befehlssatz: Funktionen --> 2/4 Zeilen, 
101
102
}
103
104
void LCD_Clear(void)            // löscht das Display und setzt Cursor den Anfang zurück
105
{
106
  lcd_command(LCD_D0);              // clear display
107
  delay_ms(30);               // 30ms Delay
108
  LCD_CursorHome();                // setzt coursor auf home
109
}
110
111
void LCD_CursorHome(void)          // Setzt Cursor den Anfang zurück
112
{
113
  lcd_command(LCD_D1);              // Cursor Homeposition
114
  delay_ms(30);               // 30ms Delay
115
}
116
117
void LCD_OutChar(char ch_data)
118
{
119
  unsigned char uch_temp = ch_data;        // übergibt das byte
120
  LCD_OUT &= ~LCD_mask;            // Enable, RW und RS auf 0 und D4 - D7 = 0
121
  LCD_OUT |= LCD_PIN_RS;                  // Wählt Datenregister aus
122
        
123
  //High Nibble   
124
  LCD_OUT = (ch_data & 0xF0);          // 4 Bits inkrementieren und maskieren und anschließen high nibble ausgeben
125
  LCD_Clock(1);                         // Clock signal
126
  //Low Nibble
127
  LCD_OUT = ((uch_temp << 4) & 0xF0);       // unteres nibble maskieren und ausgeben
128
  LCD_Clock(1);                         // Clock singal
129
}
130
131
void lcd_command(unsigned char uch_command)
132
{
133
  unsigned char uch_temp = uch_command;    // übergibt das byte
134
  LCD_OUT &= ~LCD_mask;            // Enable, RW und RS auf 0 und D4 - D7 = 0
135
  LCD_OUT &= ~LCD_PIN_RS;          // wählt Steuerbefehl aus
136
     
137
  //High Nibble   
138
  P1OUT = (uch_command & 0xF0);          // 4 Bits inkrementieren und maskieren und anschließen high nibble ausgeben
139
  LCD_Clock(1);                        // Clock signal
140
  //Low Nibble
141
  P1OUT = ((uch_temp << 4) & 0xF0);         // unteres nibble maskieren und ausgeben
142
  LCD_Clock(1);                         // Clock singal
143
}
144
145
void LCD_OutString( const char *c )      // gibt einen String aus
146
{
147
   while( *c != '\0' )
148
   {
149
      LCD_OutChar( *c++ );
150
   }
151
}
152
153
154
155
#endif /*LCDROUTINE_H_*/

Nein sry sollst du nicht, tut mir leid!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Johannes bezieht sich vermutlich auf diesen Thread hier:
Beitrag "LCD wird nicht initialisiert - MSP430"

von holger (Gast)


Lesenswert?

#define LCD_OUT       P2OUT
LCD_OUT &= ~LCD_mask;            // Enable, RW und RS auf 0 und D4 - D7 
= 0

P1OUT = (uch_command & 0xF0);          // 4 Bits inkrementieren und

Was denn nun P1 oder P2?

von Johannes (Gast)


Lesenswert?

ja das ist teileweise richtig ich bin mit Peter zusammen in der 
Ausbildung und jetzt soll ich an diesem Projekt weitermachen...nur 
irgendwie klappt das nicht wirklich :(

von Johannes (Gast)


Lesenswert?

holger schrieb:
> #define LCD_OUT       P2OUT
> LCD_OUT &= ~LCD_mask;            // Enable, RW und RS auf 0 und D4 - D7
> = 0
>
> P1OUT = (uch_command & 0xF0);          // 4 Bits inkrementieren und
>
> Was denn nun P1 oder P2?

Ja P2OUT ist der richtige aber an dem kann es ja leider nicht liegen :(

von holger (Gast)


Lesenswert?

>Ja P2OUT ist der richtige aber an dem kann es ja leider nicht liegen :(

Und wieso kommt dann P1OUT in deinem Sourcecode vor?

von Johannes (Gast)


Lesenswert?

weil wir zuvor im 8-Bit-Mode alle 8 Datenleitungen an P1OUT hatte und 
dies anscheinend beim ändern übersehen haben. Soweit bin ich aber ja 
noch gar nicht gekommen, sonst wäre mir das vielleicht auch aufgefallen, 
aber danke :)

Nur das eigentliche Problem ist leider damit immer noch nicht gelöst :(

von holger (Gast)


Lesenswert?

>Nur das eigentliche Problem ist leider damit immer noch nicht gelöst :(

Du hast die Initialisierung ja auch nicht bis zum Ende gemacht.
Display Reset und Interface auf 4Bit stellen reicht nicht.

von holger (Gast)


Lesenswert?

>Du hast die Initialisierung ja auch nicht bis zum Ende gemacht.
>Display Reset und Interface auf 4Bit stellen reicht nicht.

Falschmeldung von mir. Habs grad mal mit einem ATMega32
und einem 2x40 Display ausprobiert. Es reicht. Da wo du aufhörst
müsste der Balken in der ersten Zeile weg sein.

Dann hast du dein Display wohl falsch angeschlossen.
Wo ist eigentlich der RW Pin angeschlossen?

Foto von der Hardware machen könnte noch helfen.

Ansonsten bin zumindest ich hier jetzt am Ende.

von Johannes (Gast)


Lesenswert?

Den RW-Pin habe ich auf GND geschlossen, da ich nur Schreib-Zugriffe 
mache und mir somit einen I/O am µC sparen kann.

Ich habe eigentlich alles schon zweimal kotnrolliert und nach meiner 
Meinung hat alles seine Richtigkeit.
Ich habe ja auch die 3 Puls am Enable mit dem Oszi gesehen.

von Johannes (Gast)


Lesenswert?

während an D5 und D5 3,6 anlagen. Soviel anderes kann ja dann nicht mehr 
falsch sein.

Danke für deine Mühe

von holger (Gast)


Lesenswert?

>Den RW-Pin habe ich auf GND geschlossen, da ich nur Schreib-Zugriffe
>mache und mir somit einen I/O am µC sparen kann.

Das ist ok. Mach ich auch immer so.

von holger (Gast)


Lesenswert?

>Ich habe ja auch die 3 Puls am Enable mit dem Oszi gesehen.

Laut deinem Code müssten es aber 4 sein;)

von Johannes (Gast)


Lesenswert?

ja da hast du recht aber ich hab den Break bei nach dem 3. Puls gemacht, 
umzusehen ob D4 auch wirklich auf 0V geht.

von Johannes (Gast)


Angehängte Dateien:

Lesenswert?

Das ist das Ozilogramm des ersten Teiles der init-Funktion:
1
void LCD_Init(void)          // Initialisierung  
2
{
3
  LCD_OUT &= ~LCD_mask;            // Enable, RW und RS auf 0 und D4 - D7 = 0
4
  delay_ms(250);               // 250ms Delay
5
 
6
  LCD_OUT |= LCD_PIN_D5 + LCD_PIN_D4;    // Befehlssatz: Funktioen
7
  LCD_Clock(1);                       // befehl ausfuehren  
8
  delay_ms(250);              // warten
9
  
10
  LCD_Clock(1);                       // befehl ausfuehren  
11
  delay_ms(200);              // warten
12
  
13
  LCD_Clock(1);                       // befehl ausfuehren  
14
  delay_ms(30);                // warten
15
  
16
  LCD_OUT |= LCD_D5 
17
//      + LCD_D4;            // 0 = 4-Bit Interface; 1 = 8-Bit Interface
18
        ;
19
  LCD_Clock(1);                       // befehl ausfuehren  
20
  delay_ms(30);                // warten
21
22
...

CH1 --> enable
CH2 --> D4
CH3 --> D5

in diesem Bereich muss ja irgendwo der Fehler liegen, sonst würde das 
Display ja nicht mehr die "bitte inizialisier mich" Anzeige anzeigen.
Hat keine eine Idee mehr?

von Johannes (Gast)


Angehängte Dateien:

Lesenswert?

So ich habe das Problem gefunden, der Kontrast war falsch eingestellt 
und weil das Display auf Grund eines anderen Fehlers (den ich noch 
suchen muss) nur die erste Zeile initialisiert hat sich da einfach keine 
Änderung zu erkennen geben.
Danke für eure Hilfe :)

von holger (Gast)


Lesenswert?

LCD_OUT |= LCD_PIN_D5 + LCD_PIN_D4;    // Befehlssatz: Funktioen
 ........
  LCD_OUT |= LCD_D5

Bei der letzten Zeile musst du D4 erst noch löschen.
Sprich: Du bist immer noch im 8Bit Modus.

von holger (Gast)


Lesenswert?

>LCD_OUT |= LCD_PIN_D5 + LCD_PIN_D4;    // Befehlssatz: Funktioen
> ........
>  LCD_OUT |= LCD_D5
>
>Bei der letzten Zeile musst du D4 erst noch löschen.
>Sprich: Du bist immer noch im 8Bit Modus.

Laut Bild vom Osci sollte es passen. D4 geht auf Null vor dem
vierten E Clock. Dann solltest du auch im 4 Bit Mode sein.

Allerdings hast du uns dann den falschen Code gezeigt.
Bei dem würde D4 nicht einfach mal so auf Null gehen.

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.