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)?
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 :)
>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.
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
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.
>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;)
>>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.
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
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.
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.
>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.
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.
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
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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".