Forum: Mikrocontroller und Digitale Elektronik LCD Anzeige wird nicht gelöscht


von Danonino (Gast)


Lesenswert?

Guten Abend zusammen,

ich arbeite mich gerade in das Thema µController ein.

Ich nutze einen ATMEGA 8 und das myAVR MK2 Board mit dem LCD Board.

Nun habe ich folgendes Programm geschrieben, welches mir einen Text auf 
dem LCD ausgibt.

Das Schreiben funktioniert.
1
#define F_CPU 10000000  // µController hat 1 MHZ
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
6
7
void lcd_cmd(char cmd)
8
{
9
10
PORTD &=(1<<PD2); //RS = 0 um ein Kommando zu senden
11
lcd_send(cmd); // Aufruf einer Funktion
12
}
13
14
void lcd_clear()
15
{
16
lcd_cmd(0x01); // Anzeige auf dem LCD löschen
17
_delay_ms(2);
18
}
19
20
void lcd_home()
21
{
22
lcd_cmd(0x02); // Zeiger auf die Anfangsposition
23
_delay_ms(2);
24
}
25
26
void lcd_on()
27
{
28
lcd_cmd(0x0E); // LCD anschalten
29
}
30
31
void lcd_off()
32
{
33
lcd_cmd(0x08); // LCD ausschalten
34
}
35
36
void lcd_send(char data)
37
{
38
39
char rs = PORTD; // Abfrage ob RS 0 oder 1
40
41
rs &= 4; // RS auf 1 setzen um Daten senden zu können
42
43
char tmp = data;
44
tmp &= 0xf0; // Erst die obere Bits aufbereiten und schicken
45
tmp|=rs;
46
PORTD = tmp; 
47
PORTD |= (1<<PD3);//0x08; // Enable aktivieren, so dass das Display diesen Befehl vom Bus lesen kann
48
_delay_ms(50);// Zeit fürs umschalten geben (50ms)
49
PORTD &= ~(1<<PD3);//PORTD = 0x00;  // Enable wieder auf NULL setzen
50
_delay_ms(5); // Zeit fürs umschalten geben
51
52
53
tmp = data;
54
tmp &=0x0f; // Anschließend die unteren Bits aufbereiten und schicken
55
tmp*=16;
56
tmp|=rs;
57
PORTD = tmp;
58
PORTD |= (1<<PD3);//0x08; // Enable aktivieren, so dass das Display diesen Befehl vom Bus lesen kann
59
_delay_ms(50);// Zeit fürs umschalten geben (50ms)
60
PORTD &= ~(1<<PD3);//PORTD = 0x00;  // Enable wieder auf NULL setzen
61
_delay_ms(5); // Zeit fürs umschalten geben
62
63
}
64
65
void lcd_write(char text)
66
{
67
68
PORTD|= (1<<PD2); //RS auf 1 setzen, um  Daten zu schicken
69
lcd_send(text);
70
}
71
72
void lcd_string(const char *data)
73
{
74
while(*data != '\0')
75
{
76
  lcd_send(*data++);
77
}
78
}
79
80
void lcd_init() // Initialisierung des LCD-Displays
81
{
82
83
DDRD = 0xFF; // PORTD wird für die Ansteuerung genutzt. PORTD = Ausgang
84
PORTD = 0; // PORTD  auf NULL setzen
85
86
_delay_ms(50); // Start Vorgang des Diplays abwarten 50ms
87
88
PORTD =0x20; // 4 Bit Modus nutzen
89
PORTD |= (1<<PD3);//0x08; // Enable aktivieren, so dass das Display diesen Befehl vom Bus lesen kann
90
_delay_ms(50);// Zeit fürs umschalten geben (50ms)
91
PORTD &= ~(1<<PD3);// Enable wieder auf NULL setzen
92
_delay_ms(5); // Zeit fürs umschalten geben
93
94
lcd_cmd(0x28); //Function Set schicken, 4 Bit Modus, 2 Zeilen Display, 5x7 Pixel
95
lcd_off(); // LCD ausschalten
96
lcd_clear(); // LCD Anzeige löschen
97
lcd_cmd(0x06); //Entry Mode Display on und Curser on
98
lcd_on(); // LCD einschalten
99
}
100
101
102
int main(void)
103
{
104
105
lcd_init();
106
107
/*
108
lcd_write('H');
109
lcd_write('a');
110
lcd_write('l');
111
lcd_write('l');
112
lcd_write('o');
113
*/
114
//lcd_string("Hallo Welt");
115
while(1)
116
{
117
118
lcd_write('H');
119
lcd_write('a');
120
lcd_write('l');
121
lcd_write('l');
122
lcd_write('o');
123
124
_delay_ms(5000);
125
lcd_clear();
126
_delay_ms(5000);
127
128
}
129
130
return 0;
131
132
}

Nun habe ich folgende Fragen,

1) Warum wird die Anzeige nicht gelöscht. Der Text "Hallo" bleibt stehen 
und nach ein paar Sekunden werden || angezeigt und dann erfolgt wieder 
"Hallo". Aber ich rufe doch die funktion lcd_clear() auf.
Wieso wird das nicht übernommen?


2) Wie kann ich verhindern, das der Text auch in der 2 Zeile angezeigt 
wird?

Möchte nun gerne verstehen, wie ich einzelne Zeichen(char) oder ganze 
Strings ans LCD übergeben kann und wie ich diese auch ändern kann.

Möchte danach gerne den Umgang mit dem ADC erlernen und mir die 
notwendigen Werte auf dem LCD anzeigen lassen.

Hoffe ihr könnt helfen. Schaue da gerade nicht mehr durch.

Danke

von holger (Gast)


Lesenswert?

>void lcd_cmd(char cmd)
>{
>
>PORTD &=(1<<PD2); //RS = 0 um ein Kommando zu senden
>lcd_send(cmd); // Aufruf einer Funktion
>}
1
void lcd_cmd(char cmd)
2
{
3
  PORTD &= ~(1<<PD2); //RS = 0 um ein Kommando zu senden
4
  lcd_send(cmd); // Aufruf einer Funktion
5
}

Ein Wunder das das überhaupt funktioniert hat.

von Mike (Gast)


Lesenswert?

Danonino schrieb:
> Möchte nun gerne verstehen, wie ich einzelne Zeichen(char) oder ganze
> Strings ans LCD übergeben kann und wie ich diese auch ändern kann.

Guck mal in deinen Code. Einzelne Zeichen gibtst du aus mit der von dir 
dauern verwendeten Funktion
1
void lcd_write(char text)
Einen String mit der Funktion
1
void lcd_string(const char *data)

von Danonino (Gast)


Lesenswert?

Hallo Holger,

darüber hatte ich schon nachgedacht. Aber wenn ich ~ nutze funktioniert 
das Schreiben nicht mehr.
1
void lcd_cmd(char cmd)
2
{
3
  PORTD &= ~(1<<PD2); //RS = 0 um ein Kommando zu senden
4
  lcd_send(cmd); // Aufruf einer Funktion
5
}

Ist mein Aufruf denn falsch?

von Mike (Gast)


Lesenswert?

Danonino schrieb:
> Hoffe ihr könnt helfen. Schaue da gerade nicht mehr durch.

Wenn du es dir ganz einfach machen willst, suchst du hier im Forum 
einfach mal nach Quellcode, mit dem das LCD Display benutzt wird.

Glaub mit - du bist nicht der erste, der das Ding benutzt. Es gibt 
direkt einen Artikel, der direkt deine Frage beantwortet (Beispiel 1) in
AVR-GCC-Tutorial/LCD-Ansteuerung

von holger (Gast)


Lesenswert?

>void lcd_send(char data)
>{
>
>char rs = PORTD; // Abfrage ob RS 0 oder 1
>
>rs &= 4; // RS auf 1 setzen um Daten senden zu können

rs &= 4; // setzt RS nicht

rs |= (1<<PD2); // setzt RS

von Karl H. (kbuchegg)


Lesenswert?

holger schrieb:
>>void lcd_send(char data)
>>{
>>
>>char rs = PORTD; // Abfrage ob RS 0 oder 1
>>
>>rs &= 4; // RS auf 1 setzen um Daten senden zu können
>
> rs &= 4; // setzt RS nicht
>
> rs |= (1<<PD2); // setzt RS

Das Original war schon richtig.
In lcd_send ist die Absicht nicht, RS zu setzen oder nicht zu setzen, 
sondern an dieser Stelle soll festgestellt werden, ob RS gesetzt ist 
oder nicht, damit der jeweilige Zustand dann in das auszugebende Byte 
wieder einkopiert werden kann, welches er mit
1
tmp|=rs;
2
PORTD = tmp;
dann ausgibt.


>  funktioniert das Schreiben nicht mehr.

welches Schreiben?
Das von Einzelzeichen oder das von Strings.
Das von Einzelzeichen muss nach wie vor funktioniern. Das Schreiben von 
Strings kann nicht funktionieren, weil hier (wie Mike bereits angemerkt 
hatte)
1
void lcd_string(const char *data)
2
{
3
while(*data != '\0')
4
{
5
  lcd_send(*data++);
6
}
7
}

die falsche Funktion benutzt wird. Die Ausgabe von auszugebenden Zeichen 
geht über die Funktion lcd_write und nicht über lcd_send. Also muss es
1
void lcd_string(const char *data)
2
{
3
  while(*data != '\0')
4
  {
5
    lcd_write(*data++);
6
  }
7
}
heißen.

Und formatier deinen Code besser!
Einrückungen sind nicht Selbstzweck.
Die Verwendung der 4 hier
1
rs &= 4;
ist inakzeptabel. Überall anders hast du (1<<PD2) benutzt. Warum nicht 
hier? Dann würde man auch aus 5 Schritten Entfernung erkennen können, 
was hier wirklich passiert - nämlich den aktuell eingestellten Zustand 
der RS Leitung auf PD2 abzufragen. Was dann auch bei notwendigen 
Änderungen, wie zb das Leitungen auf andere Pins gelegt werden müssen, 
sofort ins Auge springen würde.

: 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.