Hallo,
ich habe hier ein 320x240 Display von Bolymin mit SED1335 Controller an
einem NXP LPC2378. Die Backlightfarbe ist weiß und das LCD blau.
http://www.bolymin.com.tw/Doc/P111-BG320240F.pdf
Prinzipiell läuft auch alles.
Früher hatte ich eine Darstellung von weißer Schrift auf blauem
Hintergrund, also eigentlich eine invertierte Darstellung.
Nun brauche ich auch die andere Darstellungsvariante, also weiße Schrift
auf blauem Grund. Dazu habe ich einfach die Farbwerte vertauscht und der
gewünschte Effekt war erreicht.
Nun habe ich aber beim Schreiben auf das Display (zB. Screenwechsel)
leichte Störungen, die besonders deutlich in den hellen Flächen
auffallen. Die Störung ist ein Aufblitzen von kurzen hellgrauen
horizontalen Strichen auf dem ganzen Display. Genau sagen kann ich es
nicht, aber es könnten immer 8 zusammenhängende Pixel, also ein Byte,
sein. Je nach Blickwinkel fallen die Störungen unterschiedlich stark
auf. In der anderen Farbvariante sind mir die Fehler nie aufgefallen.
Wenn ein Screen fertig aufgebaut ist und sich nichts ändert, treten die
Störungen auch nicht auf!
Im Datenblatt zum Controller steht, dass Displayflickern auftauchen
kann, wenn man die Timings nicht einhält. Wenn ich aber auf das Busyflag
warte, wird es schnarch langsam (unten im Code: SED1335_EnableWait=1).
Außerdem sind dann immer noch Striche zu sehen.
Da aber prinzipiell alles funktioniert, gehe ich eigentlich davon aus,
dass es was mit dem Timing zu tun haben muss.
Bei der Suche im Forum bin ich über folgende Library gestolpert:
http://en.radzio.dxp.pl/sed1335/
Allerdings sehen die Schreibroutinen fast genauso aus wie meine. Also
kein Warten auf ein Busyflag oder ähnliches.
Hat jemand eine Idee in welche Richtung ich weiter suchen könnte?
Meine init sieht so aus:
------------------------------------------------------------------------
SED1335_cput(0x40);
//waitMS(3); //(Forumshinweise, aber bringt nichts gegen das Flackern)
u08 msg1[8]={0x30,0x87,0x07,0x27,0x30,0xF0,0x28,0x00};//modified
system set
//u08 msg1[8]={0x30,0x87,0x07,0x27,0x2F,0xC7,0x28,0x00};//default
system set of SED1335 from datasheet
SED_dputMessage(8,msg1); //system set
//
SED1335_cput(0x44);
u08 msg2[10]={0x00,0x00, //Address
0xF0, //SL1=240
SED1335_G_BASE1&0xFF,SED1335_G_BASE1>>8, //Address
0xF0, //SL2=240
0x00,0x00,0x00,0x00};//scroll
SED_dputMessage(10,msg2); //scroll
//
SED1335_cput(0x5D);
u08 msg3[3]={0x07,0x87}; //csr form
SED_dputMessage(2,msg3);
//
SED1335_cput(0x5A); //hscr param
SED1335_dput(0x00);
//
SED1335_cput(0x5B);
SED1335_dput(0x0D); //overlay both layers XOR
//SED1335_dput(0x0C); //overlay both layers OR
//
SED1335_cput(0x59); //disp ON
SED1335_dput(0x14); //1st,2nd no flash
//
SED1335_clear_Allgraph();
----------------------------------------------------------------------
Meine Datenausgabe so:
(Kommandbyteausgabe entsprechend)
void SED1335_dput(int byte)
{
//wait until display ready
if (SED1335_EnableWait) { //momentan fest auf 0!!
u16 TCount=SED1335_WAITTOVER; //1000
while (((SED1335_sget()&SED1335_BUSYMASK)==0)&&(TCount--));
}
//
SED1335_DATA_PORT(byte); // write value to data port
//
SED1335_A0_low();
SED1335_cs_low(); // enable chip, which outputs data
SED1335_wr_low(); // activate LCD's write mode
//
asm("nop");
//
SED1335_wr_high(); // deactivate write mode
SED1335_cs_high(); // enable chip, which outputs data
SED1335_A0_high(); // address
}
Hallo Frank,
Zitat Datenblatt:
When CS, A0 and RD are LOW, D6 functions as the display status
indication output
Ein Vergleich mit einem URALT Code (man möge den Stil verzeihen) von mir
zeigt:
LCDCTL = (0<<A0)|(0<<RD)|(1<<WR); // Setzt die Bitmaske auf Status Read
cli();
do
{
asm("WDR");
} while ( (LCDDataIN & 0x40) == 0x40); //Wait for Retrace
LCDCTL = (0<<A0)|(1<<RD)|(1<<WR); // Setzt die Bitmaske auf Write
.
.
.
Bei deinem Code fehlt mir das setzen der Bitmaske auf Status Read.
Kann es sein, dass es so "schnarchlangsam wird", weil das Statusflag
nicht korrekt gelesen wird und Deine einzige Abbruchbedingung das
Ablaufen von TCount ist ?
Nur eine dumme Idee....
Gruss, Gerrit
> Nun habe ich aber beim Schreiben auf das Display (zB. Screenwechsel)> leichte Störungen, die besonders deutlich in den hellen Flächen> auffallen.
Soweit ich weiss ist dieses Verhalten normal wenn du in das Display
schreibst waehrend es selber gerade Daten aus dem Ram liesst
um das Panel zu betreiben. Wenn man das nicht will dann
muss man wohl auf irgendein Bit warten um nur in der Austastluecke
zu schreiben.
Das gilt aber nur fuer die alten SED1335. Das IC ist ja schon einige
Jahre geschichte und wurde IMHO bereits durch zwei Nachfolger ersetzt.
Und die koennen wohl ohne Wartezeit verschachtelt auf das Ram zugreifen
und flackern dann nicht mehr.
Olaf
Ich vermute auch, dass Schreibzugriffe während das Display selber aus
dem RAM liest, die Ursache ist. So steht es ja auch im Datenblatt.
Aber mein Ansatz zum Auswerten des Statusflags macht die Sache
unerträglich langsam. Ich sehe da keinen Unterschied zum Vorschlag von
Gerrit.
@Gerrit: Was meinst du mit:
"Bei deinem Code fehlt mir das setzen der Bitmaske auf Status Read." ??
In meinem Datenblatt steht nicht, dass D6 den Status nur enthält, wenn
CS A0 und RD LOW sind. Außerdem habe ich es so verstanden, dass ich
Daten schreiben darf, wenn D6 HIGH ist.
Mit folgendem Code, geht der Aufbau schneller, wenngleich immer noch
deutlich langsamer als ohne Statusabfrage. Komischerweise beschränkt
sich dabei das Flickern auf einen schmalen vertikalen Streifen auf der
rechten Seite, wo es sehr deutlich auftritt.
Gleicher Code nachdem alles auf LOW gezogen wurde (Position (B) ) führt
zu wilden Streifen auf dem Display, die immer neu geschrieben werden.
void SED1335_dput(int byte)
{
//
SED1335_DATA_PORT(byte); // write value to data port
//
do
{
asm("nop");
} while ( (SED1335_sget() & SED1335_BUSYMASK) == 0x40); //Wait for
Retrace
//
SED1335_A0_low();
SED1335_cs_low(); // enable chip, which outputs data
SED1335_wr_low(); // activate LCD's write mode
//
asm("nop"); // (B)
//
SED1335_wr_high(); // deactivate write mode
SED1335_cs_high(); // enable chip, which outputs data
SED1335_A0_high(); // address
}
Es gibt ein sehr sehr ähnliches, wenn nicht sogar gleiches, Display von
Bolymin mit dem S1D13700 als Controller. Hat der dieses Problem nicht
mehr und ist vielleicht die bessere Wahl?
Also wenn ich die gleiche Busyflag abfrage wie bei meinem Beitrag
gestern um 17:00 nicht nur in der Datensende-Funktion sonderen auch in
der Kommandosende-Funktion einfüge, ist das Flickern komplett weg.
Was bleibt ist gelegentlich ein heller grauer horizontaler Streifen über
das ganze Display beim Schreiben. Vielleicht hilft dagegen eine
Busyflag-Abfrage in den Lese-Funktionen. Das habe ich aber noch nicht
probiert.
Vorher waren diese Striche aber glaube ich überhaupt nicht da...
Das Problem ist jetzt aber vielmehr der langsamere Bildaufbau. Es ist
nicht mehr so schnarch langsam wie bei meiner 1. Busyflag-Abfrage, aber
es ist immer noch zu langsam.
Kann man den S1D13700 ohne Busyflag-Abfrage und dann natürlich auch ohne
Flickern beschreiben? Ist der S1D13700 so eine modernere Variante von
der Olaf im dritten Post sprach?
Im Daternblatt zum S1D13700 ist die Rede von einem WAIT# Pin. Der ist
aber bei dem Bolymin Display nicht rausgeführt.
Hallo Frank,
Mein Code bezog sich auf den Controller SED13305. Da war es so, dass man
die A0 /RD /WR Leitungen auf eine bestimmte Bitmaske setzen musste.
In dem Datenblatt, das Ich zum SED1335 gefunden habe, stand es genauso
drin.
Ich habe die Busy-Flag Abfrage vor jedem Lese oder Schreibkommando zum
Display und es ist bei mir sehr schnell und flackerfrei.
Evtl ist Dein RAIO8835 doch anders aufgebaut...
Hallo Frank !
anbei mein Code.
Er ist ca 5 jahre alt. Damals konnte ich noch nicht so gut programmieren
und auch der Compiler war noch nicht auf dem heutigen Stand.
Folgende Namen müssen #define'd werden, damit der Codeausschnitt
funktioniert:
#define LCDDataIN PINA
#define LCDDataDDR DDRA
#define LCDData PORTA
#define LCDCTLDDR DDRG
#define LCDCTL PORTG
#define A0 PG2
#define WR PG0
#define RD PG1
Ich hoffe, Du kommst damit klar.
Viele Grüße,
Gerrit
Nein, das war ein Doppelpost auf Grund der komischen Vorschau hier...
Ich schreibe hier nicht sehr oft Beiträge...
in eine .h Datei kommen die Defines rein
Hm, ich sehe da bei unseren Codes keine großen Unterschiede.
Meine Busyflagabfrage funktioniert ja auch. Es wird einfach nur
arschlangsam.
Vielleicht liegt es auch an der Menge an Daten die ich schreibe.
Was hast du denn mit dem LCD vor? Zum Videokucken ist es sicher zu
langsam. Der Controller ist ja fuer Messtechnikanwendungen wo man mal
ein Bild aufbaut und dann immer nur ein par Daten aendet. Dafuer ist die
Gechwindigkeit sicher mehr als ausreichen. Wenn ich aber den gesamten
Screen ausgebe dann dauert das sicher 1/4s. Man merkt jedenfalls eine
Verzoegerung.
Aber du hast ja auch mehre Banks und kannst erst in einen unsichtbaren
Speicher schreiben und den dann einschalten.
Olaf
Ich möchte keine Videos darstellen.
Auf meinem Controller hab ich eine Art Window-Api.
Also ich kann Screens mit Rahmen, Knöpfen und Texten definieren.
Beim Screenwechsel wird der komplette Screen neu gezeichnet, aber das
dauert so lang, dass man dabei zugucken kann (~2 Sekunden).
Auf manchen Screens können sich auch Inhalte, wie Uhrzeit oder
Fortschrittsbalken, ändern.
Ohne Busyflagabfrage war es schnell genug, aber eben mit Flickern.
Das soll stört aber und soll weg.
Vielleicht muss ich den ganzen Screenaufbau ändern oder wirklich mit
mehreren Banks arbeiten. Aber so tief wollte ich eigentlich gar nicht
eingreifen.
Weiß jemand, ob ich ohne Busyflag in einen unsichtbaren Layer schreiben
kann, ohne Flickern im aktiven Layer zu sehen?
Hat jemand vielleicht ein Beispiel, wie man das mit mehreren Layern
macht?