Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - FAQ - Zum CC1-Forum - Zum CC-Pro-Forum

Re: Init LCD in lcdext vs. pcflcd Kategorie: Sonstige Hardware (von Rolf - 22.08.2003 23:02)
Als Antwort auf Re: Init LCD in lcdext vs. pcflcd von André H. - 22.08.2003 16:54

Hallo André

> Kommen wir zuerst zum Datenblatt des PCF8574.
> Der PCF8574 ist ein quasi-bidirektionaler Baustein.
> D.h. er kennt nur zwei Zustände: Low und High.
> Dabei ist der High-Pegel gleichzeitig Eingang, da die Ausgänge Open-Drain
> sind und eine 100µA Konstantstromquelle für den nötigen Pull-Up sorgt.

Sehe ich auch so....

> > In dem Augenblick wo ich 0x2 auf das PCF schreibe, beginnt aber auf den Datenleitungen ein KurzschluÃ?
> > weil beide Bausteine zu diesem Zeitpunkt als Ausgang laufen. Dieser KurzschluÃ? wird erst behoben wenn
> > der PCF in den Lesemodus geschaltet wird wobei dann die RS und RW-Leitungen hochohmig werden dürften.
> > Beim zurückschalten des Displays auf Schreibbetrieb passiert etwas ähnliches.
>
> Das passiert wie gesagt nur, wenn die Ports, die als eingänge genutzt werden sollen,
> vorher keinen High-Pegel besitzen.

Das Display hat aber ggf. auf dem Datenbus beim lesen D4-D7 Lowpegel, damit wäre ein Kurzschlu�
durchaus denkbar. Jedoch wäre der auf 100µA begrenzt, was das Display und der PCF aushalten müste.
Da hast Du sicher recht.

Jedoch ist zum Zeitpunkt des Einlesens die Information für RS und R/W beides logisch 1 (durch eben dieses
verhalten beim Lesen des PCF so das also letztlich der Low Pegel für RS nicht zustande kommt.
Dadurch wird aus dem Leseversuch von CGRAM / DDRAM Addr bzw. BF immer ein Leseversuch des DDRAM.
An die Info von BF und CGRAM / DDRAM Addr komme ich aber damit so nicht.
Ursache dafür ist wie gesagt der Umstand, das beim Lesen die Pullups des PCF aktiv sind.
Es hat also relativ wenig damit zu tun, welchen Pegel die Ports vorher hatten da zum Zeitpunkt des Leseversuchs
RS auf 1 "gepullt" und das falsche Register gelesen wird.

> > 1.Ist es möglich, das BF-Flag mit dem PCF-Modul auszulesen und wenn ja, wie?
>
> Es ist möglich:
>
> i2c.cstart(addr);
> i2c.write(0xF2);
> i2c.write(0xF6);
> i2c.stop();
> i2c.cstart(addr or 1);
> BF= (i2c.readlast() and 0x80)!=0;
> i2c.stop();
> i2c.cstart(addr);
> i2c.write(0xF2);
> i2c.write(0xF0);
> i2c.stop();
>
> Jedoch benötigt man das BF i.d.R. nicht, da die Ansteuerung über I²C
> langsam genug ist. Und bei Clear und Home kennt man schlie�lich die nötigen
> Wartezeiten.

Genau das möchte ich überprüfen und deshalb interessiert mich das BF-Flag.
Ich habe aus diversen Publikationen entnommen, das im 4-Bit Modus die Verarbeitungszeiten höher sind
als im 8-Bit-Modus und bis zu 4 ms dauern können bis BF wieder 0 ist. Ausserdem habe ich gelesen,
das auch andere Befehle als Clear und Home bedeutend länger brauchen sollen. Um das zu prüfen will
ich an das Flag.

Zu Deinem Codesegment, man müste wohl 2 Nibble lesen damit das Display nicht aus dem 4-Bit-Tritt kommt.
Wenn ich das richtig erkenne, liest Du dort nur ein Nibble. Das nur nebenbei.
Das Problem des RS-Bits und damit der Zugang zu BF ist mit dem Codesegemet aber noch nicht gelöst,
da zum Zeitpunkt des Einlesens das falsche Register gelesen wird..

> > 2.Müsten dazu in die Datenleitung nicht Widerstände von min. 10 K damit der Kurzschlu� nicht das Display
> > oder den PCF zerstört?
>
> Nein, das setzen von Widerständen ist nicht möglich, da die meisten Displays
> Pull-Ups besitzen, und dies dann eher störend auf die Datenübertragung wirkt.
> (Habe ich damals ausprobiert)
> Zum Trost: Da� der PCF8574 davon zerstört werden kann, ist eher unwahrscheilich.
> Und die meisten Display halten auch kurze Kurzschlüsse aus.
> (zumindest bei denen mir das schon bei Versuchsaufbauten passiert ist.
 
Hat sich geklärt, siehe oben die 100µA-Geschichte.
 
> > 3.Müste an die RS-Leitungnicht nicht ein Pulldown und an die RW-Leitung nicht ein Pullup damit im hochohmigen
> > Lese-Zustand die Signale für RS und RW nicht verloren gehen?
> > (dann wäre es auch nicht nötig, den Baustein vorher mit 0x2 zu setzen)
>
> Das macht keinen Sinn.
> Bei einem Pull-Down an einer Leitung könnte man nie RS=1 setzen. (Datenplatt PCF8574)
> Und da man die Ports eines PCF8574 einzeln als Ein- und Ausgänge benutzen kann,
> macht es keinen Sinn.

Da bin ich noch nicht mit einverstanden.
Ein passender Pulldown, der in der Lage ist, die 100µA auf 0-Pegel zu ziehen (schätze mal 3,3K Ohm)
kann durchaus mit einem 1-Pegel und deutlich höheren Ausgangsströmen im Schreibmodus des PCF
eingesetzt werden und würde den Ausgang nur gering belasten. Der Pulldown müste ja nur dem Pullup im
PCF übersteuern, bei Ansteuerung als Ausgang flie�en ja doch ggf. höhre Ströme die dann den Pulldown
egalisieren. Ich habe soetwas beim 68HC11 Prozessor schon gemacht.

Wie auch immer - das läst sich ja austesten. Wie anders wollte man RS wärend des Lesens
und damit bei aktiven Pullups des PCF auf Pegel 0 kriegen? Genau das ist aber der Zustand
der Ports beim Einlesen über den PCF. Allerdings lie�e sich dann (mit Pulldown) auch nicht mer das DDRAM
auslesen da es im Lesebetrieb nicht mehr auf 1 zu kriegen ist. (anders als im Schreibbetrieb)
 
> > 4.Wenn es nicht möglich wäre, das BF-Flag einzulesen, warum ist es dann verschaltet?
>
> Pinkompatibilität zu P1L an der CC2. :-)
> Au�erdem könnte schlie�lich jemand Daten aus dem CG- oder CC-RAM
> auslesen wollen.

Hm... wenn ich die Wahl hätte, nur eins von beiden Registern lesen zu können, würde mich das mit BF und den
aktuellen Adressen aber mehr interessieren als der Inhalt vom Displayram - zumal genau dieses meist irgendwo
in einer Stringvariable im System vorhanden ist.

> > Die PCF-LCD's sind gereadezu prädestiniert für den Betrieb als Anwendung mit mehrfachen LCD's.
> > Will man jedoch z.B. pro Thread ein LCD verwalten, kriegt man relativ schnell Probleme mit der selektion des
> > richtigen LCD. Ich habs ausprobiert und mir ein zweites PCF-Modul auf einem Steckboard nachgebaut.
> > Von da her wäre es nicht nur in der Init-Funktion sondern in allen Funktionen interessant, ein
> > function init (byte pcfnr) // Displaynummer
> > {
> >  setpcf(pcfnr); // wird hier selektiert (ggf. auch direkt mit if.... )
> >  light=light and 8;
> >
> > auszuführen. Jeder Thread müste dann nur seine Displaynummer kennen und schon lassen sich 2 oder mehr
> > Displays bequem steuern. Das Argument zur Inkompatibilität mit lcdext kann ich nachvollziehen aber es wäre
> > sowieso unmöglich, 15 Module über lcdext zu steuern... Ein Festplattentreiber mu� ja auch nicht kompatibel
> > zu einem Floppytreiber sein obwohl bei beiden die gleichen physikalischen Vorgänge ablaufen.
> > Und zudem ist es nur eine parametrische  und keine funktionelle Inkompatibilität. Ich denke, das man wegen
> > der besonderen Anwendungsweise auf Parameterkompatibilität verzichten kann zumal das die Verwaltung
> > im Thread vereinfacht. Das als Vorschlag.
>
> Am Anfang wollte ich auch Adressparameter für die einzelnen Befehle vorsehen.
> Jedoch wird so alles unnötig verlangsamt.
> I.d.R gibt sendet man schlie�lich mehrer Befehle am Stück an ein LCD. :-)

Das PCF-Display läuft als i2c (100 KBit) also seriell in 4 Bit Modus! Welche Rolle spielt es da, ob ein zusätzlicher
Parameter übergeben wird? Das Argument kann ich beim lcdext nachvollziehen, beim EEPROM-Treiber fand
ich es schon bedenklich aber hier im PCFLCD-Modul ist es am falschen Platz.
Der Overhead für ein zusätzlichen Parameter dürfte nur ein 10tel bis 100stel einer einzigen i2c-Operation sein.
Wenn nicht sogar noch weniger. (Wobei pro Buchstabe auf dem Display min. 4 i2c-Befehle nötig sind)

> Deshalb muÃ? man bei einem mehr-Display-Betrieb auch ein explizites Capture verwenden.
> (Das war mit ein Grund, für das neue I²C-Capture)
> Also z.B.:
>
> thread A:
> capture var.pcflcdflag;
>  pcflcd.setpcf(0)
>  pcflcd.line(1);
>  pcflcd.print2(str);
>  pcflcd.line(2);
>  pcflcd.zahl4n1(wert);
> release;
>
> thread A:
> capture var.pcflcdflag;
>  pcflcd.setpcf(1)
>  pcflcd.line(1);
>  pcflcd.time(0)
>  pcflcd.line(2);
>  pcflcd.print("Irgendetwas")
>  pcflcd.line(3);
>  pcflcd.date(1);
> release;

In diesem Beispiel sperren sich die Treads gegenseitig aus.
Wenn man sich zusätzliche Tastatureingaben/Menübehandlung in den Treads vorstellt,
ist das Ergebnis katastrophal da jeweils nur ein "Terminal" benutzt werden könnte.
Man stelle sich das ganze doch mal als i2c-Hausbus mit mehreren Terminals vor.
Wärend Eingaben auf Terminal A gemacht werden, muss der Thread B warten und wenn
Tread A z.b. in einer Endlosschleife hängt weil eine Eingabe nicht abgeschlossen wurde,
(was man natürlich auch wieder mit Timern abfangen könnte)
gibts im Tread 2 keine Möglichkeit zur Datenausgabe (und ggf. weitere Dinge).
Damit kriege ich also eine ganze Anlage zum Stillstand weil ich das Multithreading
auf oberster Ebene ausgehebelt habe. Das kann es nicht sein.

> Ich finde diese Variante besser, als wenn man bei jedem Befehl
> einen Parameter übergeben mu�.

Na die Nachteile scheinen mir gegenüber der Möglichkeit mit Displaynurmmern
zu arbeiten aber gewaltig. Das berührt aber auch schon wieder meine und Deine Ansicht
von Single/Multithreadig..

> AuÃ?erdem kann man so sogar ohne Probleme mit mehreren Thread
> auf das selbe Display zugreifen. (Obwohl ich das nicht unbedingt empfehle :-) )

Das geht auch wenn alle Threads die gleiche Displaynurmmer verwenden.

Mir ist noch was aufgefallen was das Timing der Displays angeht.
Zwischen Pegel RS bzw. RW und steigender Flanke von E müsssen min. 40ns liegen.
Das läst sich nur erreichen wenn man nicht

 i2c.write((cmd and 0xF0) or light or 0x4);// HighNibble
 i2c.write((cmd and 0xF0) or light); //Datenübername E

sondern einen Vorlauf einbaut.

 i2c.write((cmd and 0xF0) or light); // Vorlauf
 i2c.write((cmd and 0xF0) or light or 0x4);// HighNibble
 i2c.write((cmd and 0xF0) or light); //Datenübername E

Im Low Nibble ist dann schon alles korrekt gesetzt, da reicht dann ein

 i2c.write((cmd shl 4) or light or 0x4);   // LowNibble
 i2c.write((cmd shl 4) or light);

Kommt jetzt ein Datenbyte für das DDRAM, hätte man das gleiche Problem dort auch.
Da das Display aber zunächst mit der Verarbeitung beschäftigt ist, kann ich den PCF
schon in den Modus für DDRAM setzen. Dann brauche ich den Aufwand später nicht mehr zu treiben
Da mehr Daten, als Steuerbytes geschrieben werden, lohnt sich diese Aufteilung auch.

 i2c.write(light or 0x1);

Da _alle_ Kommandos scheinbar mehr Zeit benötigen _können_ , je nach dem aktuellen Vorgang im Display
sollte die Wartezeit für das Display auch in WriteCmd mit sleep gesetzt werden. 2 ms sollten ausreichen, das
würde ich aber gerne noch mit dem BF-Flag verifizieren.

Die Funktion WriteCmd müste als Beispiel dann so aussehen:

function WriteCmd (byte cmd)
{
 i2c.cstart(PCF);
 i2c.write((cmd and 0xF0) or light);
 i2c.write((cmd and 0xF0) or light or 0x4);// HighNibble
 i2c.write((cmd and 0xF0) or light);
 i2c.write((cmd shl 4) or light or 0x4);   // LowNibble
 i2c.write((cmd shl 4) or light);
 i2c.write(light or 0x1);
 i2c.stop();
 sleep 2; //evtl auch 4
}

Das Timingproblem haben übrigens scheinbar alle LCD-Module.
Ich beziehe mich ausdrücklich auf die Datenblätter von Hitachi und die Werte für tAS

GruÃ? Rolf
 




    Antwort schreiben


Antworten:

Re: Init LCD in lcdext vs. pcflcd (von André H. - 23.08.2003 0:50)
    Re: Init LCD in lcdext vs. pcflcd (von Rolf - 23.08.2003 2:14)
        Re: Init LCD in lcdext vs. pcflcd (von Rolf - 23.08.2003 13:27)
Re: Init LCD in lcdext vs. pcflcd (von Rolf - 23.08.2003 0:43)