Problem Intialisierung LCD MSP430

Gast #2926803
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 :)
Gast #2926844
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
}
Gast #2926885
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!
Gast #2926925
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 :(
Gast #2926958
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 :(
Gast #2927047
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.
Gast #2927062
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.
Gast #2927700
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?
Angehängte Dateien:
Gast #2927754
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 :)
Angehängte Dateien:
Gast #2928410
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.

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