Forum: Mikrocontroller und Digitale Elektronik LCD wird nicht initialisiert - MSP430


von Peter Hoffsteter (Gast)


Lesenswert?

Hallo zusammen,

ich versuche vergeblich ein LCD mit dem HD44780 anzusteuern.
Das hat im 8-Bit Modus auch super geklappt, nur seit dem ich (alles) auf 
den 4-Bit Modus umgestellt wollte/hab, geht leider nichts mehr :-(

Ich hab die Zeiten vervielfacht damit ich ein Zeitproblem des LCD 
ausschließen kann.

Meine LCD-Routinen sind wie folgend auf gebaut:
1
#ifndef LCDROUTINE_H_
2
#define LCDROUTINE_H_
3
4
/************************************************************
5
* definations
6
************************************************************/
7
//Port1
8
#define LCD_D0    (0x01)      // Befehlsatz D0
9
#define LCD_D1    (0x02)      // Befehlsatz D1
10
#define LCD_D2    (0x04)      // Befehlsatz D2
11
#define LCD_D3    (0x08)      // Befehlsatz D3
12
#define LCD_D4    (0x10)      // Befehlsatz D4
13
#define LCD_D5    (0x20)      // Befehlsatz D5
14
#define LCD_D6    (0x40)      // Befehlsatz D6
15
#define LCD_D7    (0x80)      // Befehlsatz D7
16
17
//Port2
18
#define LCD_RS      (0x01)      // RS --> selects register 0: Instruction register (write) 1: Data register ( write & read)
19
#define LCD_RW      (0x02)      // R/W --> selects read or write
20
#define LCD_E       (0x04)      // E --> Starts data read/write.
21
22
23
/************************************************************
24
* declarations
25
************************************************************/
26
27
void delay_50us(unsigned int delay);    // Delay 50µs
28
void LCD_Clock(void);            // erzeugt ein Clock-Singal
29
void lcd_command(unsigned char uch_command); //sendet command
30
void LCD_Init(void);            // Initialisierung
31
void LCD_Clear(void);            // löscht das Display und setzt Cursor den Anfang zurück
32
void LCD_CursorHome(void);          // Cursor auf Startpostion 0    
33
void LCD_OutChar(unsigned char uch_data);  // gibt einen Character aus
34
void LCD_OutString( const char* c );    // gibt einen String aus
35
36
unsigned short ush_test_array = 0;
37
unsigned short i = 0;
38
39
/************************************************************
40
* functions
41
************************************************************/
42
43
void delay_50us(unsigned int uint_delay)
44
{
45
    while (uint_delay--)          // Loop für Delay 
46
    {
47
      __delay_cycles(5000);          // Delay 50*Masterclock
48
    }
49
}
50
51
void LCD_Clock(void)            // erzeugt ein Clock-Singal
52
{
53
  delay_50us(4);               // 200µs Delay
54
  P2OUT &= ~LCD_E;                   // zuerst das clock-bit sicherheitshalber auf low
55
  delay_50us(4);               // 200µs Delay
56
  P2OUT |= LCD_E;                    // clock-bit auf high 
57
  delay_50us(4);               // 200µs Delay
58
  P2OUT &= ~LCD_E;                   // und jetzt wieder auf low
59
  delay_50us(4);               // 200µs Delay
60
}
61
62
void LCD_Init(void)        //// Initialisierung  
63
{
64
 P2OUT = 0;                  // Enable, RW und RS auf 0
65
 delay_50us(500);               // 2500µs Delay
66
 
67
 P1OUT = LCD_D5               // Befehlssatz: Funktioen
68
  //  + LCD_D4              //  1 --> 8-Bit Interface; 0 --> 4-Bit Interface
69
      ;
70
 //for ( i = 0; i < 2; i++ )
71
//  {
72
    LCD_Clock();                     // befehl ausfuehren  
73
    delay_50us(500);             // 2500µs Delay
74
     LCD_Clock();                   // befehl ausfuehren  
75
    delay_50us(500);             // 2500µs Delay
76
//  }
77
    
78
  lcd_command(LCD_D5 + LCD_D3 );       // Befehlssatz: Funktionen --> 2/4 Zeilen, 
79
  lcd_command(LCD_D4 + LCD_D2 );       // Befehlssatz: Cursor/Display schieben --> Cursor rechts schieben
80
  lcd_command(LCD_D3 + LCD_D2);       // Befehlssatz: Display/Cursor --> Display an
81
  lcd_command(LCD_D2 + LCD_D1);         // Befehlssatz: Modus festlegen   --> Cursor inkrementieren(rechts)
82
  LCD_Clear();
83
}
84
85
void LCD_Clear(void)            // löscht das Display und setzt Cursor den Anfang zurück
86
{
87
  lcd_command(LCD_D0);              // clear display
88
  delay_50us(50);               // 2500µs Delay
89
  
90
  lcd_command(LCD_D1);              // Cursor Homeposition
91
  delay_50us(50);               // 2500µs Delay
92
}
93
94
void LCD_CursorHome(void)          // löscht das Display und setzt Cursor den Anfang zurück
95
{
96
  lcd_command(LCD_D1);              // Cursor Homeposition
97
  delay_50us(50);               // 2500µs Delay
98
}
99
100
void LCD_OutChar(unsigned char uch_data)
101
{
102
   unsigned char uch_byte = uch_data;      // übergibt das byte
103
   P2OUT = LCD_RS;               // Wählt Datenregister aus
104
   
105
   //High Nibble   
106
   P1OUT = (uch_byte >> 4) & 0x0F;      // 4 Bits inkrementieren und maskieren und anschließen high nibble ausgeben
107
   LCD_Clock();                 // Clock signal
108
    //Low Nibble
109
   P1OUT = (uch_byte & 0x0F);          // unteres nibble maskieren und ausgeben
110
   LCD_Clock();                 // Clock singal
111
}
112
113
void lcd_command(unsigned char uch_command)
114
{
115
   unsigned char uch_byte = uch_command;    // übergibt das byte
116
   P2OUT = 0;                  // Wählt Datenregister aus
117
      
118
   //High Nibble   
119
   P1OUT = (uch_byte >> 4) & 0x0F;      // 4 Bits inkrementieren und maskieren und anschließen high nibble ausgeben
120
   LCD_Clock();                 // Clock signal
121
    //Low Nibble
122
   P1OUT = (uch_byte & 0x0F);          // unteres nibble maskieren und ausgeben
123
   LCD_Clock();                 // Clock singal
124
}
125
126
void LCD_OutString( const char *c )        // gibt einen String aus
127
{
128
    while( *c != '\0' )
129
    {
130
           LCD_OutChar( *c++ );
131
    }
132
}
133
134
135
136
#endif /*LCDROUTINE_H_*/

und meine Hauptprogramm so:
1
#include <msp430g2232.h>
2
#include "lcdroutine.h"
3
4
5
6
/************************************************************
7
* declarations
8
************************************************************/
9
10
void Init_MSP(void);        // Initialisierung MSP430
11
12
unsigned short    str;
13
14
15
/************************************************************
16
* main
17
************************************************************/
18
19
int main(void)
20
{
21
  Init_MSP();            // Initialisierung MSP                 
22
  LCD_Init();                    // Initialisierung LCD 
23
  LCD_Clear();                   // löscht Display und cursor an den anfang zurueck
24
  
25
  LCD_OutString("Jonas Enderlin");   //Ausgabe
26
  
27
  while(1);              // Loop
28
}
29
30
/************************************************************
31
* functions
32
************************************************************/
33
34
void Init_MSP(void)          // Initialisierung MSP430
35
{
36
  
37
  //Watchdog
38
  WDTCTL = WDTPW + WDTHOLD;      // watchdog off
39
  
40
  //Clock
41
  BCSCTL3 |= LFXT1S_0;        // waehlt Quarz (32768Hz) als LFXTCLK aus
42
  BCSCTL1 &= ~XTS;          // wählt LFXTCLK low freqency aus
43
  BCSCTL1 |= XT2OFF          // XT2 is off
44
       + DIVA_0;        // ACLK = LFXTCLK/1 (Divder 1) = 32768Hz
45
  
46
  if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                     
47
  {  
48
     while(1);               // If calibration constants erased
49
                     // do not load, trap CPU!!
50
  }  
51
   
52
  BCSCTL1 = CALBC1_1MHZ;          // Set range to 1MHz
53
  DCOCTL = CALDCO_1MHZ;        // Set DCO step + modulation
54
        
55
  BCSCTL2 |=SELM_0 + DIVM_0;       //MCLK = DCO/1 = 1MHz
56
//BCSCTL2 |=DIVS_0;          //SMLK Divider 1 
57
  BCSCTL2 &= ~SELS;          //SMCLK = DCO/1 = 1MHz
58
  
59
  //Ports
60
  P1DIR = 0xFF;                 // Port1 = OUTPUT (8 datenleitungen zum LCD)
61
  P2DIR = 0xFF;                 // Port2 = OUTPUT (RS --> P2.0; R/W --> P2.1; E --> P2.2)
62
  
63
  P1SEL = 0x00;            
64
  P2SEL = 0x00;            // all ports are GPIO
65
  
66
  P1IE = 0x00;                  
67
  P2IE = 0x00;            // interrupt disable
68
  
69
  P1OUT = 0x00;                 
70
  P2OUT = 0x00;            // all Pins are low
71
   
72
}

Danke für euch Hilfe im vorraus :-)

netter Gruß
Peter

von J.-u. G. (juwe)


Lesenswert?

Ich kenne mich mit dem MSP430 überhaupt nicht aus. Aber 4-Bit-Modus beim 
HD44780 bedeutet, dass die Datenleitungen 0-3 des LCD inaktiv sind, und 
die Nibble an das LCD über die Datenleitungen 4-7 ausgegeben werden 
müssen.

Wenn das LCD im 8-Bit_Modus funktioniert hat und Du bei der Umstellung 
vom 8-Bit-Modus in den 4-Bit-Modus Dein Layout nicht geändert hast, 
werden die Funktionen LCD_OutChar und lcd_command so nicht 
funktionieren.

Das High Nibble müsste, nach meinem Verständnis, mittels:
P1OUT = uch_byte & 0xF0;

und das Low Nibble mittels:
P1OUT = (uch_byte << 4) & 0xF0;

ausgegeben werden.

von Peter Hoffsteter (Gast)


Lesenswert?

Ich habe den Steuerungs- und Datensendebefehl wie folgt geändert:

1
void LCD_OutChar(unsigned char uch_data)
2
{
3
   unsigned char uch_temp_1 = uch_data;    // übergibt das byte
4
   unsigned char uch_temp_2 = uch_data;    // übergibt das byte
5
   P2OUT = 0;                  // Wählt Datenregister aus
6
      
7
   //High Nibble   
8
   P1OUT |= (uch_temp_1 & 0xF0);      // 4 Bits inkrementieren und maskieren und anschließen high nibble ausgeben
9
   LCD_Clock();                 // Clock signal
10
    //Low Nibble
11
   P1OUT |= ((uch_temp_2 << 4) & 0xF0);          // unteres nibble maskieren und ausgeben
12
   LCD_Clock();                 // Clock singal
13
}
14
15
void lcd_command(unsigned char uch_command)
16
{
17
   unsigned char uch_temp_1 = uch_command;    // übergibt das byte
18
   unsigned char uch_temp_2 = uch_command;    // übergibt das byte
19
   P2OUT = 0;                  // Wählt Datenregister aus
20
      
21
   //High Nibble   
22
   P1OUT |= (uch_temp_1 & 0xF0);      // 4 Bits inkrementieren und maskieren und anschließen high nibble ausgeben
23
   LCD_Clock();                 // Clock signal
24
    //Low Nibble
25
   P1OUT |= ((uch_temp_2 << 4) & 0xF0);          // unteres nibble maskieren und ausgeben
26
   LCD_Clock();                 // Clock singal
27
}

wenn ich mir jetzt aber während des Programmablaufs uch_temp_1 in einer 
Watch Expression anschaue, steht immer nur in der Werte-Zeile 
"identifier not found: uch_temp_1". Das heißt doch das irgendwas in der 
Bezeichnung falsch gemacht habe?
Das kann aber irgendwie nicht sein, da ich uch_temp_2 kopiert habe und 
das ja alles funktioniert.

Weiß jemand die Lösung?

Danke im Vorraus!

netter Gruß
Peter

von holger (Gast)


Lesenswert?

>wenn ich mir jetzt aber während des Programmablaufs uch_temp_1 in einer
>Watch Expression anschaue, steht immer nur in der Werte-Zeile
>"identifier not found: uch_temp_1". Das heißt doch das irgendwas in der
>Bezeichnung falsch gemacht habe?

Wurde wahrscheinlich vom Compiler rausgeworfen.
Debuggen immer ohne Optimierung.

von Johannes (Gast)


Lesenswert?

Ich habe auch 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 Roland (Gast)


Lesenswert?

Die Initialisierung der 44780 (kompatiblen) hat wimre den einen oder 
anderen netten Fallstrick:
1. Bis man dem Display erzählt hat, dass es 4-BIT Anbindung hat, muss 
man es "normal" 8-Bit ansprechen.
2. Die Reihenfolge (nach Toshiba-Waschzettel) sollte man tunlichst 
einhalten.

Wimre waren die ersten 3 oder 4 Steuerkommandos ans Display normal wie 
8Bit rauszuschicken, und erst wenn die Konfig dem Display erzählt hat, 
dass da nur 4 Bit sind, ging es auch mit 4Bit weiter...

von THC_SIDO (Gast)


Lesenswert?

Mein Tip: Datenblatt des HD44780 lesen und verstehen!

Außerdem: http://www.geocities.com/dinceraydin/djlcdsim/djlcdsim.html

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.