Forum: Compiler & IDEs LCD Peter Fleury


von Thomas (Gast)


Lesenswert?

Hallo

Ich verwende AVR Studio 4.18 und Win AVR. Weiters besitze ich das 
RN-Control 1.4 Mega32 Board von
http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=64&products_id=10

Habe mir die LCD Dateien von Peter Fleury downgeloadet und eingebunden.
lcd.h
lcd.c
test_lcd.c

Als Nächstes habe ich mein zweizeiliges Display an PORTB angeschlossen 
und in der lcd.h für #define LCD_PORT  PORTB eingetragen.

Laut der test_lcd.c Datei müsste irgendetwas am LCD-Display angezeigt 
werden, tut es aber nicht.

Kann mir jemand sagen, welche Änderungen im Programm noch vorzunehmen 
sind.

Danke für eure Hilfe

von display (Gast)


Lesenswert?

was hast du wie und wo angeschlossen (Datenleitungen, RW, E ...)??

von Thomas (Gast)


Lesenswert?

Bezeichnung-LCD    Pin-µC
1   Vss             GND
2   Vcc             5V
3   Vee             Poti
4   RS              PD4 am AVR
5   RW              GND
6   E               PD5 am AVR
7   DB0             offen (unbenutzt)
8   DB1             offen (unbenutzt)
9   DB2             offen (unbenutzt)
10  DB3             offen (unbenutzt)
11  DB4             PD0 am AVR
12  DB5             PD1 am AVR
13  DB6             PD2 am AVR
14  DB7             PD3 am AVR

von Thomas (Gast)


Lesenswert?

Display funktionierte schon mit dem Tutorial von microcontroler.net

von Justus S. (jussa)


Lesenswert?

Thomas schrieb:

> 11  DB4             PD0 am AVR
> 12  DB5             PD1 am AVR
> 13  DB6             PD2 am AVR
> 14  DB7             PD3 am AVR

dann solltest du vielleicht auch in der lcd.h PORTD eintragen...

von Thomas (Gast)


Lesenswert?

Hab mich verschrieben! LCD an PORT B angeschlossen und in der lcd.h
#define LCD_PORT  PORTB eingetragen.

von Karl H. (kbuchegg)


Lesenswert?

Thomas schrieb:
> Display funktionierte schon mit dem Tutorial von microcontroler.net

Das ist der entscheidende Hinweis

> 5   RW              GND

Das geht nicht.
Die Fleury Lib will RW bedienen. Du MUSST diesen Pin am µC anschliessen 
und in die lcd.h eintragen.

von TEVA (Gast)


Lesenswert?

Hallo....
ich verwende  myavr Workpad Plus Demo und besitze Atmega8 MK1-Board.

Habe mir die LCD Dateien von Peter Fleury downgeloadet und eingebunden.
lcd.h

beim brennen bekomme ich Fehlermeldung:

Datei "globals.h" nicht gefunden...


muss man globals.h selber schreiben oder was gibt es da für 
alternative???
 Bin für jeden Tip Dankbar


Lieben Gruß TEVA

von Tobi P (Gast)


Lesenswert?

Hallo.Hab da ein ähnliches Problem. Ich hab keinen Pin mehr für RW frei. 
Lässt sich das irgenwie umgehen ? Einfach für RW Port = PORTE beim Mega 
8 reinschreiben geht nicht. Da meckert der Compiler. Ich kenn mich da 
noch nicht so aus...

von maximan (Gast)


Lesenswert?

andere lib verwenden ;) bzw. die Lib patchen, dass sie nicht mehr vom 
Display liest. So ganz am Rande, wieso macht sie das überhaupt?

von Tobi P (Gast)


Lesenswert?

Hat wohl irgenwas mit dem auslesen des Busy Flags zu tun. Wenn ich das 
richtig verstanden habe...

von Karl H. (kbuchegg)


Lesenswert?

Das hast du richtig verstanden.
Allerdings war Peter schlau genug, das auselesen des Busy Flags in einer 
einzigen Funktion zu konzentrieren.
Wenn du daher in dieser Funktion das Auslesen ganz einfach durch einen 
delay ersetzt, erfolgt kein Lesezugriff mehr und die Lib funktioniert.

(Die 'Vom LCD auslesen' Funktion geht klarerweise auch nicht. Aber das 
sollte logisch sein)

von Robert P (Gast)


Lesenswert?

Hallo Leute,

Wenn du daher in dieser Funktion das Auslesen ganz einfach durch einen
delay ersetzt, erfolgt kein Lesezugriff mehr und die Lib funktioniert.

Wie genau sieht die Lib dann aus ?

von Robert P (Gast)


Lesenswert?

Ich hab´s jetzt herausgefunden. :

in der LCD.C die Codezeilen :

static uint8_t lcd_waitbusy(void)

{
    register uint8_t c;

    /* wait until busy flag is cleared */
    while ( (c=lcd_read(0)) & (1<<LCD_BUSY)) {}

    /* the address counter is updated 4us after the busy flag is cleared 
*/
    delay(2);

    /* now read the address counter */
    return (lcd_read(0));  // return address counter

}/* lcd_waitbusy */



in :

static uint8_t lcd_waitbusy(void)
{
    delay(1000);
    return 0;
}

ändern. Dann kommt zwar noch eine Warnung das irgendeine andere Funktion 
nicht genutzt wird, aber das Display funktioniert..

Hab gelesen das die Funktion den Befehl /n beeinflusst. Das funktioniert 
dann wohl nicht mehr richtig. Für meine Zwecke aber belanglos.

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


Lesenswert?

Robert P schrieb:

> Ich hab´s jetzt herausgefunden. :

> static uint8_t lcd_waitbusy(void)
>
> {
...
>     return (lcd_read(0));  // return address counter
>
> }/* lcd_waitbusy */

ändern zu

> static uint8_t lcd_waitbusy(void)
> {
>     delay(1000);
>     return 0;
> }

> Dann kommt zwar noch eine Warnung das irgendeine andere Funktion
> nicht genutzt wird, aber das Display funktioniert..
>
> Hab gelesen das die Funktion den Befehl /n beeinflusst. Das funktioniert
> dann wohl nicht mehr richtig. Für meine Zwecke aber belanglos.

Ganz allgemein funktioniert nach dieser Änderung der automatische 
Wechsel auf die nächste Displayzeile - bei einzeiligen Displays der 
Sprung zum Anfang der Zeile - beim Erreichen des Zeilenendes nicht mehr.

Ob es das wert ist?

Die Fleury-LCD-Lib ist übrigens an ein paar Stellen subtil kaputt. Das 
Timing ist grenzwertig, was bei manchen Displays zu Kauderwelsch führt. 
Vor allem, wenn man Strings mit "\n" oder über mehrere Zeilen ausgibt.

Hier ist ein Diff meiner Änderungen:
1
--- lcd.c       (revision 95)
2
+++ lcd.c       (revision 116)
3
@@ -19,7 +19,8 @@
4
 ** constants/macros
5
 */
6
 
7
-#define lcd_e_delay()   __asm__ __volatile__( "rjmp 1f\n 1:" );
8
+//#define lcd_e_delay()   __asm__ __volatile__( "rjmp 1f\n 1:" );
9
+#define lcd_e_delay()   delay(1);
10
 #define lcd_e_toggle()  toggle_e()
11
 
12
 #if LCD_LINES==1
13
@@ -75,6 +76,7 @@
14
 /* toggle Enable Pin to initiate write */
15
 static void toggle_e(void)
16
 {
17
+    lcd_e_delay();
18
     lcd_e_high();
19
     lcd_e_delay();
20
     lcd_e_low();
21
@@ -157,7 +159,7 @@
22
     while ( (c=lcd_read(0)) & (1<<LCD_BUSY)) {}
23
 
24
     /* the address counter is updated 4us after the busy flag is cleared */
25
-    delay(2);
26
+    delay(4);
27
 
28
     /* now read the address counter */
29
     return (lcd_read(0));  // return address counter

Ich habe das für eins meiner Projekte (Frequenzzählermodul) gefixt, 
nachdem Rückmeldungen über spinnende Displays kamen. Die sind jetzt weg.


XL

von Peter D. (peda)


Lesenswert?

Robert P schrieb:
> static uint8_t lcd_waitbusy(void)
> {
>     delay(1000);
>     return 0;
> }

Was bedeutet die 1000?
Sind das 1000 Jahre oder was?
Besser nimmt man die delay.h, dann kann man Zeiten (µs, ms) angeben.

1000µs sind natürlich viel zu viel, das bremst nur unnötig aus. Die 
meisten Funktionen brauchen nur etwa 50µs.
Bei den langsamen Funktionen (Clear, Home) fügt man dann zusätzlich 
Delays (2ms) ein. Oder am besten benutzt man sie erst garnicht. Clear 
bewirkt nämlich sichbares Flackern.


Peter

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


Lesenswert?

Peter Dannegger schrieb:
> Robert P schrieb:
>> static uint8_t lcd_waitbusy(void)
>> {
>>     delay(1000);
>>     return 0;
>> }
>
> Was bedeutet die 1000?
> Sind das 1000 Jahre oder was?

delay() ist ein Makro in lcd.c, so richtig mit Inline-Assembler. Peter 
F. wickelt das ganze Timing mit dieser Funktion ab. Das Argument ist in 
µs.

> 1000µs sind natürlich viel zu viel, das bremst nur unnötig aus. Die
> meisten Funktionen brauchen nur etwa 50µs.
> Bei den langsamen Funktionen (Clear, Home) fügt man dann zusätzlich
> Delays (2ms) ein.

Das ist aber nur die zweitbeste Lösung und mit den ganzen Sonderlocken 
auch häßlich. Man muß das Timing pessimistisch machen, sonst 
funktioniert es u.U. mit Exoten nicht. Dadurch wartet man fast immer 
länger als nötig.

Viel besser ist es, wenn man noch ein Pin freimacht für RW. Oder man 
nimmt gleich ein LCD mit serieller Schnittstelle.


XL

von Peter D. (peda)


Lesenswert?

Axel Schwenke schrieb:
> Man muß das Timing pessimistisch machen, sonst
> funktioniert es u.U. mit Exoten nicht.

Kann ich nicht bestätigen.
In den Foren sind es nie Timingprobleme.

Die üblichen Probleme sind:
- Programmfehler
- falsche Initialisierung
- falscher Anschluß
- falsche F_CPU Angabe

Ich hatte auch einmal vergessen, den RW-Pin anzuschließen.


Axel Schwenke schrieb:
> Viel besser ist es, wenn man noch ein Pin freimacht für RW.

Noch besser ist ein Timerinterrupt, dann muß man nie warten, auch nicht 
auf das Busy-Bit.
Meistens sind mir aber die <1% CPU-Last für das LCD mit 50µs Delay total 
schnuppe.


Peter

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


Lesenswert?

Peter Dannegger schrieb:
> Axel Schwenke schrieb:

>> Man muß das Timing pessimistisch machen, sonst
>> funktioniert es u.U. mit Exoten nicht.
>
> Kann ich nicht bestätigen.
> In den Foren sind es nie Timingprobleme.

Naja, da ist kein Widerspruch. Man macht das Timing ja von vornherein 
pessimistisch, weil man keine Timingprobleme kriegen will.

Andererseits habe ich schon beim ersten veröffentlichten Projekt 
Rückmeldungen bekommen, daß Displays Mist anzeigen. Am Ende lief es 
darauf hinaus, daß Peter F. nur 2µs wartet und dann den Adreßzähler 
ausliest. Darüber aber einen Kommentar stehen hat, daß das bis 4µs 
dauern kann :(
Oder daß er E-Pulse mit 4 Takten Länge verwendet, was nur bis 8MHz 
Controller-Takt in der Spezifikation bleibt.

>> Viel besser ist es, wenn man noch ein Pin freimacht für RW.
>
> Noch besser ist ein Timerinterrupt, dann muß man nie warten, auch nicht
> auf das Busy-Bit.

Ich sehe nicht, wie dir ein Interrupt hier weiterhilft. Wenn du einen 
Befehl an das LCD schicken willst, dann muß der vorherige fertig sein. 
Darauf mußt du notfalls warten.

Was man korrekterweise macht, ist nicht nach jedem Befehl zu warten, 
bis der fertig ist. Sondern vor jedem Befehl zu checken ob der 
vorherige fertig ist. Wenn man aus laufendem Code heraus immer mal ein 
Zeichen an das LCD schickt, muß man so u.U. niemals warten. Beim 
Kopieren eines Buffers auf das LCD bringts natürlich nichts.

Bei einem LCD mit 50µs Ausführungszeit ist das natürlich ziemlich 
akademisch. Aber wenn es z.B. ein UART mit 9600Bd ist, will man die 
pessimal 1ms nur dann warten, wenn es wirklich nötig ist.


XL

von Peter D. (peda)


Lesenswert?

Axel Schwenke schrieb:
> Ich sehe nicht, wie dir ein Interrupt hier weiterhilft.

Ganz einfach, der Timerinterrupt (z.B. 1ms) kommt nicht schneller als 
50µs und somit muß nicht gewartet werden. Er kann immer das nächste Byte 
ausgeben.

Das Main schreibt immer nur in den Displaypuffer und wartet daher auch 
nirgends. Das geht sogar extrem schneller als direkt zum LCD.

Der Displaypuffer muß so groß sein, wie die Zeichenanzahl des LCD. Der 
RAM-Verbrauch ist also höher als ohne Interrupt.

Beitrag "Formatierte Zahlenausgabe in C"


Peter

von Peter D. (peda)


Lesenswert?

Axel Schwenke schrieb:
> Am Ende lief es
> darauf hinaus, daß Peter F. nur 2µs wartet und dann den Adreßzähler
> ausliest. Darüber aber einen Kommentar stehen hat, daß das bis 4µs
> dauern kann :(
> Oder daß er E-Pulse mit 4 Takten Länge verwendet, was nur bis 8MHz
> Controller-Takt in der Spezifikation bleibt.

Ja, was soll man davon halten.
Das absichliche Verletzen der Spezifikation zählt für mich nicht als 
Timingfehler, sondern als Programmierfehler.


Peter

von Peter D. (peda)


Lesenswert?

Falls jemand eine kleine übersichtliche LCD-Lib sucht:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=102296


Peter

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


Lesenswert?

Peter Dannegger schrieb:
> Axel Schwenke schrieb:

>> Ich sehe nicht, wie dir ein Interrupt hier weiterhilft.
>
> Ganz einfach, der Timerinterrupt (z.B. 1ms) kommt nicht schneller als
> 50µs und somit muß nicht gewartet werden.
...
> Das Main schreibt immer nur in den Displaypuffer und wartet daher auch
> nirgends. Das geht sogar extrem schneller als direkt zum LCD.

Ach so. Ein FIFO-Buffer zwischen Display und Code. Dann sag das doch.

Der Interrupt muß übrigens keineswegs langsam sein (wenn man das 
Busy-Flag auslesen kann). Pseudocode im Interrupt:

1
if (!buffer_empty() && !lcd_busy()) {
2
  lcd_putc(buffer_get());
3
}


XL

von Peter D. (peda)


Lesenswert?

Axel Schwenke schrieb:
> Ach so. Ein FIFO-Buffer zwischen Display und Code.

Nein, kein FIFO.
Das Main schreibt die Zeichen immer an die Stelle im Puffer, wo es im 
LCD angezeigt werden soll. Und der Interrupt fügt die Zeilenwechsel 
automatisch ein. Ein 4*20 LCD braucht also 80 Byte Puffer.

Axel Schwenke schrieb:
> Der Interrupt muß übrigens keineswegs langsam sein

Dann würde unnötig oft auf das LCD ausgegeben. 1ms scheint mir ein 
optimaler Wert zu sein. Schnell genug, damit man auch Zeichen blinken 
lassen kann (z.B. bei Eingaben).


Peter

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


Lesenswert?

Peter Dannegger schrieb:

> kein FIFO.

Schon wieder ein Mißverständnis. Irgendwie hakelt unsere Kommunikation 
:)

> Das Main schreibt die Zeichen immer an die Stelle im Puffer, wo es im
> LCD angezeigt werden soll. Und der Interrupt fügt die Zeilenwechsel
> automatisch ein. Ein 4*20 LCD braucht also 80 Byte Puffer.

Ach so, dann also ein Frame Buffer. Ist das für ein Textmode Display 
nicht ein kleines bisschen übertrieben? Zumal du ja auch einen völlig 
unveränderten  Buffer immer wieder zyklisch in den Frame Buffer des LCD 
kopierst...

> Axel Schwenke schrieb:

>> Der Interrupt muß übrigens keineswegs langsam sein
>
> Dann würde unnötig oft auf das LCD ausgegeben.

Klar, wenn man das als Frame Buffer organisiert. Wenn man einfach nur 
ein FIFO macht, dann ist das egal. Sobald der leer ist, passiert nichts 
mehr.


XL

von Karl H. (kbuchegg)


Lesenswert?

Axel Schwenke schrieb:

> Ach so, dann also ein Frame Buffer. Ist das für ein Textmode Display
> nicht ein kleines bisschen übertrieben? Zumal du ja auch einen völlig
> unveränderten  Buffer immer wieder zyklisch in den Frame Buffer des LCD
> kopierst...

Genau darum gehst.
Diesen zyklischen Refresh kannst du mit einem Interrupt machen, der 
immer nur 1 Zeichen updated. Kostet dir so gut wie nichts, ist schnell 
genug und du bist die Wartezeiten im Ausgabecode sofort los.
Hinzukommt, dass dadurch die LCD-Ausgaben automatisch reentrant werden, 
mann kann damit also auch zb in einer anderen ISR auch mal was aufs LCD 
malen, ohne befürchten zu müssen, dass da technisch was durcheinander 
kommt.

>> Dann würde unnötig oft auf das LCD ausgegeben.

Im Prinzip richtig. In der Praxis bei den üblichen Grössen der Text-LCD 
irrelevant. Ist halt einfach eine Sache mehr, die in der meistens 
sowieso bereits vorhandenen Timer-ISR für Basisdinge mitgemacht wird.

von Bernhard M. (boregard)


Lesenswert?

Axel Schwenke schrieb:
> Ach so, dann also ein Frame Buffer. Ist das für ein Textmode Display
> nicht ein kleines bisschen übertrieben?

Nein, da man sich die ganze Warterei spart (wenn man das Busy-Flag nicht 
benutzt), weil das "warten" immer zwischen zwei Timer Interrupts ist
Das wiederholte schreiben kriegt man mit ein bisschen Zusatzaufwand weg, 
allerdings ist das nicht wirklich von Vorteil.
Dann kann man das noch geschickt mit der Tastaturabfrage (-entprellung) 
koppeln und so Leitungen sparen....

Von einer Busy-Flag Abfrage im Interrupt halte ich gar nichts, weil man 
dann ja den Interrupt auf "unbestimmte" Zeit blockiert.

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


Lesenswert?

Bernhard M. schrieb:
> Axel Schwenke schrieb:

>> Ach so, dann also ein Frame Buffer. Ist das für ein Textmode Display
>> nicht ein kleines bisschen übertrieben?
>
> Nein, da man sich die ganze Warterei spart (wenn man das Busy-Flag nicht
> benutzt), weil das "warten" immer zwischen zwei Timer Interrupts ist

Ich hab das ehrlich gesagt noch nie als Problem empfunden (halte aber 
auf der anderen Seite nichts vom Pins sparen und schließe meine LCD 
immer mit RW an). Falls überhaupt, würde ich einen FIFO implementieren.

> Von einer Busy-Flag Abfrage im Interrupt halte ich gar nichts, weil man
> dann ja den Interrupt auf "unbestimmte" Zeit blockiert.

Nur wenn man sich dumm anstellt. Man soll ja nicht im Interrupthandler 
warten, bis BUSY wieder weg ist. Man prüft nur einmal ob es gesetzt ist 
(und das auch nur, wenn es was auszugeben gibt). Und wenn BUSY gesetzt 
ist, gibt man in diesem Interrupt halt nix aus, sondern beendet die ISR. 
Der nächste Interrupt kommt bestimmt!

Was ich als Nachteil dieser Frame Buffer Methode ansehe, ist daß man 
sich jeglicher Möglichkeiten des Displays beraubt. Oder das zumindest 
deutlich verkompliziert, weil man Schreibzugriffe aufs Display nur mit 
gesperrtem Interrupt machen kann. Also Scherze wie Blink-Cursor 
einschalten (wenn man auf Eingabe wartet) oder benutzerdefinierte 
Zeichen ändern (sehr nett: animierte Zeichen). Oder die Möglichkeiten 
die sich durch das Verschieben des Display-Framebuffers ergeben.

Versteh mich nicht falsch: ich will die Idee nicht schlechtreden. Sie 
löst halt nur kein Problem, das ich je gehabt hätte. Und für das hier 
ursprünglich diskutierte "ich hab nicht genug Pins und kann deswegen 
BUSY nicht auslesen" ist sie die berühmte Kanone zum Spatzen abschießen.


XL

von Peter D. (peda)


Lesenswert?

Axel Schwenke schrieb:
> Falls überhaupt, würde ich einen FIFO implementieren.

Das bring garnichts, sondern macht nur zusätzliche Probleme. Was machst 
Du, wenn der FIFO voll ist?
Der Displaypuffer überschreibt sich einfach immer mit dem aktuellsten 
Text. Der FIFO müßte ihn aber wegschmeißen oder doch wieder warten.

Axel Schwenke schrieb:
> Also Scherze wie Blink-Cursor
> einschalten (wenn man auf Eingabe wartet)

Gehen damit prima bei 1ms. Es soll ja blinken und nicht nervös flackern.

Axel Schwenke schrieb:
> ich will die Idee nicht schlechtreden. Sie
> löst halt nur kein Problem, das ich je gehabt hätte.

Ist daher auch eher eine Designstudie von mir. In Spezialfällen kann es 
nötig sein, die Mainloop sehr schnell zu durchlaufen, z.B. für 
Regelungen. Und dann könnte auch die Ausgabe mit Busy-Test zu langsam 
sein.

Für die meisten Anwendungen ist die 50µs Delay LCD schnell genug.
Der Busy-Test kann ja auch nicht erheblich schneller sein. Er wird 
vielleicht die Wartezeit auf 60% reduzieren.
Die Maximalzeiten werden etwa den tatsächlichen Zeiten des 
LCD-Controllers mit etwas Sicherheitsaufschlag entsprechen.


Peter

von Karl H. (kbuchegg)


Lesenswert?

Axel Schwenke schrieb:

> Was ich als Nachteil dieser Frame Buffer Methode ansehe, ist daß man
> sich jeglicher Möglichkeiten des Displays beraubt.

> Oder das zumindest
> deutlich verkompliziert, weil man Schreibzugriffe aufs Display nur mit
> gesperrtem Interrupt machen kann.

Ist jetzt aber auch nicht so das große Problem.

> Also Scherze wie Blink-Cursor
> einschalten (wenn man auf Eingabe wartet)

Na ja. Kann aber auch der nächste Interrupt mit machen.

> oder benutzerdefinierte
> Zeichen ändern (sehr nett: animierte Zeichen).

> Oder die Möglichkeiten
> die sich durch das Verschieben des Display-Framebuffers ergeben.

Das wollte ich immer schon mal fragen.
Jetzt abgesehen vom 'Effekt' "komplette Anzeige scrollt herein", den man 
mit dem Framebuffer ebenfalls ziemlich banal erzeugen kann, kennt jemand 
irgendeinen sinnvollen Einsatz für dieses Feature?

Der größte Nachteil ist für mich: Es kostet Speicher. Was ich dafür 
kriege: ich kann immer und überall Ausgaben machen. Ich muss nur darauf 
auspassen, dass ich nicht übereinanderschreiben, aber abgesehen davon, 
kann ich alles jederzeit überall ausgeben. Und sei es nur eine 
Statusmeldung in einer ISR.

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


Lesenswert?

Peter Dannegger schrieb:
> Axel Schwenke schrieb:

>> Falls überhaupt, würde ich einen FIFO implementieren.
>
> Das bring garnichts, sondern macht nur zusätzliche Probleme. Was machst
> Du, wenn der FIFO voll ist?

Warten :)

Man muß die FIFO-Größe schon auf das restliche Programm abstimmen. Aber 
klar, aus einer zeitkritischen ISR würde ich trotzdem nicht aufs Display 
pinseln.

>> Also Scherze wie Blink-Cursor
>> einschalten (wenn man auf Eingabe wartet)
>
> Gehen damit prima bei 1ms. Es soll ja blinken und nicht nervös flackern.

Aber du mußt dich drum kümmern. Das Display kann das auch ganz 
alleine.

> Ist daher auch eher eine Designstudie von mir. In Spezialfällen kann es
> nötig sein, die Mainloop sehr schnell zu durchlaufen, z.B. für
> Regelungen. Und dann könnte auch die Ausgabe mit Busy-Test zu langsam
> sein.

Das Display selber wird ja auch gescannt. Und normalerweise kann man es 
deutlich schneller beschreiben als es die Zeichen auch anzeigt. Wenn es 
100Hz Refreshrate hat, kann man 10ms/50µs = 200 Zeichen ausgeben. Ein 
16x4 Display also gut dreimal überschreiben.

> Für die meisten Anwendungen ist die 50µs Delay LCD schnell genug.
> Der Busy-Test kann ja auch nicht erheblich schneller sein. Er wird
> vielleicht die Wartezeit auf 60% reduzieren.

Man weiß halt nicht, wie schnell das gerade angeschlossene Display ist. 
Der HD44780 verwendet einen externen Widerling in Verbindung mit 
integrierten Kapazitäten. Die exakte Frequenz wird also von Exemplar, 
Temperatur und Betriebsspannung abhängen. Das Datenblatt sagt +/-30%. 
Und explizit verschiedene Widerstände (91K vs. 75K) für verschiedene 
Betriebsspannungen (5V vs. 3V). Die Ausführungszeiten dürften also 
Nominalwert + 30% + Sicherheitszuschlag sein. Weniger als die Hälfte 
wäre also möglich.

Ach und weil ich gerade das Datenblatt sehe: Framerate ist f_clk  400  
duty. Mit nominal 270kHz also 84Hz (duty 8/16) oder 61Hz (duty 11).


XL

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


Lesenswert?

Karl Heinz Buchegger schrieb:
> Axel Schwenke schrieb:

>> Also Scherze wie Blink-Cursor
>> einschalten (wenn man auf Eingabe wartet)
>
> Na ja. Kann aber auch der nächste Interrupt mit machen.

Dazu muß man das aber auch vorgesehen haben. Wenn ich PeDa richtig 
verstanden habe, ist das ein reiner Character Frame Buffer. Der 
Interrupt gibt also nur Zeichen aus und setzt evtl. den Adresszeiger 
neu, um auf die nächste Zeile zu kommen.

Wenn man Befehle an das LCD schicken will, kann man die ja nicht einfach 
in den Framebuffer pinseln.

>>  Möglichkeiten
>> die sich durch das Verschieben des Display-Framebuffers ergeben.
>
> Das wollte ich immer schon mal fragen.
> Jetzt abgesehen vom 'Effekt' "komplette Anzeige scrollt herein", den man
> mit dem Framebuffer ebenfalls ziemlich banal erzeugen kann, kennt jemand
> irgendeinen sinnvollen Einsatz für dieses Feature?

Laufschriften mit minimalem Aufwand. Oder Eingabefelder länger als das 
Display. Ist aber in der Tat mehr ein Gimmick als ein hartes Feature.


XL

von Peter D. (peda)


Lesenswert?

Axel Schwenke schrieb:
> Wenn ich PeDa richtig
> verstanden habe, ist das ein reiner Character Frame Buffer.

Ja.
Andere Funktionen benutze ich nicht.
Das Blinken mache ich in Software, d.h. alle 250ms Wechsel zwischen 
Zeichen und Blanks ausgeben.
Blinken nur einiger Zeichen (z.B. 4-stellige Zahl eingeben) kann das LCD 
ja nicht.

Und Laufschrift mache ich auch in SW.
Wenn ich das richtig erinnere, geht die Laufschriftfunktion des LCD 
nicht richtig. Da gibts beim Zeilenumbruch Probleme und am Display-RAM 
Ende.
Und Laufschrift in einer Zeile, stehender Text in den anderen, geht 
garnicht.


Peter

von Karl H. (kbuchegg)


Lesenswert?

Axel Schwenke schrieb:
> Karl Heinz Buchegger schrieb:
>> Axel Schwenke schrieb:
>
>>> Also Scherze wie Blink-Cursor
>>> einschalten (wenn man auf Eingabe wartet)
>>
>> Na ja. Kann aber auch der nächste Interrupt mit machen.
>
> Dazu muß man das aber auch vorgesehen haben. Wenn ich PeDa richtig
> verstanden habe, ist das ein reiner Character Frame Buffer. Der
> Interrupt gibt also nur Zeichen aus und setzt evtl. den Adresszeiger
> neu, um auf die nächste Zeile zu kommen.

Sieh das Ganze als 'System' an. Was immer dir notwendig erscheint, 
kannst du reinprogrammieren.

>> Das wollte ich immer schon mal fragen.
>> Jetzt abgesehen vom 'Effekt' "komplette Anzeige scrollt herein", den man
>> mit dem Framebuffer ebenfalls ziemlich banal erzeugen kann, kennt jemand
>> irgendeinen sinnvollen Einsatz für dieses Feature?
>
> Laufschriften mit minimalem Aufwand.

Schon mal gemacht?
So minimal ist der Aufwand nämlich gar nicht.
Zumindest dann nicht, wenn jede beliebige Laufschrift möglich sein soll.
* Links rum, Rechts rum
* Text beliebiger Länge
* 1 feststehende Zeile, 1 laufende Zeile.

> Oder Eingabefelder länger als das
> Display.

Ditto.

> Ist aber in der Tat mehr ein Gimmick als ein hartes Feature.

IMHO in Wirklichkeit für Nichts zu gebrauchen.

Mir wärs lieber gewesen, sie hätten dem Controller mehr RAM verpasst und 
dafür ein paar Attribute auf Character-Ebene, wie Blinken bzw Invers. 
Damit hätte man mehr anfangen können.

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.