Forum: Mikrocontroller und Digitale Elektronik Fehler in der Ansteuerungsroutine für HD44780- Display reagiert träge


von Henry (Gast)


Angehängte Dateien:

Lesenswert?

Guten Abend allerseits,

ich weiß Beiträge und Beispiele zu den Themen HD44780 und LCD gibt es 
schon zu genüge. Allerdings konnte ich bis jetzt noch nicht meinen 
Fehler bzw. Phänomen in den Beiträgen finden.
Ich habe folgendes Problem:
Die Initialisierung und Ansteuerung meines Displays funktioniert zwar 
allerdings reagiert das Display irgendwie träge. Man kann zu gucken wie 
die Zeichen von links nach rechts eingeblendet werden bzw. wie die Zeile 
wieder gelöscht wird. Der Aufbau dauert ca. eine 1/2 Sekunde, die 
eigentliche Anzeige eine 1/4 sekunde und das Löschen auch eine 1/4 
Sekunde.
Es wirkt fast so als ob das Display mit einem niedrigeren Takt läuft als 
normal. Wenn ich fertigen Code verwende z.B. aus Codesammlung tritt das 
Phänomen nicht auf.
Als Hardware verwende ich einen Atmega32 auf einem 
Olimex-Entwicklungsboard. Das LCD ist von Electronic Assembly (HD44780 
mit 2x16 Zeichen).Das Display betreibe ich im 4Bit-Modus. Die 
Verkabelung steht in der lcd.h.
Es wäre nett, wenn mir jemand einen Tip geben könnte, wo der Fehler in 
meinem Code steckt bzw. was ich falsch gemacht habe.

mfg
Henry

von Johannes M. (johannesm)


Lesenswert?

sprintf und LCD-Ausgaben in der ISR durchzuführen halte ich für nicht 
besonders sinnvoll.

von Klaus (Gast)


Lesenswert?

@ Henry

Mit welchem Takt arbeitet dein Atmega32?

1 Mhz?

16 Mhz? mit Quarz?


Wenn du einen externen Quarz benutzt must du auch deinen µC per Fuses 
einstellen.
Dann gilt auch #define F_CPU 16000000UL vor #include <util/delay.h> zu 
setzen.

von Klaus (Gast)


Lesenswert?

Johannes M. schrieb:
> sprintf und LCD-Ausgaben

Funktioniert das Tatsächlich mit einem Standard HD44780 Display oder 
muss da noch irgendwie etwas umgebogen werden.

von Henry (Gast)


Lesenswert?

@Johannes: hab deine anmerkung mal umgesetzt -> kein Erfolg
@Klaus: Der Atmega läuft mit nem externen 8 MHz-Quarz. Fuses sind 
eigentlich gesetzt. Das mit "#define F_CPU" hab ich auch 
eingebaut(natürlich für mich passend mit 8000000UL ;) ) -> ebenfalls 
leider noch kein Erfolg

mfg
Henry

von holger (Gast)


Lesenswert?

>Es wäre nett, wenn mir jemand einen Tip geben könnte, wo der Fehler in
>meinem Code steckt bzw. was ich falsch gemacht habe.
1
void lcd_enable()
2
{
3
  lcd_port |= (1<<en); //von low -> high lese Werte von RS und RW ein
4
  _delay_ms(5);
5
  lcd_port &= ~(1<<en); // high -> low lese Datenleitungen ein
6
  _delay_ms(5);
7
  return;
8
}

Bei 10ms pro Enable Clock sollte man sich über gar nichts wundern.
Diese Delays ziehen sich durch deinen kompletten Code.

Und welcher Schwachkopf hat dir geraten Funktionen in eine
Header Datei zu legen?

von Henry (Gast)


Lesenswert?

Klaus schrieb:
> Johannes M. schrieb:
>> sprintf und LCD-Ausgaben
>
> Funktioniert das Tatsächlich mit einem Standard HD44780 Display oder
> muss da noch irgendwie etwas umgebogen werden.


Mit dem sprintf-Befehl kopiere ich bloß den Ausgabestring in ein 
char-Array und geben diesen anschließend Zeichen für Zeichen auf dem LCD 
aus.

mfg
Henry

von Klaus (Gast)


Lesenswert?

Aha! Danke Henry

von Henry (Gast)


Lesenswert?

holger schrieb:
> Bei 10ms pro Enable Clock sollte man sich über gar nichts wundern.
> Diese Delays ziehen sich durch deinen kompletten Code.
>
> Und welcher Schwachkopf hat dir geraten Funktionen in eine
> Header Datei zu legen?

wie macht man es denn am richtigsten ?

von Bernhard S. (b_spitzer)


Lesenswert?

Zusätzlich wird vor jeder Ausgabe noch mal "schnell" das Display 
gelöscht:
1
lcd_clear();
2
  char text[17];
3
  sprintf(text,"    %02d:%02d:%02d",zeit->stunden,zeit->minuten, zeit->sekunden);
4
  lcd_string(text);
ist unnötig wie ein Kropf, weil das Löschen ja auch reichlich Zeit 
braucht. Einfach die neuen Werte drüberbügeln und fertig. Wenn mal 
Geisterzeichen stehenbleiben, dann nach dem Ausgabestring ein paar 
Leerzeichen einfügen (ist hier aber dank %02d kein Problem).

@Henry: Kleine Nebenrechnung: ein Enable ist hier auf 10ms aufgebläht 
(2us reichen auch). Danach ist bei der Zeichenausgabe zur Sicherheit 
noch jedes mal ein kurzes Päuschen von 20ms. Pro Zeichen werden also 
eben schnell mal 60ms "Delayed". Dein Ausgabetext, der jede Sekunde raus 
soll hat 4 Leerzeichen (240ms) und 8 Nutzzeichen (480ms). Dazu noch die 
Löschfunktion und schon ist klar, woher die Zeitdauer kommt.

von Bernhard S. (b_spitzer)


Lesenswert?

Henry schrieb:
> am richtigsten
Ui, klasse Superlativ. Noch mal richtiger als richtig schon richtig war.

Wirf die delays raus, schaue auf das Busy-Flag des Displays und die 
Chose ist um Längen schneller.
Für den ersten schnellen Test kannst Du ja mal aus den 5ms bei Enable 
eine machen und die 20ms bei der Zeichenausgabe ganz rausschmeissen. Das 
reduziert den Zeitfraß schon mal um 90%...

von Michael (Gast)


Lesenswert?

Henry schrieb:
>> Bei 10ms pro Enable Clock sollte man sich über gar nichts wundern.
>> Diese Delays ziehen sich durch deinen kompletten Code.
>>
>> Und welcher Schwachkopf hat dir geraten Funktionen in eine
>> Header Datei zu legen?
>
> wie macht man es denn am richtigsten ?

z.B. indem man die Dauer des Enable-Pulse gerade etwas länger als lt. 
Datenblatt benötigt macht, d.h. du kannst als ersten Schitt ms durch µs 
ersetzen - spart an der Stelle schon mal einen Faktor 1000.

Funktionen in C-Datei legen und nur den Funktionkopf öffentlicher 
Funktionen (Header) in die H-Datei packen.

von Henry (Gast)


Lesenswert?

hmm ... wieder mal ein Beweis, dass mein Hirn nach 22.00 nicht mehr zu 
gebbrauchen ist. ;)

Ich hab eure Vorschläge eingepflegt und siehe da: es geht. Eigentlich 
auch logisch wenn man mal die Zeiten durchrechnet ... neija siehe erster 
Satz.

nochmal danke an alle

mfg
Henry

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.