Forum: Mikrocontroller und Digitale Elektronik MSP430F55 LCD Ansteuerung


von AMHM M. (mfly87)


Lesenswert?

Hallo, kann mir jemand sagen, wo mein Fehler steckt?
Möchte gerne ein LCD mit einem MSP430 ansteuern.

Die Pin Konfiguration lautet:


E = P8.2
RS = P3.7
R/W = GND
D4 = P1.3
D5 = P1.2
D6 = P4.3
D7 = P4.0
1
#include <msp430x552x.h>
2
#include <stdio.h>
3
4
void LCD_init(void);
5
void DelayMs(int Ms);
6
void LCD_cmd4(unsigned char cmd);
7
void LCD_dat4(unsigned char byte);
8
9
unsigned char i;
10
const unsigned char Msg1[] = "LCD Test";
11
const unsigned char Msg2[] = "MSP430";
12
13
void main()
14
{
15
 WDTCTL = WDTPW + WDTHOLD;  // Stop watchdog timer
16
 P1DIR = 0x0C;                             // Set D4 und D5 as Outout
17
 P3DIR = 0x80;                             // Set RS
18
 P4DIR = 0x06;                             // Set D6 und D7 as Output
19
 P8DIR = 0x04;                             // Set EN
20
 DelayMs(500);                             // Delay
21
 LCD_init();                               // LCD Init
22
 DelayMs(500);                             // Delay
23
24
 while(1)
25
  {
26
   LCD_cmd4(0x80);
27
   for(i=0;i<16;i++)
28
29
   {
30
    LCD_dat4(Msg1[i]);
31
    DelayMs(5);
32
   }
33
34
   LCD_cmd4(0xc0);
35
   for(i=0;i<16;i++)
36
37
    {
38
     LCD_dat4(Msg2[i]);
39
     DelayMs(5);
40
    }
41
  }
42
}
43
44
void LCD_init(void)
45
 {
46
47
  LCD_cmd4(0x28);              // 28 for four Bit mode
48
  DelayMs(500);                // Delay
49
  LCD_cmd4(0x0C);              // Turns the Display on
50
  DelayMs(500);                // Delay
51
  LCD_cmd4(0x1C);              // Cursor move to right
52
  DelayMs(500);                // Delay
53
  LCD_cmd4(0x01);              // Clear the Display
54
  DelayMs(500);                // Delay
55
 }
56
57
void LCD_cmd4(unsigned char cmd)
58
 {
59
  P3OUT = 0x00;                  // RS=0
60
  P1OUT = cmd;                   // Display Output D4,D5 = CMD set
61
  P4OUT = cmd;                   // Display Output D6,D7 = CMD set
62
  P8OUT = 0x04;                  // En = 1;
63
  P8OUT = 0x00;                  // En = 0;
64
  cmd = (cmd<<4) & 0xF0;         //?????????
65
  P1OUT = cmd;                   // Display Output D4,D5 = CMD set
66
  P4OUT = cmd;                   // Display Output D6,D7 = CMD set
67
  P8OUT = 0x80;                  // En = 1;
68
  P8OUT = 0x00;                  // En = 0;
69
  DelayMs(5);                    // Delay
70
 }
71
72
void LCD_dat4(unsigned char byte)
73
 { 
74
   P3OUT = 0x80;                 // RS=0
75
   P1OUT = byte;                 // Display Output D4,D5 = Byte set
76
   P4OUT = byte;                 // Display Output D6,D7 = Byte set
77
   P8OUT = 0x04;                 // En = 1;
78
   P8OUT = 0x00;                 // En = 0;
79
   byte = (byte<<4) & 0xF0;      // ?????????
80
   P1OUT = byte;                 // Display Output D4,D5 = Byte set
81
   P4OUT = byte;                 // Display Output D6,D7 = Byte set
82
   P8OUT = 0x04;                 // En = 1;
83
   P8OUT = 0x00;                 // En = 0;
84
   DelayMs(3);
85
 }
86
87
void DelayMs(int Ms)
88
 {
89
  int i;
90
  while(Ms>0)
91
    {
92
     for(i=0;i<104;i++);
93
     Ms--;
94
    }
95
  }

--

Bitte Code in [ c ] [ /c ] -Tags packen.

-rufus

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

AMHM M. schrieb:
> Hallo, kann mir jemand sagen, wo mein Fehler steckt?

Die Fehlerbeschreibung fehlt. Du beschreibst nur, was Du tust, nicht 
aber, was Du erreichen willst, und auch nicht, was schief geht.


Wobei ... das hier macht ziemlich sicher nicht das, was Du willst:
1
  P1OUT = cmd;                   // Display Output D4,D5 = CMD set
2
  P4OUT = cmd;                   // Display Output D6,D7 = CMD set

Was ist an P1 und an P4?
1
D4 = P1.3
2
D5 = P1.2
3
D6 = P4.3
4
D7 = P4.0

Was passiert, wenn Du P1 und P4 so beschreibst?

Von "cmd" werden die Bits 0, 2 und 3 ausgegeben, Bit 0 an D7, Bit 2 an 
D5 und Bit 3 sowohl an D4 als auch an D6.

: Bearbeitet durch User
von AMHM M. (mfly87)


Lesenswert?

Der Fehler besteht darin, dass das Programm zwar korrekt geladen wird, 
aber auf dem Display tut sich nicht.
Der Fehler kann beim Initialisieren liegen oder auch beim senden. Da ich 
neu in der Materie bin, kenne ich mich mit der Fehlersuche nicht so gut 
aus....

von Amateur (Gast)


Lesenswert?

>void LCD_dat4(unsigned char byte)

Diese Zeile sollte als Bleistift, für eine maximal, mittelprächtige 
Parameterbezeichnung, archiviert werden.
... oder im Rahmen an die Wand.

von AMHM M. (mfly87)


Lesenswert?

Amateur schrieb:
>>void LCD_dat4(unsigned char byte)
>
> Diese Zeile sollte als Bleistift, für eine maximal, mittelprächtige
> Parameterbezeichnung, archiviert werden.
> ... oder im Rahmen an die Wand.



Was meinst du damit?
Ist die falsch?

von Clemens L. (c_l)


Lesenswert?

AMHM M. schrieb:
> kann mir jemand sagen, wo mein Fehler steckt?

Du hast Netiquette: Klare Beschreibung des Problems nicht gelesen.

> Möchte gerne ein LCD

Irgendein LCD? Oder ein bestimmtes?

> mit einem MSP430 ansteuern.

Irgendein MSP430? Oder ein bestimmter?


Amateur schrieb:
>> void LCD_dat4(unsigned char byte)
>
> Diese Zeile sollte als Bleistift, für eine maximal, mittelprächtige
> Parameterbezeichnung, archiviert werden.

Wenn der Zweck dieser Funktion ist, ein Byte zu senden, dann ist der 
Name des Parameters selbst gar nicht mal so schlecht.

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Clemens L. schrieb:
> Irgendein MSP430? Oder ein bestimmter?

Im Programm wird eine Headerdatei eingebunden, die verrät es:

 'F552x

von Route_66 H. (route_66)


Lesenswert?

Hallo!
Das hier:

> D6 = P4.3
> D7 = P4.0

korrespondiert nicht mit:

> P4DIR = 0x06;                             // Set D6 und D7 as Output

: Bearbeitet durch User
von AMHM M. (mfly87)


Lesenswert?

Also es handelt sich um eine Msp430f5529.
Das LcD ist ein herkömmliches von Conrad.
Wenn ihr wollt, kann ich das Datenblatt einfügen. Hat aber einen HD44780 
Controller.

Möchte natürlich nicht nur ein Byte sondern einen Text wie oben 
angegeben anzeigen lassen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dann lies doch mal die verschiedenen Hinweise, die Dir gegeben wurden. 
Deine Initialisierung und Ansteuerung von Port1 und Port4 sind 
fehlerhaft.

Wieso eigentlich zerstückelst Du die vier Datenleitungen des Displays 
auch noch so hochgradig ungeschickt? Hättest Du die nicht alle vier an 
einen Port hängen können?

von AMHM M. (mfly87)


Lesenswert?

Rufus Τ. F. schrieb:
> Dann lies doch mal die verschiedenen Hinweise, die Dir gegeben wurden.
> Deine Initialisierung und Ansteuerung von Port1 und Port4 sind
> fehlerhaft.
>
> Wieso eigentlich zerstückelst Du die vier Datenleitungen des Displays
> auch noch so hochgradig ungeschickt? Hättest Du die nicht alle vier an
> einen Port hängen können?

Weil alle anderen Port bzw Pins vergeben sind. Habe mir eine 
Leiterplatte herstellen lassen und dabei nicht soweit gedacht, aber 
leider ist das so.

Ich habe mir deinen Hinweis angeschaut,
Verstehe ich leider nicht, kannst du mir einen Tipp geben, wie ich es 
verstehen kann :-)

von Route_66 H. (route_66)


Lesenswert?

AMHM M. schrieb:
Ds hier:
> P1OUT = byte;                 // Display Output D4,D5 = Byte set
>    P4OUT = byte;                 // Display Output D6,D7 = Byte set

schreibt alle 8 Bit von byte auf Port 1 und Port 4.
Du haast bei beiden Ports nur zwei Pins als Ausgang definiert. Nur sind 
das nicht D4 und D5. bzw D6 und D7 wie es in Deinem Kommentar steht. Die 
Bits sind Dank Deiner Verwurstelung ganz anders. Das mußt Du hier: 
LCD_dat4 und auch in LCD_cmd4 wieder entwursteln.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

AMHM M. schrieb:
> Verstehe ich leider nicht, kannst du mir einen Tipp geben, wie ich es
> verstehen kann :-)

Du willst VIER unterschiedliche Bits eines Bytes ausgeben, die an 
bestimmten Positionen im Byte untergebracht sind.
Vermutlich willst Du die Bits 0..3 ausgeben.

Diese vier Bits sollen an den Datenleitungen D4..7 des Displays landen.

Wenn Du an beide Ports exakt denselben Wert ausgibst, entsprechen sich 
alle Bits dieser Ports.

Du aber verwendest diese Portzuordnung:

D4 = P1.3
D5 = P1.2
D6 = P4.3
D7 = P4.0

Da P1.3 und P4.3 gleich sind, steuerst Du D4 und D6 des Displays mit dem 
gleichen Wert an. Bit 1 Deines Werts hingegen verschwindet im Nirvana.

Das geht in die Hose. Du musst bei beiden Zugriffen die Bits vorher 
korrekt anordnen, bevor Du sie auf die Ports ausgibst.

Wenn Du Bit 0 und Bit 1 Deines Datenbytes an D4 und D5 des Displays 
ausgeben willst, musst Du diese beiden Bits in Deinem Datenbyte so 
anordnen, daß sie an P1.3 und P1.2 auftauchen.
1
uint8_t Portwert = 0;
2
3
if (cmd & (1 << 0))
4
  Portwert |= (1 << 3);
5
if (cmd & (1 << 1))
6
  Portwert |= (1 << 2);
7
8
P1OUT = Portwert;

Und entsprechend musst Du die Bits 2 und 3 Deines Datenbytes, die Du an 
D6 und D7 ausgeben willst, so anordnen, daß sie auf P4.3 und P4.0 
landen.

von AMHM M. (mfly87)


Lesenswert?

Rufus Τ. F. schrieb:
> AMHM M. schrieb:
>> Verstehe ich leider nicht, kannst du mir einen Tipp geben, wie ich es
>> verstehen kann :-)
>
> Du willst VIER unterschiedliche Bits eines Bytes ausgeben, die an
> bestimmten Positionen im Byte untergebracht sind.
> Vermutlich willst Du die Bits 0..3 ausgeben.
>
> Diese vier Bits sollen an den Datenleitungen D4..7 des Displays landen.
>
> Wenn Du an beide Ports exakt denselben Wert ausgibst, entsprechen sich
> alle Bits dieser Ports.
>
> Du aber verwendest diese Portzuordnung:
>
> D4 = P1.3
> D5 = P1.2
> D6 = P4.3
> D7 = P4.0
>
> Da P1.3 und P4.3 gleich sind, steuerst Du D4 und D6 des Displays mit dem
> gleichen Wert an. Bit 1 Deines Werts hingegen verschwindet im Nirvana.
>
> Das geht in die Hose. Du musst bei beiden Zugriffen die Bits vorher
> korrekt anordnen, bevor Du sie auf die Ports ausgibst.
>
> Wenn Du Bit 0 und Bit 1 Deines Datenbytes an D4 und D5 des Displays
> ausgeben willst, musst Du diese beiden Bits in Deinem Datenbyte so
> anordnen, daß sie an P1.3 und P1.2 auftauchen.
>
>
1
> uint8_t Portwert = 0;
2
> 
3
> if (cmd & (1 << 0))
4
>   Portwert |= (1 << 3);
5
> if (cmd & (1 << 1))
6
>   Portwert |= (1 << 2);
7
> 
8
> P1OUT = Portwert;
9
>
>
> Und entsprechend musst Du die Bits 2 und 3 Deines Datenbytes, die Du an
> D6 und D7 ausgeben willst, so anordnen, daß sie auf P4.3 und P4.0
> landen.


Also ist genau diese Zeile falsch.
cmd = (cmd<<4) & 0xF0;

Und es müsste heißen:

cmd = (cmd & (1 << 0))
Portwert |= (1 << 3);

cmd = (cmd & (1 << 1))
Portwert |= (1 << 2);

cmd = (cmd & (1 << 2))
Portwert |= (4 << 3);

cmd = (cmd & (1 << 3))
Portwert |= (4<< 0);

Habe Ich das richtig verstanden.
Wenn ja, bedanke ich mich sehr bei euch,
Hoffe es funktioniert und das ist das einzigste Problem gewesen. Kann es 
erst morgen testen :-)

von Route_66 H. (route_66)


Lesenswert?

AMHM M. schrieb:
> Also ist genau diese Zeile falsch.
> cmd = (cmd<<4) & 0xF0;

Nein.

Das Alles ist falsch:

AMHM M. schrieb:
> P3OUT = 0x80;                 // RS=0
>    P1OUT = byte;                 // Display Output D4,D5 = Byte set
>    P4OUT = byte;                 // Display Output D6,D7 = Byte set
>    P8OUT = 0x04;                 // En = 1;
>    P8OUT = 0x00;                 // En = 0;
>    byte = (byte<<4) & 0xF0;      // ?????????
>    P1OUT = byte;                 // Display Output D4,D5 = Byte set
>    P4OUT = byte;                 // Display Output D6,D7 = Byte set

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

AMHM M. schrieb:
> Habe Ich das richtig verstanden.

Nein.

von AMHM M. (mfly87)


Lesenswert?

Rufus Τ. F. schrieb:
> AMHM M. schrieb:
>> Habe Ich das richtig verstanden.
>
> Nein.

Dann brauch ich bitte noch ein Tipp :-(

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Vergleiche doch einfach mal, was ich geschrieben habe
1
if (cmd & (1 << 0))
2
  Portwert |= (1 << 3);
3
if (cmd & (1 << 1))
4
  Portwert |= (1 << 2);

mit dem, was Du daraus gemacht hast:
1
cmd = (cmd & (1 << 0))
2
Portwert |= (1 << 3);
3
4
cmd = (cmd & (1 << 1))
5
Portwert |= (1 << 2);
6
7
cmd = (cmd & (1 << 2))
8
Portwert |= (4 << 3);
9
10
cmd = (cmd & (1 << 3))
11
Portwert |= (4<< 0);

Kannst Du versuchen, mir zu erklären, wie Du darauf gekommen bist, und 
was das mit dem, was ich geschrieben habe, zu tun hat?

von AMHM M. (mfly87)


Lesenswert?

Also, das erste habe ich von dir kopiert:

If cmd = (cmd & (1 << 0))
Portwert |= (1 << 3);

If cmd = (cmd & (1 << 1))
Portwert |= (1 << 2);

If cmd = (cmd & (1 << 2))
Portwert |= (4 << 3);

If cmd = (cmd & (1 << 3))
Portwert |= (4<< 0);

Der erste Bit 1 << 0 soll an Port 1.3

Der zweite Bit 1 << 1 soll an Port 1.2

Das dritte Bit 1 << 2 soll an Port 4.3

Das vierte Bite 1 << 3 soll an Port 4.0

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

AMHM M. schrieb:
> Also, das erste habe ich von dir kopiert:
>
> If cmd = (cmd & (1 << 0))
> Portwert |= (1 << 3);

Hast Du nicht. Sieh doch nochmal genau hin.

> If cmd = (cmd & (1 << 0))

hat mit

> if (cmd & (1 << 0))

nur sehr wenig Ähnlichkeiten.

Und schaff' Dir ein Buch über die von Dir verwendete Programmiersprache 
an, wenn Dich deren Syntax derartig herausfordert.

von AMHM M. (mfly87)


Lesenswert?

Route 6. schrieb:
> AMHM M. schrieb:
>> Also ist genau diese Zeile falsch.
>> cmd = (cmd<<4) & 0xF0;
>
> Nein.
>
> Das Alles ist falsch:
>
> AMHM M. schrieb:
>> P3OUT = 0x80;                 // RS=0
>>    P1OUT = byte;                 // Display Output D4,D5 = Byte set
>>    P4OUT = byte;                 // Display Output D6,D7 = Byte set
>>    P8OUT = 0x04;                 // En = 1;
>>    P8OUT = 0x00;                 // En = 0;
>>    byte = (byte<<4) & 0xF0;      // ?????????
>>    P1OUT = byte;                 // Display Output D4,D5 = Byte set
>>    P4OUT = byte;                 // Display Output D6,D7 = Byte set

Sorry, war wohl so verzweifelt, dass ich nur noch Sterne gesehen habe.
Route 66 meinte aber das alles wäre falsch.

von AMHM M. (mfly87)


Lesenswert?

If (cmd & (1 << 0))
Portwert |= (1 << 3);

If (cmd & (1 << 1))
Portwert |= (1 << 2);

If (cmd & (1 << 2))
Portwert |= (4 << 3);

If (cmd & (1 << 3))
Portwert |= (4<< 0);

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Schön. Und verstehst Du auch, was da passiert?

Und was mit "Portwert" wann geschehen muss?

von AMHM M. (mfly87)


Lesenswert?

Ich hoffe es :-)

P1Out = cmd;
P4Out = cmd;

Hier ordne ich es dem ganzen Port zu und das ist falsch.

Ich muss es wie du es mir versucht hast beizubringen bzw ich es 
verstanden habe einzeln zuordnen.

Also mit:

If (cmd & (1 << 0))
Portwert |= (1 << 3);
If (cmd & (1 << 1))
Portwert |= (1 << 2);
If (cmd & (1 << 2))
Portwert |= (4 << 3);
If (cmd & (1 << 3))
Portwert |= (4<< 0);

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

AMHM M. schrieb:
> ch muss es wie du es mir versucht hast beizubringen bzw ich es
> verstanden habe einzeln zuordnen.

Schon. Aber mein Beispiel ist nur für einen Port. Das Drumherum 
(Initialisierung von "portwert") und Ausgabe an den jeweiligen Port 
musst Du entsprechend zweimal machen.

von AMHM M. (mfly87)


Lesenswert?

Rufus Τ. F. schrieb:
> AMHM M. schrieb:
>> ch muss es wie du es mir versucht hast beizubringen bzw ich es
>> verstanden habe einzeln zuordnen.
>
> Schon. Aber mein Beispiel ist nur für einen Port. Das Drumherum
> (Initialisierung von "portwert") und Ausgabe an den jeweiligen Port
> musst Du entsprechend zweimal machen.

Das hat mich jetzt wieder verwirrt.
Zweimal?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ja, denn Du benutzt zwei Ports, Port1 und Port4, und an die willst Du ja 
nicht das gleiche ausgeben.

von AMHM M. (mfly87)


Lesenswert?

If (cmd & (1 << 0))
Portwert |= (1 << 3);
If (cmd & (1 << 1))
Portwert |= (1 << 2);
If (cmd & (1 << 2))
Portwert |= (4 << 3);
If (cmd & (1 << 3))
Portwert |= (4<< 0);

Dachte mit dem Ausdruck gebe ich es an das jeweilige Port.....
1. Bit an Port 1.3 D4
2. Bit an Port 1.2 D5
3. Bit an Port 4.3 D6
4. Bit an Port 4.0 D7

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du bastelst Dir nur eine Variable namens Portwert zusammen, an Ports 
gibst Du gar nichts aus.

Sieh Dir doch einfach nochmal mein Codebeispiel an:
1
uint8_t Portwert = 0;
2
3
if (cmd & (1 << 0))
4
  Portwert |= (1 << 3);
5
if (cmd & (1 << 1))
6
  Portwert |= (1 << 2);
7
8
P1OUT = Portwert;

Was macht das anders als Dein Code? Erkennst Du einen Unterschied?

von AMHM M. (mfly87)


Lesenswert?

uint8_t PortwertA = 0;

if (cmd & (1 << 0))
  Portwert |= (1 << 3);
if (cmd & (1 << 1))
  Portwert |= (1 << 2);

uint8_t PortwertB = 0;
If (cmd & (1 << 2))
Portwert |= (4 << 3);
If (cmd & (1 << 3))
Portwert |= (4<< 0

 {
  P3OUT = 0x00;                  // RS=0
  P1OUT = PortwertA;             // Display Output D4,D5 = CMD set
  P4OUT = PortwertB;             // Display Output D6,D7 = CMD set
  P8OUT = 0x04;                  // En = 1;
  P8OUT = 0x00;                  // En = 0;
  cmd = (cmd<<4) & 0xF0;         //?????????
  P1OUT = PortwertA;             // Display Output D4,D5 = CMD set
  P4OUT = PortwertB;             // Display Output D6,D7 = CMD set
  P8OUT = 0x80;                  // En = 1;
  P8OUT = 0x00;                  // En = 0;
  DelayMs(5);                    // Delay
 }

So vielleicht?

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das kommt (von den Flüchtigkeitsfehlern abgesehen) dem Ziel schon etwas 
näher. Zwar brauchst Du keine zwei Variablen, aber das ist erst mal 
egal.

Hintergrundinformation:

Das Display ist mit vier Datenleitungen angeschlossen, aber Du möchtest 
8-Bit-Werte an das Display übertragen. Im 4-Bit-Modus müssen die beiden 
Hälften eines Bytes nacheinander an die gleichen Datenleitungen 
ausgegeben werden. Und zwar, so steht's im Datenblatt, erst die vier 
oberen Bits und dann die vier unteren Bits.

Du hast jetzt (mit einiger Nachhilfe) den Teil hinbekommen, der die 
unteren vier Bit Deines Werts "cmd" an das Display ausgibt.

Das ist der zweite Teil der Übung, Du brauchst dasselbe für die oberen 
vier Bits, und den Teil musst Du zuerst ausführen.

Mach Dir eine Kopie von Deinem Code, und pass' ihn so an, daß nicht die 
unteren, sondern die oberen vier Bits an das Display ausgegeben werden.

Kannst Du nachvollziehen, was dazu nötig ist?

von AMHM M. (mfly87)


Lesenswert?

uint8_t PortwertA = 0;

if (cmd & (1 << 0))
  Portwert |= (1 << 3);
if (cmd & (1 << 1))
  Portwert |= (1 << 2);

uint8_t PortwertB = 0;
If (cmd & (1 << 2))
Portwert |= (4 << 3);
If (cmd & (1 << 3))
Portwert |= (4<< 0

 {
  P3OUT = 0x00;                  // RS=0
  P1OUT = PortwertA;             // Display Output D4,D5 = CMD set
  P4OUT = PortwertB;             // Display Output D6,D7 = CMD set
  P8OUT = 0x04;                  // En = 1;
  P8OUT = 0x00;                  // En = 0;
  cmd = (cmd>>4) & 0xF0;         //?????????
  P1OUT = PortwertA;             // Display Output D4,D5 = CMD set
  P4OUT = PortwertB;             // Display Output D6,D7 = CMD set
  P8OUT = 0x80;                  // En = 1;
  P8OUT = 0x00;                  // En = 0;
  DelayMs(5);                    // Delay
 }
 {
  P3OUT = 0x00;                  // RS=0
  P1OUT = PortwertA;             // Display Output D4,D5 = CMD set
  P4OUT = PortwertB;             // Display Output D6,D7 = CMD set
  P8OUT = 0x04;                  // En = 1;
  P8OUT = 0x00;                  // En = 0;
  cmd = (cmd & 0x0F;             //?????????
  P1OUT = PortwertA;             // Display Output D4,D5 = CMD set
  P4OUT = PortwertB;             // Display Output D6,D7 = CMD set
  P8OUT = 0x80;                  // En = 1;
  P8OUT = 0x00;                  // En = 0;
  DelayMs(5);                    // Delay
 }

Ich bin mir nicht sicher :-(((

: Bearbeitet durch User
von Sebastian S. (amateur)


Lesenswert?

Sorry musste für mein Gehalt arbeiten...

Meine Kritik bezog sich auf den Namen "byte" für einen 
Übergabeparameter. Wundert mich auch, dass dein Compiler nicht über 
einen reservierten Bezeichner meckert bzw. dessen Fehlen moniert.

Die bisherige Diskussion erweckt in mir den Gedanken, dass: "Kopieren 
geht über Studieren", hier einen zu hohen Stellenwert hat.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Nein. Jetzt hast Du den falschen Codeblock verdoppelt.

Die zwei interessanten Hälften sind rund um Deine mit vielen 
Fragezeichen versehene Zeile angeordnet.


1
  uint8_t Portwert;
2
3
  P3OUT = 0x00; // RS=0
4
5
  ... hier fehlt der Code zur Ausgabe von Bit 7..4 
6
7
  P8OUT = 0x04; // En = 1;
8
  P8OUT = 0x00; // En = 0;
9
10
  cmd = (cmd << 4) & 0xF0; //?????????
11
12
  Portwert = 0;
13
14
  if (cmd & (1 << 0))      // Bit 0
15
    Portwert |= (1 << 3);  // an P1.3
16
  if (cmd & (1 << 1))      // Bit 1 
17
    Portwert |= (1 << 2);  // an P1.2
18
19
  P1OUT = Portwert;     
20
21
  Portwert = 0;
22
23
  if (cmd & (1 << 2))      // Bit 2
24
    Portwert |= (4 << 3);  // ** das ist falsch, wieso schiebst Du hier den Wert 4?
25
  if (cmd & (1 << 3))      // Bit 3
26
    Portwert |= (4<< 0);   // ** das ist auch falsch  
27
28
  P4OUT = Portwert;
29
30
  P8OUT = 0x80; // En = 1;
31
  P8OUT = 0x00; // En = 0;
32
  DelayMs(5); // Delay
33
}


An diesem Fragment solltest Du vielleicht schon mehr erkennen können.

Klar ist jedenfalls eines: Durch diese ausgesprochen ungeschickte Art 
des Anschlusses des Displays machst Du Dir das Leben ausgesprochen 
schwer.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Sebastian S. schrieb:
> Wundert mich auch, dass dein Compiler nicht über einen reservierten
> Bezeichner meckert bzw. dessen Fehlen moniert.

"byte" ist in C kein reservierter Bezeichner.

(Deine Kritik ansonsten völlig gerechtfertigt)

von AMHM M. (mfly87)


Lesenswert?

uint8_t Portwert;

  P3OUT = 0x00; // RS=0

 cmd = (cmd & 0x0F

  P8OUT = 0x04; // En = 1;
  P8OUT = 0x00; // En = 0;

  cmd = (cmd << 4) & 0xF0; //?????????

  Portwert = 0;

  if (cmd & (1 << 0))      // Bit 0
    Portwert |= (1 << 3);  // an P1.3
  if (cmd & (1 << 1))      // Bit 1
    Portwert |= (1 << 2);  // an P1.2

  P1OUT = Portwert;

  Portwert = 0;

  if (cmd & (1 << 2))      // Bit 2
    Portwert |= (4 << 3);  // **Bit 2 soll doch auf Port 4.3 geschrieben 
werden
  if (cmd & (1 << 3))      // Bit 3
    Portwert |= (4<< 0);   // ** soll doch Port 4.0 sein

  P4OUT = Portwert;

  P8OUT = 0x80; // En = 1;
  P8OUT = 0x00; // En = 0;
  DelayMs(5); // Delay
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

AMHM M. schrieb:
> Portwert |= (4 << 3);  // **Bit 2 soll doch auf Port 4.3 geschrieben
> werden

Aua. Aua.

Das tut echt weh.

Sorry, aber bist Du Dir sicher, Dir die richtige Aufgabe gesucht zu 
haben?

Was bitte macht die Zuweisung, die ein paar Zeilen weiter unten steht?

P4OUT = Portwert;

Wozu mag das gut sein?

von AMHM M. (mfly87)


Lesenswert?

Jeder fängt mal klein an.
Kannst du mir bitte den Code mal per PN oder so zukommen lassen,
damit ich ihn genaustens analysiere, weil anscheinend habe ich das nicht 
richtig verstanden, weil sonst bringt das ja nicht viel. Das wäre sehr 
großzügig von dir.
Ich finde es ja absolut klasse, dass du dich überhaupt mit mir 
beschäftigst.

Sie gibt den Inhalt der Variable Portwert an Port4 aus.

von AMHM M. (mfly87)


Lesenswert?

AMHM M. schrieb:
> Jeder fängt mal klein an.
> Kannst du mir bitte den Code mal per PN oder so zukommen lassen,
> damit ich ihn genaustens analysiere, weil anscheinend habe ich das nicht
> richtig verstanden, weil sonst bringt das ja nicht viel. Das wäre sehr
> großzügig von dir.
> Ich finde es ja absolut klasse, dass du dich überhaupt mit mir
> beschäftigst.
>
> Sie gibt den Inhalt der Variable Portwert an Port4 aus.

Rufus Τ. F. schrieb:
> AMHM M. schrieb:
>> Portwert |= (4 << 3);  // **Bit 2 soll doch auf Port 4.3 geschrieben
>> werden
>
> Aua. Aua.
>
> Das tut echt weh.
>
> Sorry, aber bist Du Dir sicher, Dir die richtige Aufgabe gesucht zu
> haben?
>
> Was bitte macht die Zuweisung, die ein paar Zeilen weiter unten steht?
>
> P4OUT = Portwert;
>
> Wozu mag das gut sein?

Eine weitere Frage, bei mir gibt er uint8_t als undefiniert an,
obwohl ich stdint.h eingebunden habe? Hast du eventuell auch dafür eine 
erklärung? ------> Ok, habe ich doch hinbekommen. Bräuchte nur für oben 
Hilfe.

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

AMHM M. schrieb:
> Sie gibt den Inhalt der Variable Portwert an Port4 aus.

Immerhin. Warum aber schiebst Du dann den Wert 4?

Darf an Port4 nur eine 4 ausgegeben werden?

Zum Verständnis:

Der Wert eines Bits entspricht der Zweierpotenz seiner Nummer.

Bit 0 hat den Wert 2^0
Bit 1 hat den Wert 2^1
Bit 2 hat den Wert 2^2
Bit 3 hat den Wert 2^3

etc.

Das bedeutet, daß die Bitnummer gleich der Potenz ist. Praktisch, nicht?

2^0 ist 1.
2^1 ist 2, und den Rest der Reihe solltest Du jetzt selbst 
vervollständigen können.

Es gibt unterschiedliche Philosophien, wie man in der C-Programmierung 
solche Bitkonstanten schreibt, bei der hier im Forum überwiegend 
vertretenen AVR-Fraktion ist es gebräuchlich, das durch Verwendung des 
Schiebeoperators in Verbindung mit der Bitnummer zu erledigen.


Bit 0, das den Wert 1 (also 2^0) hat, ist gleichbedeutend mit 1 << 0.

Bit 1 ist gleichbedeutend mit 1 << 1.

Der Schiebeoperator verdoppelt den Wert des links von ihm stehenden 
Ausdrucks sooft, wie rechts von ihm angegeben ist.

1 << 1 verdoppelt also den Wert von 1 genau einmal.

Folglich verdoppelt 1 << 3 den Wert von 1 dreimal, das Resultat also 
beträgt wieviel?

Dieses Resultat (das Du jetzt bitte herausfinden sollst, damit ich sehe, 
daß Du verstanden hast, was ich hier schreibe) hat den Wert von Bit 3.

Eine andere Art und Weise mit Bitkonstanten umzugehen ist es, gleich 
deren Wert zu verwenden, aber das erfordert Übung und Erfahrung, 
weil man diese Werte nämlich erkennen muss. Das ist eine 
Abstraktionsebene mehr, die für ungeübte das, was gemeint ist, 
versteckt.

Oder würdest Du erkennen, daß mit

if (cmd & 0x80)

das Bit 7 von cmd ausgewertet wird?

Oder welches Bit mit (cmd & 64) gemeint ist?

Eben. Deswegen habe ich hier bewusst die Schiebe-Schreibweise in 
Verbindung mit Bitnummern verwendet.

von AMHM M. (mfly87)


Lesenswert?

Rufus Τ. F. schrieb:
> Der Schiebeoperator verdoppelt den Wert des links von ihm stehenden
> Ausdrucks sooft, wie rechts von ihm angegeben ist.
>
> 1 << 1 verdoppelt also den Wert von 1 genau einmal.
>
> Folglich verdoppelt 1 << 3 den Wert von 1 dreimal, das Resultat also
> beträgt wieviel?

Achso, ich dachte ich gebe unten wirklich die Portnummer, also Adresse 
4.3 und Adresse 4.0.
Aber ich muss ja, nur angeben, wieoft der Bit nach links verschoben 
werden muss.

uint8_t Portwert;

  P3OUT = 0x00; // RS=0

 cmd = (cmd & 0x0F

  P8OUT = 0x04; // En = 1;
  P8OUT = 0x00; // En = 0;

  cmd = (cmd << 4) & 0xF0; //?????????

  Portwert = 0;

  if (cmd & (1 << 0))      // Bit 0
    Portwert |= (1 << 3);  // an P1.3
  if (cmd & (1 << 1))      // Bit 1
    Portwert |= (1 << 2);  // an P1.2

  P1OUT = Portwert;

  Portwert = 0;

  if (cmd & (1 << 2))      // Bit 2
    Portwert |= (1 << 3);  // Bit wird um 3 Stellen nach links 
verschoben also Bit 3

  if (cmd & (1 << 3))      // Bit 3
    Portwert |= (1 << 0);  // Bit wird um 0 Stellen nach links 
verschoben also Bit 0

  P4OUT = Portwert;

  P8OUT = 0x80; // En = 1;
  P8OUT = 0x00; // En = 0;
  DelayMs(5); // Delay
}

Rufus Τ. F. schrieb:
> if (cmd & 0x80)
>
> das Bit 7 von cmd ausgewertet wird?
>
> Oder welches Bit mit (cmd & 64) gemeint ist?
>
> Eben. Deswegen habe ich hier bewusst die Schiebe-Schreibweise in
> Verbindung mit Bitnummern verwendet.

if (cmd & 0x80) ist natürlich binär 10000000, also 7 Bit
if (cmd & 0x64) iat binär 01100100, also Bit 6,5 und 3

Richtig?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

AMHM M. schrieb:
> if (cmd & 0x64) iat binär 01100100, also Bit 6,5 und 3

Habe ich 0x64 geschrieben? Sieh nochmal genau hin.

von Route_66 H. (route_66)


Lesenswert?

Rufus Τ. F. schrieb:
> AMHM M. schrieb:
>> if (cmd & 0x64) iat binär 01100100, also Bit 6,5 und 3

Bits 6,5 und zwei!

von AMHM M. (mfly87)


Lesenswert?

Rufus Τ. F. schrieb:
> Habe ich 0x64 geschrieben? Sieh nochmal genau hin

Oh, okay. also mit Hexadezimal kenne ich mich aus, aber mit dem nicht.
Sorry. ich probier den code jetzt gleich mal aus und dann sage ich ob es 
funzt. Der rest passt???

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

AMHM M. schrieb:
> Oh, okay. also mit Hexadezimal kenne ich mich aus, aber mit dem nicht.

Äh, echt jetzt? 64. Vierundsechzig. Das ist eine ganz normale 
Dezimalzahl.

von AMHM M. (mfly87)


Lesenswert?

Oh, klar :-) also auch das 7. Bit.
Vielen Dank, hast mir sehr weiter geholfen. Zimindestens theoretisch.

Praktisch funktioniert der Code immer noch nicht... Fällt dir zufällig 
noch ein Fehler auf?

von Route_66 H. (route_66)


Lesenswert?

AMHM M. schrieb:
> Oh, klar :-) also auch das 7. Bit.

NEIN das s e c h s t e!

(Kopfschüttel)

AMHM M. schrieb:
> Praktisch funktioniert der Code immer noch nicht... Fällt dir zufällig
> noch ein Fehler auf?

Wie sieht denn jetzt Dein Code aus?

: Bearbeitet durch User
von AMHM M. (mfly87)


Lesenswert?

1
#include <msp430x552x.h>
2
#include <stdio.h>
3
#include <stdint.h>
4
5
void LCD_init(void);
6
void DelayMs(int Ms);
7
void LCD_cmd4(unsigned char cmd);
8
void LCD_dat4(unsigned char byte);
9
10
unsigned char i;
11
const unsigned char Msg1[] = "LCD Test";
12
const unsigned char Msg2[] = "MSP430";
13
14
void main()
15
{
16
 WDTCTL = WDTPW + WDTHOLD;  // Stop watchdog timer
17
 P1DIR = 0x0C;                             // Set D4 und D5 as Outout
18
 P3DIR = 0x80;                             // Set RS
19
 P4DIR = 0x06;                             // Set D6 und D7 as Output
20
 P8DIR = 0x04;                             // Set EN
21
 DelayMs(500);                             // Delay
22
 LCD_init();                               // LCD Init
23
 DelayMs(500);                             // Delay
24
25
 while(1)
26
  {
27
   LCD_cmd4(0x80);
28
   for(i=0;i<16;i++)
29
30
   {
31
    LCD_dat4(Msg1[i]);
32
    DelayMs(5);
33
   }
34
35
   LCD_cmd4(0xc0);
36
   for(i=0;i<16;i++)
37
38
    {
39
     LCD_dat4(Msg2[i]);
40
     DelayMs(5);
41
    }
42
  }
43
}
44
45
void LCD_init(void)
46
 {
47
48
  LCD_cmd4(0x28);              // 28 for four Bit mode
49
  DelayMs(500);                // Delay
50
  LCD_cmd4(0x0C);              // Turns the Display on
51
  DelayMs(500);                // Delay
52
  LCD_cmd4(0x1C);              // Cursor move to right
53
  DelayMs(500);                // Delay
54
  LCD_cmd4(0x01);              // Clear the Display
55
  DelayMs(500);                // Delay
56
 }
57
58
void LCD_cmd4(unsigned char cmd)
59
 {
60
  uint8_t Portwert;        // Variable deklarieren ohne Vorzeichen Integer 8-Bit Typ
61
62
    P3OUT = 0x00;          // RS=0
63
64
   cmd = (cmd & 0x0F);      // Unteren 4 Bits an die Datenleitung senden
65
66
    P8OUT = 0x04;          // En = 1;
67
    P8OUT = 0x00;          // En = 0;
68
69
    cmd = (cmd << 4) & 0xF0;    // Unteren 4 Bits an die Datenleitung senden
70
    Portwert = 0;          // Variable löschen
71
72
    if (cmd & (1 << 0))      // Bit 0
73
      Portwert |= (1 << 3);    // Um 3 Stellen nach links verschieben (P1.3)
74
    if (cmd & (1 << 1))      // Bit 1
75
      Portwert |= (1 << 2);    // Um 2 Stellen nach links verschieben (P1.2)
76
77
    P1OUT = Portwert;        // Variable gibt Inhalt an P1
78
    Portwert = 0;          // Variable löschen
79
80
    if (cmd & (1 << 2))          // Bit 2
81
      Portwert |= (1 << 3);      // Um 3 Stellen nach links verschieben (4.3)
82
    if (cmd & (1 << 3))          // Bit 3
83
      Portwert |= (1 << 0);     // Um  0Stellen nach links verschieben (4.0)
84
85
    P4OUT = Portwert;        // Variable gibt Inhalt an P4
86
87
    P8OUT = 0x80;          // En = 1;
88
    P8OUT = 0x00;         // En = 0;
89
    DelayMs(50);           // Verzögerung
90
  }
91
92
93
void LCD_dat4(unsigned char byte)
94
 {
95
  uint8_t PortwertA;
96
97
   P3OUT = 0x80;                 // RS=0
98
99
   byte = (byte & 0x0F);      // Obere vier bytes in die Variable schreiben?
100
101
   P8OUT = 0x04;                 // En = 1;
102
   P8OUT = 0x00;                 // En = 0;
103
104
   byte = (byte<<4) & 0xF0;      // ?????????
105
106
   PortwertA = 0;
107
108
       if (byte & (1 << 0))      // Bit 0
109
         PortwertA |= (1 << 3);  // an P1.3
110
       if (byte & (1 << 1))      // Bit 1
111
         PortwertA |= (1 << 2);  // an P1.2
112
113
       P1OUT = PortwertA;
114
115
       PortwertA = 0;
116
117
       if (byte & (1 << 2))      // Bit 2
118
         PortwertA |= (1 << 3);  // Bit wird um 3 Stellen nach links  verschoben also Bit 3
119
120
       if (byte & (1 << 3))      // Bit 3
121
         PortwertA |= (1 << 0);  // Bit wird um 0 Stellen nach links  verschoben also Bit 0
122
123
       P4OUT = PortwertA;
124
125
   P8OUT = 0x04;                 // En = 1;
126
   P8OUT = 0x00;                 // En = 0;
127
   DelayMs(3);
128
 }
129
130
void DelayMs(int Ms)
131
 {
132
  int i;
133
  while(Ms>0)
134
    {
135
     for(i=0;i<104;i++);
136
     Ms--;
137
    }
138
  }

--

Mit den [ c ] [ /c ] -Tags wird das gleich viel lesbarer.
-rufus

: Bearbeitet durch User
von hate this (Gast)


Lesenswert?

@Rufus  Off Topic

Rufus Τ. F. schrieb:
> if (cmd & (1 << 0))

Wir haben hier kein AVR Krimskarms und sollten daher die besseren 
#define nutzen.
1
if (cmd & BIT0) ...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

hate this schrieb:
> Wir haben hier kein AVR Krimskarms und sollten daher die besseren
> #define nutzen.

Kann man so machen (würde ich selbst auch so handhaben, aber mein Code 
dient nicht Lehrzwecken), da hier aber auch viele AVR-affine Menschen 
mitlesen, hielt ich es für das allgemeine Verständnis für sinnvoller. So 
können auch nicht-MSP430-Nutzer das Problem verstehen (das mit einem 
MSP430 nur sehr entfernt am Rande zu tun hat).

von AMHM M. (mfly87)


Lesenswert?

Rufus Τ. F. schrieb:
> hate this schrieb:
>> Wir haben hier kein AVR Krimskarms und sollten daher die besseren
>> #define nutzen.
>
> Kann man so machen (würde ich selbst auch so handhaben, aber mein Code
> dient nicht Lehrzwecken), da hier aber auch viele AVR-affine Menschen
> mitlesen, hielt ich es für das allgemeine Verständnis für sinnvoller. So
> können auch nicht-MSP430-Nutzer das Problem verstehen (das mit einem
> MSP430 nur sehr entfernt am Rande zu tun hat).

Dafür bin ich dir auch dankbar. Hast du aber nochmal ein Fehler 
gefunden, warum es nicht geht?

von Route_66 H. (route_66)


Lesenswert?

AMHM M. schrieb:
> Dafür bin ich dir auch dankbar. Hast du aber nochmal ein Fehler
> gefunden, warum es nicht geht?

Viele...
Nur mal zwei:
1. du mußt erst das High-Nibble und dann dal Low-Nibble ausgeben,
2. Du mußt Dich mal entscheiden:

AMHM M. schrieb:
> P8OUT = 0x80;          // En = 1;
>     P8OUT = 0x00;         // En = 0;

> P8OUT = 0x04;          // En = 1;
>     P8OUT = 0x00;          // En = 0;

von AMHM M. (mfly87)


Lesenswert?

Route 6. schrieb:
> AMHM M. schrieb:
>> Dafür bin ich dir auch dankbar. Hast du aber nochmal ein Fehler
>> gefunden, warum es nicht geht?
>
> Viele...
> Nur mal zwei:
> 1. du mußt erst das High-Nibble und dann dal Low-Nibble ausgeben,
> 2. Du mußt Dich mal entscheiden:
>
> AMHM M. schrieb:
>> P8OUT = 0x80;          // En = 1;
>>     P8OUT = 0x00;         // En = 0;
>
>> P8OUT = 0x04;          // En = 1;
>>     P8OUT = 0x00;          // En = 0;

Okay, High nibble verstandlich.
das Enable auch.

Was denn sonst, dass es Soviele sind.

von Route_66 H. (route_66)


Lesenswert?

AMHM M. schrieb:
> Was denn sonst, dass es Soviele sind.

Dein Code zeugt einfach von Deiner Schlampigkeit und das ist eine sehr 
schlechte Tugend für einen Programmierer.

Schau dir den Programmtext langsam und sorgfältig Zeile für Zeile an.
Verstehe jede Zeile.
Korrigiere Tippfehler.
Korrigiere logische Fehler.
Lösche Überflüssige Zeilen.
Bringe den Rest in die richtige Reihenfolge.
Ergänze Fehlendes.

Und schon läuft der Laden!

: Bearbeitet durch User
von AMHM M. (mfly87)


Lesenswert?

Route 6. schrieb:
> AMHM M. schrieb:
>> Was denn sonst, dass es Soviele sind.
>
> Dein Code zeugt einfach von Deiner Schlampigkeit und das ist eine sehr
> schlechte Tugend für einen Programmierer.
>
> Schau dir den Programmtext langsam und sorgfältig Zeile für Zeile an.
> Verstehe jede Zeile.
> Korrigiere Tippfehler.
> Korrigiere logische Fehler.
> Lösche Überflüssige Zeilen.
> Bringe den Rest in die richtige Reihenfolge.
> Ergänze Fehlendes.
>
> Und schon läuft der Laden!

Das habe ich ich jetzt mal gemacht und für jede Zeile eine Kommentar 
hinzugefügt, wie ich es verstanden habe.

{
uint8_t Portwert;    // Variable Integer 8-Bit Typ

P3OUT = 0x00;        // RS=0

// Muss hier nich das Enable kurz auf high gesetzte werden?

cmd = (cmd << 4) & 0xF0;  // Oberen 4 Bits an die Datenleitung

P8OUT = 0x04;      // En = 1;
P8OUT = 0x00;      // En = 0;

cmd = (cmd & 0x0F);    // Untere 4 Bits an die Datenleitung senden
Portwert = 0;      // Variable löschen

if (cmd & (1 << 0))    // Bit 0
    Portwert |= (1 << 3);  // Um 3 Stellen nach links (P1.3)
    if (cmd & (1 << 1))  // Bit 1
Portwert |= (1 << 2);    // Um 2 Stellen nach links (P1.2)

P1OUT = Portwert;    // Variable gibt Inhalt an P1
Portwert = 0;      // Variable löschen

if (cmd & (1 << 2))        // Bit 2
    Portwert |= (1 << 3);    // Um 3 Stellen nach links (4.3)
if (cmd & (1 << 3))        // Bit 3
    Portwert |= (1 << 0);   // Um  0Stellen nach links (4.0)

P4OUT = Portwert;     // Variable gibt Inhalt an P4

P8OUT = 0x04;      // En = 1;
P8OUT = 0x00;       // En = 0;
DelayMs(50);       // Verzögerung
}

von Route_66 H. (route_66)


Lesenswert?

1
 1 {
2
 2 uint8_t Portwert;    // Variable Integer 8-Bit Typ
3
 3 
4
 4 P3OUT = 0x00;        // RS=0
5
 5 
6
 6 // Muss hier nich das Enable kurz auf high gesetzte werden?
7
 7 
8
 8 cmd = (cmd << 4) & 0xF0;  // Oberen 4 Bits an die Datenleitung
9
 9 
10
10 P8OUT = 0x04;      // En = 1;
11
11 P8OUT = 0x00;      // En = 0;
12
12 
13
13 cmd = (cmd & 0x0F);    // Untere 4 Bits an die Datenleitung senden
14
14 Portwert = 0;      // Variable löschen
15
15 
16
16 if (cmd & (1 << 0))    // Bit 0
17
17     Portwert |= (1 << 3);  // Um 3 Stellen nach links (P1.3)
18
18     if (cmd & (1 << 1))  // Bit 1
19
19 Portwert |= (1 << 2);    // Um 2 Stellen nach links (P1.2)
20
20 
21
21 P1OUT = Portwert;    // Variable gibt Inhalt an P1
22
22 Portwert = 0;      // Variable löschen
23
23 
24
24 if (cmd & (1 << 2))        // Bit 2
25
25     Portwert |= (1 << 3);    // Um 3 Stellen nach links (4.3)
26
26 if (cmd & (1 << 3))        // Bit 3
27
27     Portwert |= (1 << 0);   // Um  0Stellen nach links (4.0)
28
28 
29
29 P4OUT = Portwert;     // Variable gibt Inhalt an P4
30
30 
31
31 P8OUT = 0x04;      // En = 1;
32
32 P8OUT = 0x00;       // En = 0;
33
33 DelayMs(50);       // Verzögerung
34
34 }

Hallo!
In der Zeile 4 unterscheidest Du, ob Du ein Steuerwort an den 
Displaycontroller oder Daten zum Anzeigen übergeben willst. Es wird nur 
ein Draht auf Low oder High gesetzt.
Deshalb ist Deine Frage in Zeile 6 Unsinn.

Zeile 8 ist falsch kommentiert: es wird nur die Variable "cmd" verändert 
und nichts an irgendwelche Datenleitungen übergeben.

Zeilen 10, 11: Du hast Deine Daten für das Display so verwurstelt, dass 
jetzt noch kein Enable kommen darf, erst müssen die Bitzuordnungen 
enwirrt werden.

Zeile 13: dito zu Zeile 8

zwischen Zeile 14 und 21 entwirrst Du zwei Bits und gibst sie an den 
Port P1 aus. In den Zeilen 22 bis 29 das gleiche an Port P4 also 2 Bits 
entwirren und ausgeben.

Dann folgt in Zeile 31, 32 das Enable. Das LCD muß jetzt mit 4(!) Bits 
klar kommen. Es will aber immer 8 haben. Ich würde mich auch weigern.

Die Initialisierungssequenz zum 4-Bit-Modus solltest Du Dir auch noch 
mal ansehen. Das LCD erwartet zuerst 8-Bit-Kommandos (am 4-Bit 
Anschluss):
3xReset und dann den Umschaltbefehl in den 4-Bit-Modus.

Deine Delays sind wohl eher aus Verzweiflung entstanden als aus 
Sachkenntnis.

: Bearbeitet durch User
von LCD (Gast)


Angehängte Dateien:

Lesenswert?

> Zeile 8 ist falsch kommentiert: es wird nur die Variable "cmd" verändert
> und nichts an irgendwelche Datenleitungen übergeben.
>
> Zeilen 10, 11: Du hast Deine Daten für das Display so verwurstelt, dass
> jetzt noch kein Enable kommen darf, erst müssen die Bitzuordnungen
> enwirrt werden.
>
> Zeile 13: dito zu Zeile 8
>
> zwischen Zeile 14 und 21 entwirrst Du zwei Bits und gibst sie an den
> Port P1 aus. In den Zeilen 22 bis 29 das gleiche an Port P4 also 2 Bits
> entwirren und ausgeben.
>
> Dann folgt in Zeile 31, 32 das Enable. Das LCD muß jetzt mit 4(!) Bits
> klar kommen. Es will aber immer 8 haben. Ich würde mich auch weigern.
>
> Die Initialisierungssequenz zum 4-Bit-Modus solltest Du Dir auch noch
> mal ansehen. Das LCD erwartet zuerst 8-Bit-Kommandos (am 4-Bit
> Anschluss):
> 3xReset und dann den Umschaltbefehl in den 4-Bit-Modus.
>
> Deine Delays sind wohl eher aus Verzweiflung entstanden als aus
> Sachkenntnis.

Hi,

so jetzt habe ich es nochmal korrigiert, vorallem die Initialisierung.
Das sollte soweit passen. Des Weiteren habe ich versucht, die Routine zu 
ändern. Jedoch funktioniert es immer noch nicht, kannst du bitte nochmal 
drüber gucken? Den Quellcode habe ich als Textdatei, sonst wird es zu 
unübersichtlich.

von AMHM M. (mfly87)


Lesenswert?

Sorry, aber in der Textdatei ist bei Enable P8Out = 0x80, was natürlich 
nicht stimmt, sondern P8Out = 0x04, da es auf P8.2 liegt.

Wenn die Initialisierung stimmt, müsste doch eigentlich der Cursor 
blinken, wenn ich es mit dem Befehl 0x0F einstellen ohne das der 
restliche Part des LCD "funktioniert"

: Bearbeitet durch User
von Route_66 H. (route_66)


Lesenswert?

Hallo!
Ich sehe schon viele Fortschritte, aber...

Wo soll ich nur beginnen?

Zunächst: Du gibst im 4-Bit-Modus erst das Low-Nibble und dann das 
High-Nibble aus. Das gehört in LCD_cmd4 und LCD_dat4 genau anders herum.
Du brauchst auch keine zwei Dummy-Variablen PortwertA und PortwertB, 
eine genügt.

Die Initialisierung erfolgt als 8-Bit Ausgabe - die ist tricky.
Das ganze ist hier etwas schwierig zu beschreiben. Ich versuchs mal:
Du musst jedes Steuerwort bis zur Umschaltung als einzelne 4-Bit Ausgabe 
und nicht als zwei mal 4-Bit Ausgabe machen (Ja, hört sich bescheuert 
an).
Das Dsiplay ergänzt selbst die fehlenden 4 Bit durch 0000 im Low-Nibble.
Jedes Display sollte dazu Pull-Down-Widerstände an offenen 
Datenleitungen haben. Man könnte zur Sicherheit D0-D3 am LCD auch auf 
Low legen.

Das hört sich alles etwas wirr an, ist aber so.

Für die ersten vier Kommandos brauchst Du also eine besondere Prozedur.
Erst danach werden alle Ausgaben in zwei mal 4 Bit gemacht.

Nebenbei: (oder Internet-Denglisch BTW)
Deine zwei Prozeduren LCD_cmd4 und LCD_dat4 unterscheiden sich nur in 
einer Zeile, braucht es dazu zwei Prozeduren oder genügt ein 
Übergabeparameter für die Unterscheidung cmd/dat?

von holger (Gast)


Lesenswert?

Das Problem wurde hier bereits gelöst:

Beitrag "LCD Initialisierung W162B-N3LW"

von Route_66 H. (route_66)


Lesenswert?

holger schrieb:
> Das Problem wurde hier bereits gelöst:

Das Problem wurde hier schon zig-tausendmale glöst, nur schaut sich das 
wohl keiner an!

Zu Weihnachten will ich dem kleinen Mädchen  AMHM MARI einfach nur 
helfen.

: Bearbeitet durch User
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.