Da es hier tatsächlich einige seltsame Menschen gibt möchte ich nun
zuallererst um eine Sache bitten:
Keine RTFM-Mahnungen! Ich kann Datenblätter lesen, die vom Atmega16 und
-8 kenne ich fast auswendig (Achtung Ironie!) - manchmal will man eben
die Antwort klar formuliert von einem Mitmenschen bekommen, technisches
Englisch ist selbst für geübte anstrengend.
Dieses beim myAVR-Board verbaute LCD; ist der "Display-Shift" immer so
"schlierenhaft" oder kann man das umgehen?
Wieso kommt der Text, welcher links "anschlägt" (beim Left-Shift) nicht
sofort wieder rechts raus sondern schwirrt ca. einen ganzen
"Shift-Zyklus" über im Nichts herum und trifft verspätet ein?
Warum muss man 5ms und länger (!) für einzelne Befehle warten - beim
Powerup ist das ja durchaus noch verständlich, aber µCs haben
durchschnittliche Taktraten von mehreren MEGAhertz - da sind
MILLIsekunden eine lange Zeit; ich "spreche" über meinen Mega8 doch mit
einem anderen µC, oder??
Hi,
hast du mal das Datenblatt gelesen ??..ne warn Scherz..also
was genau meinst du mit schlierenhaft ??.
Verschwimmt die Schrift oder wie meinst du ?
Also das mit dem Verschieben und das der Text nicht sofort wieder rechts
erscheint, dürfte daran liegen, dass das Ram des Display größer ist als
die Zeichen die tatsächlich auf dem Display dargestellt werden.
Es ist sozusagen ein "unsichtbarer Bereich" vorhanden.
Sollte man mit einer entsprechenden lcdroutine und/oder einer Funktion
lösen können.
Bin mir nicht sicher ob in dem zusätzlichen Handbuch (Lehrheft LCD
Programmierung)
auf dieses Problem näher eingegangen wird.
DAs mit der Zeit ist so ne Sache..im Gegensatz zu dem Atmega oder
anderen Controllern, ist der Controller bzw das Display eher träge.
Daher muss bei gewissen Befehlen einige Zeit gewartet werden.
Allerdings sind in den Handbüchern keine exakten Wartezeiten angegeben.
Dafür am Besten ans Datenblatt halten um Fehler zu vermeiden.
Man kann sich mit der Zeit etwas heruntertasten und funktioniert
trotzdem.
enige Nanosekunden klingt natürlich recht kurz, ist für den Atmega aber
schon ne Weile bzw. einige Taktzyklen.
Trotzdem ist diese Zeitverzögerung mit dem bloßen Auge nicht zu erkennen
Gruß Alex
> Verschwimmt die Schrift oder wie meinst du ?
So ähnlich - es ist der selbe Effekt wie bei trägen TFT-Monitoren; für
den Bruchteil einer Sekunde ist noch die alte Schrift lesbar ... sieht
sehr unschön aus
> Bin mir nicht sicher ob in dem zusätzlichen Handbuch (Lehrheft LCD> Programmierung)> auf dieses Problem näher eingegangen wird.
Ich auch nicht - ich hab einfach mal den Beispiel-ASM-Code in C
übersetzt :-); ich muss sagen dass man dabei recht viel versteht,
zusammen mit der Displaykommando-Tabelle des LCD-AddOns kann ich
(hoffentlich) jedes Problem lösen
> enige Nanosekunden klingt natürlich recht kurz,
ich muss sogar in den MILLIsekunden-Bereich gehen. Genauer gesagt: 5 ms
vor jedem Displaykommando, bei weniger wird Müll angezeigt. Naja, das
muss wohl ein SEHR träger µC sein.
(An dieser Stelle bitte ein LCD-verachtendes "Pfff" denken)
Hi
>Wieso kommt der Text, welcher links "anschlägt" (beim Left-Shift) nicht>sofort wieder rechts raus sondern schwirrt ca. einen ganzen>"Shift-Zyklus" über im Nichts herum und trifft verspätet ein?
Weil der Speicher für eine Zeile grösser als der dargestellte Bereich
ist. Das was du siehst ist nur ein Teil der 'Zeile'.
>Warum muss man 5ms und länger (!) für einzelne Befehle warten - beim>Powerup ist das ja durchaus noch verständlich, aber µCs haben...
Brauchst du ja nicht. Einfach Status des LCD auswerten.
>ich "spreche" über meinen Mega8 doch mit einem anderen µC, oder??
Aber ein HD44780 läuft lt. Datenblatt nur mit 270kHz
>Dieses beim myAVR-Board verbaute LCD; ist der "Display-Shift" immer so>"schlierenhaft" oder kann man das umgehen?
Weiss ich auch nicht. Vielleicht mal ein anderes testen.
MfG Spess
Hallo,
Daten zum LCD-Display stehen im Datenblatt des LCD-Displays und dessen
Controller, da hilft es wenig, wenn Du das Mega8/16 Datenblatt fast
auswendig kannst...
Die Display sind dazu da, um Text anzuzeigen. Einfach so, statisch.
Shift geht durchaus auch, mehr als so ca. 2-3 Zeichen/s schieben macht
aber eben wenig Sinn, weil die Dinger sehr lahm sind.
Soll ja auch kein Film drauf lasufen... ;-)
Zum verschwindenden Text kam ja schon der Hinweis auf die Organisation
des Display-Rams. Steht auch im Datenblatt. Des Displays, nicht des
ATMega.
Gruß aus Berlin
Michael
Ja das Problem mit der sauberen Darstellung beim Shiften ist bei solchen
einfachen Displays nicht so einfach.
Du schiebst ja nicht pixel für pixel nach links oder rechts wie bei
einem grafischen Display zB.
Das heißt die "Auflösung" des Displays ist für solche Zwecke nicht so
besonders gut zu gebrauchen.
Dazu die Trägheit und eventuell etwas zu aufwändiger Code macht das
saubere Shiften unmöglich.
Ob sich da was tricksen lässt ist die Frage.
Aber ist ja auch nur ein einfaches Display.
Könnte mit einer Code Optimierung vielleicht sauberer aussehen.
Gruß Alex
Ich denke es hängt auch davon ab wieviele Zeichen du gleichzeitig
shiften willst.
Je mehr Zeichen desto aufwändiger und länger die Verarbeitung.
Kann da aber nur vermuten da ich deinen Code nicht kenne
lol ja hast recht ..wo hab ich denn nochmal gelesen, dass die _delay
Funktion sowieso nur 200 irgendwas ms verzögert ??
Du könntest also auch _delayms(50000) eingeben..sie würde nicht mehr
Zeit brauchen...
Hi
>Wie?
Es gibt einen Befehl 'Read busy flag & address'. Damit wird ein Byte vom
LCD gelesen, das ein Busy-Flag enthält. Bei Busy-Bit=H ist das LCD
beschäftigt. Bei L kann losgelegt werden. Allerdings verzichten manche
rudimentären µC-Interfaces auf die Möglichkeit des Lesens vom Display.
Dann geht das nicht. Selber Schuld.
MfG Spess
P.S. Doch mal auch das Datenblatt vom Displaycontroller lesen. Sonst ist
die Bildung etwas einseitig.
>Allerdings verzichten manche>rudimentären µC-Interfaces auf die Möglichkeit des Lesens vom Display.>Dann geht das nicht. Selber Schuld.
Wer wartet schon aufs Display?
Ein bißchen Shadow-RAM für das Display reservieren.
Interruptausgabe 1ms pro Zeichen und gut is ;)
spess53 wrote:
> Hi>>>Wie?>> Es gibt einen Befehl 'Read busy flag & address'. Damit wird ein Byte vom
Ah .. ich hab zuerst das Datenblatt des HD4470 gelesen, sah das
Busy-Flag und konnte aber keine Umsetzung in dem LCD-Datenblatt erkennen
- die letzte Zeile hab ich wohl übersehen. Danke!
Hat noch jemand Vorschläge für das Schlierenproblem?
So, dank der grandiosen Hilfe von spess konnte ich den Code nun
wunderschön an den LCD-Controller anpassen, mit einer Ausnahme: nach dem
schreiben von Display-Zeichen ist das Busy-Flag scheinbar dauerhaft auf
1 (also "Busy"). Kann mir jemand erklären warum?
gemeint ist in meinem Code die Funktion "lcdout_single" --> wenn man
"waitForBusyFlag()" wieder aktiviert rödelt der Atmel ständig in der
Schleife herum, wie ich mir bereits durch die Ausgabe an PortC.0 selbst
bestätigt habe (is ne LED dran).
holger wrote:
>>>> waitForBusyFlag();> Löschen!
done. Jetzt zeigt das Display nur abwechselnd Datenmüll und schwarze
Kästchen an. Und die LED leuchtet (--> Schleife).
Aus deinem letzten Code Post:
void enable()
{
PORTD |= (1 << PD3);
PORTD &= ~(1 << PD3);
}
Enable High ist vermutlich zu schnell.
Warum hast du das _delay_us entsorgt?
Hallo,
DDRC |= (1<<PC0);
PORTB |= (1<<PB0);
while((PIND & 0x80) == 0x80)
{
PORTC |= (1<<PC0);
asm volatile("nop");
}
Du schaltest hier die Datenrichtung von PC0 um?
Du liest in der Schleife PIND ein?
Die Daten vom Display sind gültig während! E auf H ist, nach der
H/L-Flanke ist das Display wieder im TriState...
Warum gibst Du den Bits nicht ein paar sprechende Namen?
PORTB |= (1<<LCD_RS) (oder was am Bit auch immer dranhängt)
liest sich besser als
PORTB |= (1<<PB0);
Oder gegt das in C nicht (bin immernoch ASM-Programmierer...)?
Gruß aus Berlin
Michael
Michael U. wrote:
> Du schaltest hier die Datenrichtung von PC0 um?> Du liest in der Schleife PIND ein?
Ja, an PortC liegt eine LED. PortD ist das eigentliche Datenbyte für das
LCD ...
> Die Daten vom Display sind gültig während! E auf H ist, nach der> H/L-Flanke ist das Display wieder im TriState...
Jap. Und genau das nutze ich doch aus ... ?
> Warum gibst Du den Bits nicht ein paar sprechende Namen?
Weil ich Redundanz verabscheue ... in meinem Berufsalltag erhöht das
regelmässig den "WTFs/min"-Index
Hallo,
Vorname Nachname wrote:
> Michael U. wrote:>>> Du schaltest hier die Datenrichtung von PC0 um?>> Du liest in der Schleife PIND ein?> Ja, an PortC liegt eine LED. PortD ist das eigentliche Datenbyte für das> LCD ...
Gut, ich muß jetzt nicht verstehen, warum man die Datenrichtung ändert,
wenn eine LED dran hängt. Ich schalte LEDs mit dem Portzustand ein und
aus.
Ich suche die Stelle, wo Du zum Lesen des Busybits die Datenleitungen
des LCD am AVR auf Eingang umschaltest. Wie willst Di sonst da was lesen
können?
>>> Die Daten vom Display sind gültig während! E auf H ist, nach der>> H/L-Flanke ist das Display wieder im TriState...> Jap. Und genau das nutze ich doch aus ... ?
Naja, hätte das Bit PD3 LCD_E oder so geheissen, wäre es wohl sogar mir
aufgefallen......
>> Warum gibst Du den Bits nicht ein paar sprechende Namen?> Weil ich Redundanz verabscheue ... in meinem Berufsalltag erhöht das> regelmässig den "WTFs/min"-Index
Ich wümsche Dir mit solchen Quellen viel Spaß, wenn Du die in ein paar
Monaten mal wieder anfäßt...
Gruß aus Berlin
Michael
Michael U. wrote:
> Ich suche die Stelle, wo Du zum Lesen des Busybits die Datenleitungen> des LCD am AVR auf Eingang umschaltest. Wie willst Di sonst da was lesen> können?
1
PORTB|=(1<<PB0);
> Ich wümsche Dir mit solchen Quellen viel Spaß, wenn Du die in ein paar> Monaten mal wieder anfäßt...
so etwas trainiert und fördert Kompetenz. Wenn man etwas immer wieder
überdenken oder gar neu lernen muss fliesst es garantiert mit der Zeit
ins Langzeitgedächtnis und ist somit sehr schnell abrufbar
>> Ich wümsche Dir mit solchen Quellen viel Spaß, wenn Du die in ein paar>> Monaten mal wieder anfäßt...>so etwas trainiert und fördert Kompetenz. Wenn man etwas immer wieder>überdenken oder gar neu lernen muss fliesst es garantiert mit der Zeit>ins Langzeitgedächtnis und ist somit sehr schnell abrufbar
So etwas fördert unübersichtliche Programmierung.
In zwei Monaten weisst du selber nicht mehr was du da
gemacht hast. Dein Nachfolger wird damit auch erst mal
zu kämpfen haben. Aber ich bin mir sicher das genau das
dein Ziel ist.
dummy wrote:
> zu kämpfen haben. Aber ich bin mir sicher das genau das> dein Ziel ist.
Und ich bin mir sicher dass du nur ein Troll bist und nicht die
geringste Ahnung von professioneller Programmierung hast.
Deine scheinbare "Unübersichtlichkeit" wandelt sich ganz schnell zu
"logischer Ordnung" sobald man mal die Funktionsweise des Programms
verstanden hat. Wenn man eben noch nicht einmal die Grundzüge versteht
... tja.
Ich muss mich täglich mit kryptischen Namen auseinandersetzen, die aber
genauer betrachtet mehr als logisch und durchgehend statisch sind, dies
garantiert bei grösseren Projekten die
Nachvollziehbarkeit/Erweiterbarkeit - aber ich will dich jetzt nicht mit
OOA-Prinzipien überfordern.
Hat jemand was Sinnvolles beizutragen? Vorzugsweise spess oder gar
holger?
Vorsicht Offtopic!
>> Warum gibst Du den Bits nicht ein paar sprechende Namen?> Weil ich Redundanz verabscheue ... in meinem Berufsalltag erhöht das> regelmässig den "WTFs/min"-Index
Stimmt, das erhöht die "WhatTheF*ckIsThis/min"-Index der QS-Kollegen
beim Peer Code Review. Die zwingst du, die ansonsten an der Stelle
redundanten Datenblätter auch wirklich mal zu benutzen, um zu verstehen,
was deine magische 42 an der Stelle bedeutet.
Blablub ... ich geh dann mal Werte in mein nicht funktionierendes
Display kloppen, da ja ausser den Hobby-Experten keiner mehr weiter
weiss. Spess/holger? Habt ihr noch nen Tip? Das wäre schön ..
Hi
Ich kann dir nur meine Assmblerroutine anbieten. Das C-Gedödel muss ich
mir nicht antun.
wrdat10: sbr r17,1<<lc_e ; Enable
out lc_ctl_out,r17
nop
nop
in r16,lc_dat_in ; Read
cbr r17,1<<lc_e ; Disable Anzeige
out lc_ctl_out,r17
andi r16,$80 ; BIT7=0
breq wrdat20 ; wenn ja weiter
nop
nop ; etwas zeit lassen
rjmp wrdat10
MfG Spess
spess53 wrote:
> cbr r17,1<<lc_e ; Disable Anzeige> out lc_ctl_out,r17>> andi r16,$80 ; BIT7=0> breq wrdat20 ; wenn ja weiter> nop> nop ; etwas zeit lassen> rjmp wrdat10>> MfG Spess
Ganz genau so mach ich das ja auch. Führst du diese Überprüfung auch
beim schreiben von Zeichen durch?
dummy wrote:
> Wer wartet schon aufs Display?> Ein bißchen Shadow-RAM für das Display reservieren.> Interruptausgabe 1ms pro Zeichen und gut is ;)
Dem ist eigentlich nichts mehr hinzuzufügen, weil das mit Abstand die
effektivste Lösung ist. Keinerlei Wartezeiten oder Busy-Polling nötig.
Ich hab mir auch ganz schnell angewöhnt, den IO-Pins Namen zu geben. Der
Code wird dadurch wesentlich besser lesbarer und modularer.
Oftmals haben IO-Pins Spezialfunktionen und wenn man diese benötigt, muß
man das LCD dann an andere Pins legen.
Die mühseligen Namenlosen müssen dann ihren LCD-Treiber komplett neu
schreiben.
Aber die cleveren Namenbenutzer ändern einfach nur die Pin-Definitionen
im h-File und alles läuft wieder:
http://www.mikrocontroller.net/attachment/30300/lcd_drv.zip
Peter
Peter Dannegger wrote:
> Die mühseligen Namenlosen müssen dann ihren LCD-Treiber komplett neu
Falsch. Stichwort "Search & Replace". Jeder noch so schlechte Texteditor
kann das. Statt sich dann mit den eigenwilligen Bezeichnungen anderer
rumzuquälen gewöhnt man sich ein einziges Mal (!) an standardisierte (!)
Bezeichnungen und liegt immer richtig.
Im Übrigen ist
1
PORTD|=(1<<PD3)
nicht wirklich eine Magic Number,
1
PORTD|=8
dafür aber sehr, schliesslich steht PD3 logischerweise für Port D, Pin
3 -- das ist mehr als nachvollziehbar.
Genau das war wohl auch der einzigste Kritikpunkt an meinem Code: in
meinen Kommando-Funktionen verwende ich nur hexadezimale Angaben ...
aber das war ja auch nur ein Test-Konstrukt und wird für meine
dauerhaften Aufgaben auch nicht so bleiben.
Wenn man nun die Standard-Bezeichnungen verwendet genügt Jahre danach
ein schlichter Blick in das Datenblatt und der grobe Überblick über
"Werkstück" um alles zu verstehen, bei diesen tollen Substitutionen ist
erstmal ein Verständnis vom kompletten (!) Code nötig - im grösseren
Umfeld ist das ein Killer.
Vorname Nachname wrote:
> Peter Dannegger wrote:>> Die mühseligen Namenlosen müssen dann ihren LCD-Treiber komplett neu> Falsch. Stichwort "Search & Replace".
Ja, das ist ein sehr schönes Werkzeug, um viel Unheil anzurichten.
Es ist nämlich ein strohdummes Werkzeug, das nicht wissen kann, ob eine
richtige Stelle zuwenig oder eine falsche Stelle zuviel replaced wurde.
Frag dochmal nen professionellen Programmierer. Wenn immer möglich, sind
Hardwareanpassungen nur im h-File vorzunehmen, das c-File bleibt
unangetastet.
> Im Übrigen ist>
1
PORTD|=(1<<PD3)
> nicht wirklich eine Magic> Number
Für jeden, der Deinen Schaltplan nicht kennt, ist sowas völlig
unverständlich.
Peter
Hi
>Dem ist eigentlich nichts mehr hinzuzufügen, weil das mit Abstand die>effektivste Lösung ist. Keinerlei Wartezeiten oder Busy-Polling nötig.
Tausende Programmierer haben dieses Problem schon (ohne dieses
Forum)erfolgreich erfolgreich gelöst. Wer kann dann von dann sagen, dass
(s)eine Methode die effektivste ist.
MfG Spess
Sacht ma kann dat sein dass der LCD-Controller n bischen verbugt is? Ich
erhalte hier zufällige (!) Funktion bei ein und demselben Quelltext,
manchmal ist das Busy-Bit endlos auf HIGH und manchmal zeigt es absolut
korrekt an, direkt nach LCD-Kommandos ist es schon garnicht zu
gebrauchen und zudem bleibt es auch zufällig lange an/aus. Hat jemand
schonmal gute (!) Erfahrungen mit dem BF unter avr-gcc auf einem
myAVR-Board gemacht?
Hallo,
naja, die "Kleinigkeit", daß er ein Bit auf Eingang setzt beim Busy
lesen, das Display aber seinen ganzen Port auf Ausgang, stört ihn ja
auch nicht.
Vielleicht stört es aber irgendwann den AVR- oder Displayport wenn die
restlichen Pins gegeneinander kämpfen...
Naja, Datenblatt lesen will eben auch gelernt sein.
Aber er weiß und kann doch ohnehin alles besser.
Was solls also...
Gruß aus Berlin
Michael
spess53 wrote:
> Tausende Programmierer haben dieses Problem schon (ohne dieses> Forum)erfolgreich erfolgreich gelöst. Wer kann dann von dann sagen, dass> (s)eine Methode die effektivste ist.
Die reine Logik.
Eine Methode ohne Wartezeiten oder Busypolling ist nunmal effektiver als
jede andere mit. Da beißt die Maus keinen Faden ab.
In der Regel sind die Wartezeiten für das LCD aber tolerierbar, da ja
Ausgaben erstmal gelesen werden müssen.
Es gibt allerdings auch Anwendungen, wo die CPU schon gut ausgelastet
ist oder die Mainloop möglichst kurz sein muß. Da ist dann die
Interruptmethode das Mittel der Wahl.
Peter
Hi
>Eine Methode ohne Wartezeiten oder Busypolling ist nunmal effektiver als>jede andere mit. Da beißt die Maus keinen Faden ab.
Sinnvolle Ausgabeintervalle für komplette Displayinhalte liegen im
Sekundenbereich. In den meisten Fällen werden nur kleine Teile des
Displays aktualisiert. Und das sollte auch nur in Abständen vorkommen,
die der Betrachter registrieren kann. Also haben AVRs zwischen zwei
Ausgaben fast unendlich Zeit. Warum soll ich dann in der Zeit den AVR
mit unsinnigen LCD-Ausgaben belasten.
MfG Spess
Michael U. wrote:
> Hallo,>> naja, die "Kleinigkeit", daß er ein Bit auf Eingang setzt beim Busy> lesen, das Display aber seinen ganzen Port auf Ausgang, stört ihn ja
Naja, die "Kleinigkeit" dass du nichtmal weisst wie ein myAVR-Board
aufgebaut ist ODER gar Quelltext lesen kannst ...
das LCD selbst bzw. dessen Datenbits/-Pins haben rein GARNICHTS mit
PORTB zu tun, dort sitzt nämlich das Busyflag und ihr Kind.
> das Display aber seinen ganzen Port auf Ausgang
Das DISPLAY hat schonmal garkeinen Port, höchstens
Ausgangspins/Datenleitungen und einstellen liesse sich an dem
zuständigen, mit nem Silikattropfen bedeckten µC auch nichts.