Forum: Mikrocontroller und Digitale Elektronik HD44780: BusyFlag oder Delay?


von niki (Gast)


Lesenswert?

Hallo zusammen,

euer Erfahrung nach ist es besser mit dem Busy Flag zu arbeiten oder 
eher mit einem Delay (muss nicht unbedingt solange warten und nichts 
tun, sondern kann auch in so einer Art State machine sein, wo ich jedes 
Mal prüfe ob ein Timer (mit einm Raster von 100us) abgelaufen ist oder 
nicht)?

von Eumel (Gast)


Lesenswert?

Busy Flag braucht einen Pin mehr und aufs Display schreibt man (aus 
Controller sicht) eh so selten, dass die Delays nicht wirklich ins 
Gewicht fallen.
Natürlich ist es mit Busy Flag etwas "sauberer"
Geschmackssache :)

von holger (Gast)


Lesenswert?

>euer Erfahrung nach ist es besser mit dem Busy Flag zu arbeiten oder
>eher mit einem Delay

Delay. Spart den RW Pin. Einfach an GND legen.
Die Schaltung funktioniert dann übrigends auch ohne Display
und hängt sich nicht auf beim Busycheck.

von Holger H. (onifred)


Lesenswert?

Hi,
habe ich erst letztens gemacht. Wie holger RW auf GND.
Buffer Array im RAM anlegen und im Timer Int alle paar ms jeweils ein 
Zeichen zum Display senden. Anwendung kann dann ohne Verzögerung
ins RAM schreiben.
Gruß Holger

von MagIO (Gast)


Lesenswert?

Naja, ohne Verzögerung würde ich dazu nicht sagen, schließlich verzögert 
der Interrupt doch konstant... es sei denn die ausgabefunktion schaltet 
den interrupt an und die IRS schaltet sich selbst wieder aus, wenn alle 
Zeichen gesendet wurden.

von spess53 (Gast)


Lesenswert?

Hi

>Delay. Spart den RW Pin. Einfach an GND legen.

Man verbaut sich dadurch natürlich auch die Möglichkeit eigene Zeichen 
zu definieren.

MfG Spess

von holger (Gast)


Lesenswert?

>Naja, ohne Verzögerung würde ich dazu nicht sagen,

Würde ich mit Busycheck auch nicht sagen.
Wenn man es geschickt macht kommt man da wohl auch ohne
große Verzögerungen aus. Allerdings habe ich noch nie
gesehen wie viel Vorteil der Busycheck zeitlich bringen
könnte. Habs aber selber auch noch nie probiert.
Schande über mich. Eigentlich will ich sowas auch immer
wissen. Faulheit halt wenn der Code funktioniert wie er ist;)

von holger (Gast)


Lesenswert?

>>Delay. Spart den RW Pin. Einfach an GND legen.
>
>Man verbaut sich dadurch natürlich auch die Möglichkeit eigene Zeichen
>zu definieren.

Wieso? Wenn man das RW auf GND legt ist das Display Write only.
Die eigenen Zeichen kann man doch trotzdem schreiben.

von Eumel (Gast)


Lesenswert?

holger schrieb:
> Faulheit halt wenn der Code funktioniert wie er ist;)

Ist schon gut so, du weißt doch:"Never touch a running System"
;)

von Holger H. (onifred)


Lesenswert?

MagIO schrieb:
> Naja, ohne Verzögerung würde ich dazu nicht sagen, schließlich verzögert
> der Interrupt doch konstant... es sei denn die ausgabefunktion schaltet
> den interrupt an und die IRS schaltet sich selbst wieder aus, wenn alle
> Zeichen gesendet wurden.

Ich meinte damit, dass kein delay benötigt wird.
Refresh Rate von 32 ms auf dem Display langen wohl auch.
Und Timer Int ist ja sowieso meistens vorhanden.
Gruß Holger

von Ingo (Gast)


Lesenswert?

Also ich habe beides mal auf einem LCD ausprobiert, mit der Erkenntnis, 
das die CPU in dem Delay n Tick schneller durchkommt, da ja am LCD 
immernoch der Enable getoggelt werden muss, damit sich der Datenbus 
aktualisiert. Also, ich bleibe bei Delays...

In den paar us schafft der Controller nicht soooo viel und zeitkritische 
Sachen sollten sowieso nicht da platziert sein, wo sie stören.

Also in der While(1) Schleife das LCD über ein timertesteuertes Flag 
updaten.

von MagIO (Gast)


Lesenswert?

Ich glaube bei einem delay ist man eher konservativ und auch nicht 
wirklich gewillt die Verzögerung herauszufinden mit der es gerade noch 
funktioniert.
Und somit ist die Ausgabe eine ziemliche Zeitverschwendung und somit 
natürlich der Interrupt ne gute alternative. Allerdings kann man auch 
das besser oder schlechter lösen.
Es klang so, als ob die ISR konstant einen Framebuffer ans display 
verschickt. Das kostet natürlich konstant Zeit, auch wenn sich nix 
geändert hat.

Ich habe mal einen Treiber geschrieben, der mit busy gearbeitet hat. Der 
war dann so schnell, dass man auf dem display 2 zeilen mit jeweils 8 
custom charakter darstellen konnte, also quasi ein 64x16 grafik-bereich.

von holger (Gast)


Lesenswert?

>Ich glaube bei einem delay ist man eher konservativ und auch nicht
>wirklich gewillt die Verzögerung herauszufinden mit der es gerade noch
>funktioniert.

Siehe meinen ersten Post. Ohne Busycheck kann die Schaltung
auch ohne Display laufen ohne den Code zu ändern. Das würde
ich als Vorteil ansehen.

Ich hab noch keinen Code gesehen der im Busycheck noch ein Timeout
eingebaut hatte. Ist halt Geschmackssache.

>Ich habe mal einen Treiber geschrieben, der mit busy gearbeitet hat. Der
>war dann so schnell, dass man auf dem display 2 zeilen mit jeweils 8
>custom charakter darstellen konnte, also quasi ein 64x16 grafik-bereich.

Zeigen Angeber;)

In der Codesammlung war mal vor langer Zeit was ähnliches.
Hat aber nur 8 Zeichen in einer Zeile benutzt. Irgendwie
nehm ich dir das nicht ab das du Custom Chars so schnell ändern
kannst das das Zeichen 0 in zwei Zeilen unterschiedlich dargestellt 
wird.

von None (Gast)


Lesenswert?

Meine Erfahrung ist, dass die meisten Displaycontroller nicht den E-Pin 
setzen und somit nur ein Delay als echte Lösung bleibt.
Ich habe mich schon oft gefragt, warum sie das in den Specs angegeben, 
wenn sich keiner daran hält.

von MagIO (Gast)


Angehängte Dateien:

Lesenswert?

Hat ne Weile gedauert ... hatte das so nicht mehr aufgebaut, aber hier 
der Beweis:

von Axel S. (a-za-z0-9)


Lesenswert?

niki schrieb:

> euer Erfahrung nach ist es besser mit dem Busy Flag zu arbeiten oder
> eher mit einem Delay

Wie immer: Kommt darauf an.

Es ist in jedem Fall viel sauberer, das busy-Flag auszuwerten.
Klar gibt es Fälle, bei denen man den einen Pin für R/W nicht mehr hat. 
Oder wo das Rücklesen der Datenleitungen nicht (einfach) möglich ist. 
Eben deswegen kommt es auf die Details an.

Das Problem mit dem Warten ist, daß man nie genau weiß wie lange man 
denn nun warten muß. Das hängt nämlich von der Taktfrequenz des HD44780 
ab, die über einen Widerstand festgelegt wird. Exemplarschwankungen, 
Temperatur- und Betriebsspannungsabhängigkeit machen locker eine 
Unsicherheit um Faktor 2 aus. Dazu kommen die vielen 44780 Clones, die 
sich manchmal deutlich anders verhalten als das Original.
D.h. selbst wenn man alles gründlich getestet haben sollte, liefert der 
Hersteller womöglich nächste Woche Displays mit einem anderen Chip unter 
der Vergußmasse und schon schaut man in die Röhre.

Am Ende macht man dann die Delays deutlich länger als sie nominal sein 
müßten, weil es viel mehr Sackstand wäre, einen Timingfehler zu finden. 
Und das alles womöglich nur, weil man zu faul war, eine einzige weitere 
Leitung zwischen µC und Display zu ziehen.

Deswegen mein Fazit: solange es nicht extrem teuer wäre, den Status des 
Displays zurückzulesen, sollte man das implementieren.


XL

von B. S. (bestucki)


Lesenswert?

Axel Schwenke schrieb:
> Deswegen mein Fazit: solange es nicht extrem teuer wäre, den Status des
> Displays zurückzulesen, sollte man das implementieren.

Sehe ich auch so. Und wenn man an der entsprechenden Datenleitung einen 
Pull-Down anschliesst, bleibt das Programm auch nicht hängen, wenn das 
Display nicht angeschlossen ist.

Ich persönlich lese immer das Busy-Flag. Ein Timeout habe ich nicht 
eingebaut, da war ich zu faul.

von Herr M. (herrmueller)


Lesenswert?

Manchmal möchte man auch das Display Ram auslesen, ohne es komplett im 
Ram zu spiegeln. Ich hatte mal eine Scroll-Funktion geschrieben, die den 
Displayinhalt im Displayram nach oben schiebt. Damit war die Busy Flag 
Abfrage ein Abfallprodukt, das aber die Geschwindigkeit erhöht hat.

von Peter D. (peda)


Lesenswert?

MagIO schrieb:
> Hat ne Weile gedauert ... hatte das so nicht mehr aufgebaut, aber hier
> der Beweis:

Was für ein seltsames LCD ist das denn?
Welcher Controller ist da drin?

Ich kenne das vom HD44780 so, daß sich beim Ändern eines Custom-Zeichens 
alle bereits dargestellten gleichen Zeichen mit ändern.
D.h. das LCD hat keinen kompletten Pixel-RAM, sondern nur einen 
Zeichen-RAM.
Und beim Multiplexen werden die 5*7 Pixelmuster jedesmal neu aus der 
Zeichentabelle gelesen.

von MagIO (Gast)


Lesenswert?

Das ist ein ganz normales HD44780!

Wie schon gesagt, das senden von Daten geht so schnell, dass man 
folgendes machen kann:

1. Ersetzen der Zeile, die gerade custom Characters enthält mit 
Leerzeichen
2. Schreiben der 8 custom Character pixel-daten (64 byte)
3. Ersetzen der Leerzeichen der jeweils anderen Zeile mit den 8 custom 
Characters
4. ein klein wenig warten
5. goto 1

Dabei kommt einem zu Gute, dass die LCD-pixel ne ganze Weile brauchen um 
von Schwarz auf durchsichtig umzuschalten und es entsteht der Eindruck, 
dass man 2 Zeilen mit jeweils 8 custom Charactern sieht.

Ginge natürlich auch mit einem 4x4-Bereich.

Bei 3 Zeilen a 8 Charactern fängt es allerdings an zu blinken.

von Soul E. (Gast)


Lesenswert?

holger schrieb:

> Siehe meinen ersten Post. Ohne Busycheck kann die Schaltung
> auch ohne Display laufen ohne den Code zu ändern. Das würde
> ich als Vorteil ansehen.

Wobei ein Pulldown an D7 den gleichen Effekt hat.


Delay ist insofern etwas undankbar, als dass die Displays sich in der 
Geschwindigkeit locker um den Faktor 10 unterscheiden. Wenn Du Dein 
Delay an ein langsames Exemplar angepasst hast, wartest Du beim nächsten 
Display zu lange. Oder umgekehrt, der Kollege, der Deine Schaltung 
nachbaut und mit seinem HD44780-Imitat ausstattet, klagt über fehlende 
Zeichen.

von Rudolph (Gast)


Lesenswert?

Warum sollte ein Programm mit Abfrage des Busy-Flags hängen bleiben wenn 
man das Display entfernt?

Das kann nur passieren wenn man so ein bescheuertes Konstrukt aufzieht 
das äquivalent zum Delay() ist.
Also solange warten wie das Display beschäftigt ist.

Herzlichen Glückwunsch, der Controller stellt sich für die Zeit des 
Display-Zugriffs tot und verbraucht dabei maximale Leistung.


Alternativ kann man das Busy-Flag aber auch benutzen um alle paar ms mal 
beim Display nachzufragen wie es ihm denn geht.
Ist es bereit, bekommt es das nächste Zeichen.
Wenn nicht läuft das Programm direkt weiter.

Da bleibt garnichts hängen ohne Display.

von onifred (Gast)


Lesenswert?

Rudolph schrieb:
> Alternativ kann man das Busy-Flag aber auch benutzen um alle paar ms mal
> beim Display nachzufragen wie es ihm denn geht.
> Ist es bereit, bekommt es das nächste Zeichen.
> Wenn nicht läuft das Programm direkt weiter.

Vielen Dank. Bin überzeugt worden.
Werden bei meinen nächsten Projekten das Busy Flag benutzen.
Gruß Holger

von Niki (Gast)


Lesenswert?

Bei der 4Bit Kommunikation wie lang ist eigentlich der Delay zwischen 
senden von High nibble und low nibble?
1
tmp = data;
2
tmp >>= 4;
3
tmp &= 0x0F;
4
LCD_PORT &= 0xF0;
5
LCD_RS = 1;
6
LCD_PORT |= tmp;
7
LCD_E = 1;
8
Nop();
9
Nop();
10
LCD_E = 0;
11
12
// >>>>> Delay??? oder direkt weiter mit dem Senden
13
14
LCD_PORT &= 0xF0;
15
data &= 0x0F;
16
LCD_PORT |= data;
17
LCD_E = 1;
18
Nop();
19
Nop();
20
LCD_E = 0;

von spess53 (Gast)


Lesenswert?

Hi

>Bei der 4Bit Kommunikation wie lang ist eigentlich der Delay zwischen
>senden von High nibble und low nibble?

Kein Delay.

MfG Spess

von Felix P. (fixxl)


Lesenswert?

Ich habe bisher immer mit dem Busy-Flag gearbeitet, obwohl das - wie 
schon vielfach erwähnt - einen Portpin mehr benötigt als die 
Delay-Variante. Die Verwendung des RW-Pins bietet neben der 
Busy-Flag-Abfrage auch den Vorteil, dass man die aktuelle Cursorposition 
auslesen und dann Dinge wie einen automatischen Zeilenumbruch 
implementieren kann.

von Rudolph (Gast)


Lesenswert?

Felix Pflaum schrieb:
> auch den Vorteil, dass man die aktuelle Cursorposition
> auslesen und dann Dinge wie einen automatischen Zeilenumbruch
> implementieren kann.

Ich benutze ein Array im Speicher das ich immer wieder Zeichen für 
Zeichen an das LCD schicke.
Die Funktion die das macht weiss dann sowieso immer wo der Cursor steht.

Und alle anderen Programm-Teile können beliebig oft irgendwohin in das 
Array schreiben ohne auf irgendwas warten zu müssen.

2x16 bis 4x20 sollte man eigentlich dafür übrig haben.

von Maxx (Gast)


Lesenswert?

holger schrieb:
> Ich hab noch keinen Code gesehen der im Busycheck noch ein Timeout
> eingebaut hatte. Ist halt Geschmackssache.

Mit Geschmack hat das weniger zu tun, als mehr den bewussten Umgang mit 
Fehlersituationen. Ein Code, der auf externe Ereignisse oder fehlen 
dieser in eine unerwünschte Endlosschleife geht sollte in jedem Review 
auffallen und korrigiert werden.

Das ist nicht beschränkt auf HD44780, sondern auf alle IOs. Wenn etwas 
Unerwartetes geschieht soll sich ein SW System "fangen" oder zumindest 
in einen definierten Fehlerzustand übergehen. Andernfalls kann und wird 
im laufenden Betrieb ein Fehler (Bedienung, EMV, Alterung, ...) zum 
Systemshalt führen von dem mit gut Glück genau derjenige den Grund 
erraten kann der's Implementiert hat. Für jeden anderen "spinnt" das 
System.

von Icke ®. (49636b65)


Lesenswert?

Rudolph schrieb:
> Ich benutze ein Array im Speicher das ich immer wieder Zeichen für
> Zeichen an das LCD schicke.

So mach ich das auch. Der eigentliche Refresh des LCDs erfolgt dann wann 
immer es reinpaßt.
Ich frage ebenfalls das Busy ab und habe seitdem so gut wie keine 
Probleme mehr mit fehlerhaften Darstellungen oder einfrierendem Display.

von Peter D. (peda)


Lesenswert?

Ganz ohne Busy-Test und ohne Delay:

Beitrag "Formatierte Zahlenausgabe in C"

von Maxx (Gast)


Lesenswert?

Peter Dannegger schrieb:
> ohne Delay

Ein Timer im CTC Mode / 1ms dürfte wohl recht eindeutig unter Delay 
fallen. Nachdem laut org. Datenblatt nach den Timings schaut sogar 
ziemlich fette.

von Rudolph (Gast)


Lesenswert?

Maxx schrieb:
> Ein Timer im CTC Mode / 1ms dürfte wohl recht eindeutig unter Delay
> fallen.

Nein, delay() ist aktives Verbrennen von Taktzyklen.
Die 1ms ISR läuft vielleicht so 4µs, ganz grob überschlagen,
den Rest der Zeit kann der Controller auf so nebensächliche Dinge wie 
Benutzer-Eingaben reagieren.

2x16 Zeichen sind mit Zeilenwechsel dann 34 ms für den kompletten 
Inhalt.
Oder auch schlapp 30 Mal pro Sekunde das komplette LCD.
Dabei ist der µC etwa 4ms/1s beschäftigt.

Ein busy-wait mit dem Busy-Flag wartet vielleicht so 42µs effektiv weil 
die LCDs normal so 40µs brauchen.
-> 1,5ms in denen der Controller nicht mehr reagiert wenn man einen 
kompletten Refresh macht in in denen der Controller sinnlos volle 
Leistung benötigt.
Auch 30 Bildwechsel pro Sekunden -> 45ms/1s µC "tot".

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.