MSP430 und LCD

Gast #3702110
Lesenswert?

Hallo Forum,

ich benutze einen MSP430 F2410 und möchte das folgende Display 
ansteuern: LCD 204B BL

In der Wikipedia steht das der MSP430 (welches Derivat aber leider 
nicht) 4 backplanes für die Ansteuerung von LCDs hätte. Im UserGuide 
ahbe ich dazu leider nicht gefunden. (Oder überlesen, sind ja immerhin 
über 600 Seiten).

Hat das schonmal jemand versucht und kann mir dazu einen Link/ 
Webresource geben?

Vielen Dank
-mwstui
Gast #3702135
Lesenswert?

spess53 schrieb:
> Wenn das ein Display mit eingebautem Controller ist, dann sind mögliche
> Backplanes des MSP uninteressant.

Es ist ein HD44780 als Display-Controller implementiert.

@DSausW,
ich finde Wiki als schöner Einstieg für Fragen zu neuen µCs, versuche 
mich davon aber schnellstens zu entfernen. Danke für die Info!
Gast #3702151
Lesenswert?

Das war auch nur ein kleiner Seitenhieb.
Implementiert ist da nichts, jedenfalls nicht im MSP.
Solltest Du aber ein BOARD haben, könnte das sein.
Gängig ist auch bei den 44780-kompatiblen LCD-Modulen,
das der/die Controller auf der Anzeige sitzen.
Dann ist das ja nur ein 4bit/8bit-Geschubbse + Steuerleitungen.
Siehe Artikelsammlung /oder Gurgel, etc. .
Gast #3702152
Lesenswert?

mwstui schrieb:
> Hallo Forum,
>
> ich benutze einen MSP430 F2410 und möchte das folgende Display
> ansteuern: LCD 204B BL

Ah ja, jeder weiß nun, was gemeint ist. In Österreich fast wie dasn 
Autokennzeichen für Bregenz Land.


> In der Wikipedia steht das der MSP430 (welches Derivat aber leider
> nicht) 4 backplanes für die Ansteuerung von LCDs hätte.

Wikipedia ist ja auch genau die Stelle wo man Datenblätter eines uC 
von TI findet....

> Im UserGuide
> ahbe ich dazu leider nicht gefunden. (Oder überlesen, sind ja immerhin
> über 600 Seiten).

Normalerweise haben die Datenblätter von Ti "Lesezeichen" (beim Foxit 
nennt sich das Bookmarks). Das hilft ungemein, solch seitenlangen 
Abhandlungen einer bestimmten Peripherie im uC zu finden.

>
> Hat das schonmal jemand versucht

Ja. Mein Programmierer und ich. Mit einem anderen MSP. Erfolgreich.

> und kann mir dazu einen Link/
> Webresource geben?

geh auf die Website von TI zu den MSP-430 uC und schau nach, was im 
Datenblatt(!) zu genau Deinem uC steht. Im Userguide werden defakto alle 
uC dieser Familie  behandelt, unabhägig davon ob der nun einen 
LCD-Controller eingebaut hat oder nicht. Am Anfang solch eines Kapitels 
steht sogar fast immer, welche Controller das dann genau betrifft.

ist das so schwer daß Du dazu ein Forum benötigst?


> Vielen Dank
> -mwstui

Grüße

MiWi
Gast #3702312
Lesenswert?

@DSausW,
der LCD-Controller ist am  LCD dran.
Also nur die Daten rüber schieben, ok, das hatte ich gehofft :-)
Ich muss übrigens ein Board selbst entwerfen, also habe ich eigentlich 
nur den nackten MSP.

@MiWi,
zu deinem ersten Satz, wenn man keine Ahnung hat... Zu deinem Rest, ich 
bezweifle das du überhaupt schon mal einen Lichtschalter erfolgreich 
umgelegt hast.
Persönliche Seite #3702530
Lesenswert?

mwstui schrieb:
> In der Wikipedia steht das der MSP430 (welches Derivat aber leider
> nicht) 4 backplanes für die Ansteuerung von LCDs hätte.

Das bezieht sich nur auf Varianten, die einen eingebauten LC-Controller 
haben, Dein 'F2410 aber hat den nicht. Außerdem willst Du ein Display 
mit eigenem Controller verwenden, der Punkt ist damit doppelt 
irrelevant.
Gast #3813634
Lesenswert?

Den Thread muss ich aus gegebenen Anlass nocheinmal herausholen.

Ich bin momentan echt am verzweifeln. Das LCD leuchtet fröhlich vor sich 
hin (besser; die Hintergrundbeleuchtung), bekommt die Spannung die es 
soll an den Pins an denen es soll (also High = 3V3 oder Low = 0V) und am 
LCD liegt es auch nicht da ein zweites genauso wenig irgendetwas tut...

Ich habe meinen Quellcode jetzt soweit reduziert das ich erst einmal nur 
einen Blinkenden Cursor haben möchte... aber auch das funktioniert 
nicht... Ich habe meinen "Sendecode" auch im Simulator 
(http://www.dinceraydin.com/djlcdsim/djlcdsim.html)  ausprobiert, da 
funktioniert "natürlich" alles...

Momentan bin ich für jede Idee dankbar...
1
#include <msp430x24x.h>
2

3
void INIT(void);
4
void LCD_INI(void);
5

6
void main(void)
7
{
8
  WDTCTL=WDTPW+WDTHOLD;         // stop watchdog timer
9

10
  //D0-D7 @ P4.7 - P4.0  << Datenbits als GPIO
11
  //RS  @ P5.1      << Registerauswahl (0 = Befehlsreg; 1 = Datenreg)
12
  //E    @ P5.0      << Taktleitung
13
  //RW             Hardwaremäßig gegen GND (= immer schreiben)
14

15
  __delay_cycles(24000);//warte 15ms
16

17
  INIT();
18
  LCD_INI();
19

20
  for(;;)
21
  {}
22
}
23

24
void INIT(void)
25
{
26
  P4DIR = 0xFF;  //Port 4 = Output (8 Datenleitungen zum LCD)
27
  P5DIR = 0xFF;  //Port 5 = Output (RS, E vom LCD)
28
  P4SEL = 0x00;  //Port 4 als GPIO
29
  P5SEL = 0x00;  //Port 5 als GPIO
30
}
31

32
void LCD_INI(void)
33
{
34
  P5OUT = 0x01;      //E auf High und RS auf Low
35
  __delay_cycles(32000);  //warte 20ms
36
  P4OUT = 0xF0;      //Kommando '0000 1111'r
37
  __delay_cycles(32000);  //warte 20ms
38
  P5OUT = 0x02;      //E auf Low, RS auf High
39
  __delay_cycles(32000);  //warte 20ms
40
  P5OUT = 0x03;      //E und RS auf High
41
  __delay_cycles(32000);  //warte 20ms
42
}

-mwstui
Gast #3813653
Lesenswert?

Bevor irgendwer eine Zeile deines Codes analysiert solltest du uns 
erzählen wie du das Versorgungspannungsproblem gelöst hast.

Das LCD 204B BL von Reichelt benötigt laut Datenblatt eine 
Betriebsspannung von 5V und ein MSP430 sollte nicht über 3.6V versorgt 
werden.
Gast #3813674
Lesenswert?

Hi backplane,
die Versorgung habe ich über die externe (USB) gelöst, es kommen 5V rein 
und werden per DC/DC auf 3V3 gepegelt. Am MSP liegen dann auch 3,38V an. 
Andere Funktionen funktionieren auch, nur das LCD eben nicht.
Gast #3813708
Lesenswert?

Hallo Helper, hab ich schon alles ausprobiert gehabt, leider ohne 
Erfolg. Trotzdem Danke. Ich habe auch noch ein paar weitere Websites und 
Tutorials durchgeforstet, wenn ich irgend etwas fundamentales in meinen 
Code vergessen habe, ist es mir bislang nicht aufgefallen, und ich bin 
mittlerweile knapp 13 Stunden an diesen Problem (und den Code aus deinen 
ersten Link habe ich auch schon umgeschrieben, leider auch ohne 
Erfolgreiche Anzeige)
Gast #3813867
Lesenswert?

Helper schrieb:
> Du brauchst nur die Pinbelegung anpassen oder was noch? Poste den
> angepassten Code hier.

Bitte schön:
1
#include <msp430x24x.h>
2

3
#define     LCM_4DIR               P4DIR
4
#define     LCM_4OUT               P4OUT
5
#define     LCM_5DIR               P4DIR
6
#define     LCM_5OUT               P4OUT
7

8
//
9
// Define symbolic LCM - MCU pin mappings
10
// We've set DATA PIN TO 4,5,6,7 for easy translation
11
//
12
#define     LCM_PIN_RS            BIT1          // Px.0
13
#define     LCM_PIN_EN            BIT0          // Px.1
14
#define     LCM_PIN_D7            BIT0          // Px.7
15
#define     LCM_PIN_D6            BIT1          // Px.6
16
#define     LCM_PIN_D5            BIT2          // Px.5
17
#define     LCM_PIN_D4            BIT3          // Px.4
18

19

20
#define     LCM_P4_MASK  ((LCM_PIN_D7 | LCM_PIN_D6 | LCM_PIN_D5 | LCM_PIN_D4))
21
#define     LCM_P5_MASK  ((LCM_PIN_RS | LCM_PIN_EN))
22

23
#define     FALSE                 0
24
#define     TRUE                  1
25

26
//
27
// Routine Desc:
28
//
29
// This is the function that must be called
30
// whenever the LCM needs to be told to
31
// scan it's data bus.
32
//
33
// Parameters:
34
//
35
//     void.
36
//
37
// Return
38
//
39
//     void.
40
//
41
void PulseLcm()
42
{
43
    //
44
    // pull EN bit low
45
    //
46
    LCM_5OUT &= ~LCM_PIN_EN;
47
    __delay_cycles(200);
48

49
    //
50
    // pull EN bit high
51
    //
52
    LCM_5OUT |= LCM_PIN_EN;
53
    __delay_cycles(200);
54

55
    //
56
    // pull EN bit low again
57
    //
58
    LCM_5OUT &= (~LCM_PIN_EN);
59
    __delay_cycles(200);
60
}
61

62

63

64
//
65
// Routine Desc:
66
//
67
// Send a byte on the data bus in the 4 bit mode
68
// This requires sending the data in two chunks.
69
// The high nibble first and then the low nible
70
//
71
// Parameters:
72
//
73
//    ByteToSend - the single byte to send
74
//
75
//    IsData - set to TRUE if the byte is character data
76
//                  FALSE if its a command
77
//
78
// Return
79
//
80
//     void.
81
//
82
void SendByte(char ByteToSend, int IsData)
83
{
84
    //
85
    // clear out all pins
86
    //
87
    LCM_4OUT &= (~LCM_P4_MASK);
88
    //
89
    // set High Nibble (HN) -
90
    // usefulness of the identity mapping
91
    // apparent here. We can set the
92
    // DB7 - DB4 just by setting P1.7 - P1.4
93
    // using a simple assignment
94
    //
95
    LCM_4OUT |= (ByteToSend & 0xF0);
96

97
    if (IsData == TRUE)
98
    {
99
        LCM_5OUT |= LCM_PIN_RS;
100
    }
101
    else
102
    {
103
        LCM_5OUT &= ~LCM_PIN_RS;
104
    }
105

106
    //
107
    // we've set up the input voltages to the LCM.
108
    // Now tell it to read them.
109
    //
110
    PulseLcm();
111
     //
112
    // set Low Nibble (LN) -
113
    // usefulness of the identity mapping
114
    // apparent here. We can set the
115
    // DB7 - DB4 just by setting P1.7 - P1.4
116
    // using a simple assignment
117
    //
118
    LCM_4OUT &= (~LCM_P4_MASK);
119
    LCM_4OUT |= ((ByteToSend & 0x0F) << 4);
120

121
    if (IsData == TRUE)
122
    {
123
        LCM_5OUT |= LCM_PIN_RS;
124
    }
125
    else
126
    {
127
        LCM_5OUT &= ~LCM_PIN_RS;
128
    }
129

130
    //
131
    // we've set up the input voltages to the LCM.
132
    // Now tell it to read them.
133
    //
134
    PulseLcm();
135
}
136

137

138
//
139
// Routine Desc:
140
//
141
// Set the position of the cursor on the screen
142
//
143
// Parameters:
144
//
145
//     Row - zero based row number
146
//
147
//     Col - zero based col number
148
//
149
// Return
150
//
151
//     void.
152
//
153
void LcmSetCursorPosition(char Row, char Col)
154
{
155
    char address;
156

157
    //
158
    // construct address from (Row, Col) pair
159
    //
160
    if (Row == 0)
161
    {
162
        address = 0;
163
    }
164
    else
165
    {
166
        address = 0x40;
167
    }
168

169
    address |= Col;
170

171
    SendByte(0x80 | address, FALSE);
172
}
173

174

175
//
176
// Routine Desc:
177
//
178
// Clear the screen data and return the
179
// cursor to home position
180
//
181
// Parameters:
182
//
183
//    void.
184
//
185
// Return
186
//
187
//     void.
188
//
189
void ClearLcmScreen()
190
{
191
    //
192
    // Clear display, return home
193
    //
194
    SendByte(0x01, FALSE);
195
    SendByte(0x02, FALSE);
196
}
197

198

199
//
200
// Routine Desc:
201
//
202
// Initialize the LCM after power-up.
203
//
204
// Note: This routine must not be called twice on the
205
//           LCM. This is not so uncommon when the power
206
//           for the MCU and LCM are separate.
207
//
208
// Parameters:
209
//
210
//    void.
211
//
212
// Return
213
//
214
//     void.
215
//
216
void InitializeLcm(void)
217
{
218
    //
219
    // set the MSP pin configurations
220
    // and bring them to low
221
    //
222
    LCM_5DIR |= LCM_P5_MASK;
223
    LCM_5OUT &= ~(LCM_P5_MASK);
224

225

226
    //
227
    // wait for the LCM to warm up and reach
228
    // active regions. Remember MSPs can power
229
    // up much faster than the LCM.
230
    //
231
    __delay_cycles(100000);
232

233

234
    //
235
    // initialize the LCM module
236
    //
237
    // 1. Set 4-bit input
238
    //
239
    LCM_5OUT &= ~LCM_PIN_RS;
240
    LCM_5OUT &= ~LCM_PIN_EN;
241

242
    LCM_5OUT = 0x20;
243
    PulseLcm();
244

245
    //
246
    // set 4-bit input - second time.
247
    // (as reqd by the spec.)
248
    //
249
    SendByte(0x28, FALSE);
250

251
    //
252
    // 2. Display on, cursor on, blink cursor
253
    //
254
    SendByte(0x0E, FALSE);
255

256
    //
257
    // 3. Cursor move auto-increment
258
    //
259
    SendByte(0x06, FALSE);
260
}
261

262

263
//
264
// Routine Desc
265
//
266
// Print a string of characters to the screen
267
//
268
// Parameters:
269
//
270
//    Text - null terminated string of chars
271
//
272
// Returns
273
//
274
//     void.
275
//
276
void PrintStr(char *Text)
277
{
278
    char *c;
279

280
    c = Text;
281

282
    while ((c != 0) && (*c != 0))
283
    {
284
        SendByte(*c, TRUE);
285
        c++;
286
    }
287
}
288

289

290
//
291
// Routine Desc
292
//
293
// main entry point to the sketch
294
//
295
// Parameters
296
//
297
//     void.
298
//
299
// Returns
300
//
301
//     void.
302
//
303
void main(void)
304
{
305
    WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer
306

307
    InitializeLcm();
308

309
    ClearLcmScreen();
310

311
    PrintStr("Hello World!");
312

313
    while (1)
314
    {
315
        __delay_cycles(1000);
316
    }
317

318
}

Helper schrieb:
> Bist du sicher, dass die Hardware passt? Ist das Display 3.3V tolerant?

Die Hardware sollte passen, bei dem Kontrastwiderstand habe ich 
mittlerweile einen Poti dazwischen und zwischen 0 und 50k verschiedene 
Werte eingestellt. Passiert ist trotzdem nichts...
Das Display sollte 3V3 als High erkennen (ab 3V).
Gast #3813894
Lesenswert?

Helper schrieb:
> Was fällt auf?

Das da ein Copy-Fehler war...
Danke für den Hinweis, leider behebt der mein Problem nicht.

Ich habe die Schaltung auch mittlerweile Komplett manuell aufgebaut, Die 
Datenleitungen auch mit 5V um zu testn ob ich den Fehler evtl. so 
herausfinden kann... leider Nein, es leuchtet so auch nur das Backlight. 
Ich häng mal eine PNG von meinen Aufbau an. Vielleicht erkennt ja jemand 
den Fehler.

Zur Pinbelegung:
1 - VSS; 2 - VDD; 3 - V0; 4 - RS; 5 - RW; 6 - E;
7-14 - D0-D7; 15 - LEDA; 16 - LEDK

E ist die Taktleitung und wird "ein und aus" gestöpselt.
Der Poti an V0 ist zwischen 0 und 50k probiert wurden.

Der Befehl sollte passen, in dem Simulator 
(http://www.dinceraydin.com/djlcdsim/djlcdsim.html) kann man das auch 
nachprüfen (D0-D3 auf High; E auf High dann wieder Low)
Angehängte Dateien:
Gast #3814339
Lesenswert?

Greif an deinem USB-Port 5V ab um damit das LCD zu versorgen. Die Daten- 
und Steuerleitungen kannst i.d.R. direkt mit dem Controller verbinden, 
solange du nur schreibst und nicht liest, da der LCD-Controller auch die 
3V3 von deinem MSP als High-Pegel erkennt. Also Daten- und 
Steuerleitungen direkt an den uC und alles restliche mit 5V versorgen 
(auch das Poti vom Kontrast).
Gast #3814516
Lesenswert?

@nils,
genauso habe ich es auch gemacht,
Der Fehler lag am Poti, ich benötige sowas hier:
1
   Vcc       -----------------------
2

3
    |--------- Vcc 
4

5
    |       |
6

7
   ---/     |
8

9
P |  /|     |
10

11
O | / |------- Vee     LCD
12

13
T |/  |     |
14

15
  /---      |
16

17
    |       |
18

19
    |--------- GND
20

21
   GND      |
22

23
             -----------------------

somit geht das jetzt alles.

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