MSP430 LCD Problem

Gast #4107066
Lesenswert?

Hallo zusammen,

ich sitze nun schon seit knapp zwei Wochen an einer vermeintlich simplen 
Aufgabe.

Ich habe mein MSP430 Launchpad mit einem LCD verbunden, siehe Anhang.

Das Display verfügt über einen Samsung S6A0069 Controller. Diesen 
versuche ich mit folgender Funktion gemäß Datenblatt zu initialisieren:
1
void init_s6a0069()
2
{
3
  P1DIR = 0xFF;
4
  P2DIR |= BIT0 + BIT1 + BIT2;
5
  
6
  P2OUT = 0x00;  // RS = EN = RW = 0;
7
   
8
  delay_ms(40);  // Delay after power on
9
  
10
  P1OUT = 0x3C;  // Function Set
11
  delay_us(40);
12
  
13
  P1OUT = 0x0F;  // Display ON/OFF
14
  delay_us(40);
15
  
16
  P1OUT = 0x01;  //Display Clear
17
  delay_ms(2);
18
  
19
  P1OUT = 0x04;  // Entry MOde Set
20
  delay_us(1);
21
}

Danach sollte zumindest mal der Cursor blinken, stattdessen ist die 
rechte Seite des Displays erleuchtet (man sieht das im Bild). Und das 
auch nur wenn ich das Display kippe.

Die Delay-Funktionen funktionieren, dass habe ich mit einem Oszilloskop 
geprüft. Die Bits werden auch richtig gesetzt und die Verkabelung habe 
ich schon unzählige Male überprüft.

Das Display sollte laut Datenblatt auch mit 3 Volt auskommen.


Weiß Jemand was ich hier eventuell noch falsch mache?

Viele Grüße,
Michael
Angehängte Dateien:
Gast #4114470
Lesenswert?

Hallo zusammen,

ich habe Neuigkeiten, habe eine Bibliothek gefunden und ausprobiert:
1
#include <msp430g2553.h>
2

3
// Definitions
4
#define DR P1OUT = P1OUT | BIT4 // define RS high
5
#define CWR P1OUT = P1OUT & (~BIT4) // define RS low
6
#define READ P1OUT = P1OUT | BIT5 // define Read signal R/W = 1 for reading
7
#define WRITE P1OUT = P1OUT & (~BIT5) // define Write signal R/W = 0 for writing
8
#define ENABLE_HIGH P1OUT = P1OUT | BIT6 // define Enable high signal
9
#define ENABLE_LOW P1OUT = P1OUT & (~BIT6) // define Enable Low signal
10

11
// Function Prototypes
12
void data_write(void);
13
void data_read(void);
14
void check_busy(void);
15
void send_command(unsigned char cmd);
16
void send_data(unsigned char data);
17
void send_string(char *s);
18
void lcd_init(void);
19

20
//===================================================================================//
21
// DATA_WRITE
22
//===================================================================================//
23
void data_write(void)
24
{
25
  ENABLE_HIGH;
26
  __delay_cycles(40000);
27
  ENABLE_LOW;
28
}
29

30
//===================================================================================//
31
// DATA_READ
32
//===================================================================================//
33
void data_read(void)
34
{
35
  ENABLE_LOW;
36
  __delay_cycles(40000);
37
  ENABLE_HIGH;
38
}
39

40
//===================================================================================//
41
// DATA_WRITE
42
//===================================================================================//
43
void check_busy(void)
44
{
45
  P1DIR &= ~(BIT3); // make P1.3 as input
46
  while ((P1IN & BIT3) == 1)
47
  {
48
    data_read();
49
  }
50
  P1DIR |= BIT3; // make P1.3 as output
51
}
52

53
//===================================================================================//
54
// SEND_COMMAND
55
//===================================================================================//
56
void send_command(unsigned char cmd)
57
{
58
  check_busy();
59
  WRITE;
60
  CWR;
61
  P1OUT = (P1OUT & 0xF0) | ((cmd >> 4) & 0x0F); // send higher nibble
62
  data_write(); // give enable trigger
63
  P1OUT = (P1OUT & 0xF0) | (cmd & 0x0F); // send lower nibble
64
  data_write(); // give enable trigger
65
}
66

67
//===================================================================================//
68
// SEND_DATA
69
//===================================================================================//
70
void send_data(unsigned char data)
71
{
72
  check_busy();
73
  WRITE;
74
  DR;
75
  P1OUT = (P1OUT & 0xF0) | ((data >> 4) & 0x0F); // send higher nibble
76
  data_write(); // give enable trigger
77
  P1OUT = (P1OUT & 0xF0) | (data & 0x0F); // send lower nibble
78
  data_write(); // give enable trigger
79
}
80

81
//===================================================================================//
82
// SEND_STRING
83
//===================================================================================//
84
void send_string(char *s)
85
{
86
  while (s)
87
  {
88
    send_data(*s);
89
    s++;
90
  }
91
}
92

93
//===================================================================================//
94
// LCD_INIT
95
//===================================================================================//
96
void lcd_init(void)
97
{
98
  P2OUT &= 0x00;
99
  P2DIR &= 0x00;
100

101
  P1DIR |= 0xFF;
102
  P1OUT &= 0x00;
103
  send_command(0x33);
104
  send_command(0x32);
105
  send_command(0x28); // 4 bit mode
106
  send_command(0x0E); // clear the screen
107
  send_command(0x01); // display on cursor on
108
  send_command(0x06); // increment cursor
109
  send_command(0x80); // row 1 column 1
110
}

Die main-Funktion sieht wie folgt aus:
1
void main(void)
2
{
3
  WDTCTL = WDTPW + WDTHOLD; // stop watchdog timer
4
  init_clock();
5
  lcd_init();
6
  send_string("Hello");
7
  send_command(0xC0);
8
  send_string("World");
9

10
  while (1)
11
  {
12

13
  }
14

15
  // return 0;
16
}

Auf dem Display erscheint tatsächlich "Hello World", allerdings nur 
einmal, danach verblasst es und nur noch die rechte Display-Hälfte ist 
mit schwarzen Kästchen gesetzt.

Da ist wohl noch irgend etwas faul, aber zumindest mal ein Anfang. 
Vielleicht liegt es auch am Display, das ist nämlich schon rund 12 Jahre 
alt.

Beste Grüße,
Michael
Gast #4114531
Lesenswert?

Michael schrieb:
> allerdings nur
> einmal, danach verblasst es

Wie darf man sich das vorstellen? Du gibst nur einmal den Text aus und 
die CPU tritt auf der Stelle. Wird das Display jetzt langsam 
unleserlich?
Oder passiert das erst mit einem anderen Programm, was wir hier nicht 
sehen?
Gast #4114570
Lesenswert?

Das Display wird langsam unleserlich, siehe Anhang.

Ein anderes Programm gibt es nicht, es wird nur die oben genannte 
main-function abgearbeitet.

Vermutlich muss ich den internen RAM kontinuierlich beschreiben. Mich 
wundert nur, dass die rechte Display Hälfte einen höheren Kontrast hat.
Angehängte Dateien:
Gast #4114592
Lesenswert?

Michael schrieb:
> void check_busy(void)
> {
>   P1DIR &= ~(BIT3); // make P1.3 as input
>   while ((P1IN & BIT3) == 1)
>   {
>     data_read();
>   }
>   P1DIR |= BIT3; // make P1.3 as output
> }

Unglaublich was für ein Mist im Internet steht.

Hier wird der LCD Port gelesen nachdem der Enable weggenommen
wurde (geschieht in data_read() ). Das geht nur durch Zufall gut.

(P1IN & BIT3) kann niemals 1 sein. Entweder 0x08 oder 0x00;

1
unsigned char val;
2
do
3
{
4
  ENABLE_HIGH;
5
  __delay_cycles(xxx);
6
  val = (P1IN & BIT3)
7
  ENABLE_LOW;
8
} while (val);
Gast #4114613
Lesenswert?

LCD-Anfänger schrieb:

>> void check_busy(void)
>> {
>>   P1DIR &= ~(BIT3); // make P1.3 as input
>>   while ((P1IN & BIT3) == 1)
>>   {
>>     data_read();
>>   }
>>   P1DIR |= BIT3; // make P1.3 as output
>> }
>

Ich bessere nach:
1
unsigned char val;
2

3
P1DIR &= ~(BIT3); // make P1.3 as input
4
do
5
{
6
  ENABLE_HIGH;
7
  __delay_cycles(xxx);
8
  val = (P1IN & BIT3);
9
  ENABLE_LOW;
10
} while (val);
11
P1DIR |= BIT3; // make P1.3 as output

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