Ein gesundes neues Jahr wunsch ich euch!
Ich hab mein 1" Full-Color-OLED schon angeschlossen (prutal mit dem
Lötkolben) und "in Betrieb" genommen und bin gerade darüber mein Proggi
(ASM) zu schreiben. An ist es, Text kommt auch schon raus, nur hab ich
mit Löschen und füllen ein Problem:
Mein Display hängt an einem Atmel ATMega16, welcher derzeit mit 8MHz
läuft. Das ist langsam genug um schön einzelne Pixel zu zeichnen.
Befehle wie Löschen und Rect brauchen aber (displayseitig) etwas länger
so dass, wenn ich den nächsten Befehl gebe, das Display noch nicht
fertig ist und einfach den neuen Befehl abarbeitet. Das Ergebnis ist
ein halb gelöschter Bildschirm. Das kann man auf dem Bild unten links
gut sehen: Die Blaue Fläche und der Rote Rand ist eigentlich ein Rect
über den ganzen Schirm. Der helle Bereich ist Grieß(RAM-Müll).
Zweckmäßig wäre es das Status-Register auszulesen und zu warten bis
alles fertig ist. Und genau das gelingt mir nicht. Möglich sollte es
aber sein, wenn man dem Datenblatt glauben mag.
Kann mir da jemand helfen? Irre ich mich?
Ich verwende das 6800-Protokoll.
Danke
Mein erster Versuch sah so aus:
OLED_BUSY:
push Temp
clr Temp
out OLED_DDR_Data,Temp ;Data-Port als Input
cbi OLED_Cntr,OLED_DC ;D/C auf Controll
sbi OLED_Cntr,OLED_RW ;RW auf Lesen
sbi OLED_Cntr,OLED_E
cbi OLED_Cntr,OLED_CS
nop ;tACC (Access Time) abwarten, so ca 140ns
OLED_BUSYloop:
in Temp,OLED_DataIn ;Status auslesen
sbrc Temp,7 ;wenn das "Command lock"-Bit 0 ist ist alles
fertig
rjmp OLED_BUSYloop
sbi OLED_Cntr,OLED_CS
ser Temp
out OLED_DDR_Data,Temp ;Data-Port wieder als Ausgang
pop Temp
ret
Nur klappt das nich. Hab schon alles Mögliche versucht.
> das Status-Register auszulesen und zu warten bis> alles fertig ist. Und genau das gelingt mir nicht
der Assemblercode und die Schaltung wären hier für uns interessant,
"dann werden ihnen geholfen" ;)
Heißt »Klappt nich« jetzt
a) das Programm bleibt dort hängen (Bit wird nie low)
b) das Programm verhält sich wie ohne Abfrage (Bit ist immer low)
c) das Programm verhält sich noch anders (nämlich?)
Meist ist es in solchen Fällen ja irgendein Mist, daß man den Pin
versehentlich irgendwie anders definiert hat, so daß er nicht als
Eingang arbeitet.
Ich glaub, ich hab's
OLED_BUSYloop:
....
rjmp OLED_BUSYloop
Diese Rotine muss anders aufgebaut sein.
Das Busy wird nicht automatisch low!!!
Du musst es jedes mal neu anfordern.
Also:
Kommando senden
Enable
Ports auf Input
etwas warten
Status abfragen
Bin auch schon mal darüber gestolpert.
Bernhard
das weiß ich auch noch nicht, aber ich habs schon da, wills in nächster
zeit mal testweise an nen MEGA128 klemmen, allerdings mit
paralleleinblendung in den SRAM, entgegen oben geposteter schaltung..
Steffen schrieb:
> für 30 Euro habe ich zwei 128x128 Full Color OLED bekommen.
Das ist erfreulich für Dich, beantwortet die Frage »Wo kommt denn das
Teil überhaupt her?« nicht wirklich gut.
Vielleicht kannst Du noch Deine Quelle angeben, damit Dein Beitrag einen
Sinn bekommt? Danke.
meine Quelle ist eine Firma in China:
http://www.litearray.com/products-oled.php
Hier gab es mal einen Beitrag dazu:
Beitrag "O-LED Display von SMI"
Die Preise von damals haben sich aber gewaltig geändert. Die OLED 96x64
ähnlich die von Reichelt kostet etwa 10 EUR und die 96x96 etwa 12 EUR.
Das 128x128 OLED liegt derzeit bei 15 EUR. Ich habe die letzte
Bestellung im Dezember 2006 gemacht. Leider hatten damals nur wenige
Interesse an den OLED. Von einigen habe ich noch was da , wenn Interesse
besteht.
Gruss
Steffen
ja, da habe ich noch einige da. der Typ ist LPST128128A00-T4. Da kostet
eine 15,00 EUR ohne Versand. ( Eine kleine Adapter-LP habe ich mal dazu
gemacht, bin aber leider nicht zum Testen gekommen. ) Die würde ich
kostenlos mit beilegen.
Gruss
Steffen
Steffen ich hätte gerne ein 128x128 display... vielleicht kannst du mir
dazu auch die ansteuerungssoftware und schaltplan bereit stellen? Ich
bin halt faul :)
hier die Schaltung und LP für das OLED 128x128. Den Softwaretreiber habe
ich gekauft ( RAMTEX ) und kann diesen leider nicht weitergeben.
Gruss
Steffen
@ Bernhard Schulz (bernhard)
>OLED_BUSYloop:> ....> rjmp OLED_BUSYloop>>Diese Rotine muss anders aufgebaut sein.>Das Busy wird nicht automatisch low!!!>Du musst es jedes mal neu anfordern.>Also:>>Kommando senden>Enable>Ports auf Input>etwas warten>Status abfragen>>Bin auch schon mal darüber gestolpert.
Konntest du das noch etwas präzisieren? Ich erkenne bei dir garkeine
Schleife. Und wie immer "neu anfordern"? E Aus - E An - Kontrollieren -
E Aus - E An - Kontrollieren oder wie?
u.A. @ Philipp
der Pin ist immer LOW. Es wird nicht gewartet.
die internen Pullup sins nat. an!
@ Bernhard Schulz (bernhard)
Danke
dein Code ist einwandfrei Dokumentiert und auch nachvollziehbar.
Bitmuster passt so. Ich hab alles fast 1:1 übernommen.
Ich hab noch...
cbi PORTB, LCD_B_DC ; DC=>Command (LOW)
...hinzugefügt, aber gebracht hat es nix. Ich glaube ich gebe jetzt auf.
Hattest du Probleme zw. den Protokollen zu wählen?
Ich hatte mir gedacht, ich versuche es mal mit 8080, hab die Platine
umgelötet und die Software umgeschrieben und es ging gar nix mehr. Erst
die 6800er Software klappte wieder. Komisch. Dazu muss ich aber auch
sagen dass vorher, als ich noch der Meinung war mich mit 6800
rumzuschlagen, mir das Verhalten auch schon spanisch vor kam. Ich hatte
manchmal den Eindruck, dass ich mich im 8080-Modus befand. Kann es also
sein dass im Datenblatt (siehe Anhang) die Angaben falsch?
Mir geht das Ding langsam ganz schön auf die *****!
Ja "Protokoll" war vieleicht schlecht gewählt. Du kannst auch
"Interface" sagen. Oder "WannWoWasWielangAnliegenMussDamitEsGeht-Regeln"
:)
Das Interface-Timing-Diagram von deinem Display sieht doch schon etwas
anders aus als meins. Bei dir ist klar: Ein HIGH an E und das Display
nimmt die Daten an.
Aus meinem Diagram (ich habe es oben schon mal gepostet) werd ich nicht
schlau. Ich glauge eine Steigende Flanke an CS# sagt dem Diplay wann es
die Daten aufsaugen kann. Und bei dem 8080-Interface giebt es garkein
E-Bit mehr. Da giebt es dann ein RD (lesen) und ein WR (schreiben) Bit.
Ich glaub wenn man das nicht studiert hat, hat man da keine Chance :)
> Ich glaub wenn man das nicht studiert hat, hat man da keine Chance :)
...und bei manchen Datenblättern noch eine Glaskugel dazu ;)
Es wäre sehr schön und hilfreich, wenn Du dieses Projekt mal
veröffentlichen könntest.
Wir bräuchten dann das Fahrrad nicht noch einmal zu erfinden
Bernhard
Meinen Schrott veröffentlichen? Hmm. Das trägt dann bestimmt nur zur
Volksverdummung bei. Das ist doch alles schon recht laihenhaft,
unansehnlich und nach all dem Rumprobiere sehr chaotisch geworden. Das
müsste ich erst mal überarbeite und dokumentieren.
ok, hab den Code mal sortiert :) und dokumentiert.
Im ZIP sind ASM-Code und noch ein Bild vom aktuellen Proggi. Auch hier
wieder gut zu erkennen, dass der Bildschirm nur teilweise gelöscht wird.
Unwichtig, aber der Vollständigkeit halber: jetzt hängt ein 6.5536MHz
Quarz dran.
Darf ich als Laie fragen ob ich das Problem richtig verstanden hab wenn
du einen Löschen befehl sendest braucht das Display länger als bei
normalen befehlen und dann überschneidet sich das mit dem neuen Befehl
und der wird dann übernommen ? Also das Löschen hört auf. Da ich leider
keinerlei assambler kann kann ich dir bei deinem Problem mit der Abfrage
nicht helfen aber wie wäre es wenn du einfach nach dem Löschbefehl
einfach naja sagen wir ne par ms wartest ? Das löst zwar dein
Abfrageproblem nicht aber das müsste zumindest mit dem Überschneiden
helfen =) . Irgendwann muss ich mir auch mal so ein Display besorgen das
sieht echt nice aus.
Gruß Andreas ( der hofft das war da eben nicht zuviel Schrott )
Problem vollständig erkannt!
Einfach ein wenig warten könnte man.
1.Nur wie lang?
2. Ein Rechteck/Löschen über den Halben Schirm dauert nicht so lange wie
ein Rechteck/Löschen über den ganzen Schirm. Unnötig warten missfällt
mir!
3. Ich versuche den Code wiederverwendbar zu schreiben. Wenn ich einfach
warte, müsste ich das für jeden Prozessortakt neu "justieren".
Das wäre einfach ne halbseitene Lösung, die mir nicht gefallen würde.
Wenn sich das Ding aber weiterhin so sträubt, wird es wohl so werden.
Weil ich nur Elektriker bin. Wenn jeder "Kloppstock" zu Osram rennt,
kommen die ja garnicht mehr zum Bearbeiten der Probleme von "richtigen"
Entwicklern. Und für was giebt es denn ein solch spitzenmäßiges Forum.
HIER trifft die Elite auf die kleinen Leute! HIER sitzen die Fachfräfte,
die sich !freiwillig! mit den Wehwehchen der Anfänger beschäftigen. Und
da die Anzahl und Größe der Threads über OLEDs nicht zu verachten ist,
nahm ich an, dass mir einer der vielen Anwender weiterhelfen könnte.
An dieser Stelle noch mal ein rießen Lob an www.mikrocontroller.net
!!!!
Es giebt NIX vergleichbares im I-Net! Nicht auf euerm Niveau! Weiter so!
Hallo Harry,
danke für Deinen Programmcode ;)
Wenn ich es jetzt richtig herausgelesen habe, dann
wird das Status-Register jetzt korrekt eingelesen und das
Programm arbeitet dann erst weiter, wenn der entsprechende Pin vom LCD
den
Richtigen H/L Pegel hat ?
Also das funktioniert korrekt?
> Löschen befehl sendest braucht das Display länger als bei> normalen befehlen und dann überschneidet sich das mit
Andreas seine Bemerkung fand ich sehr interessant, stimmt das, dass sich
Kommandos an das LCD überschneiden?
Wenn dem so ist, dann wäre das doch die Ursache für das nicht korrekte
Löschen, oder?
Bernhard
>Wenn ich es jetzt richtig herausgelesen habe, dann>wird das Status-Register jetzt korrekt eingelesen und das>Programm arbeitet dann erst weiter, wenn der entsprechende Pin vom LCD>den Richtigen H/L Pegel hat ?>Also das funktioniert korrekt?
Eben nicht! Das ist das Problem. Und Andreas Ausführung ist die direkte
Folge.
Hatte ich mich in meinem ersten Thread unklar ausgedrückt?
>Mein Display hängt an ... 8MHz.>Das ist langsam genug um schön einzelne Pixel zu zeichnen.>Befehle wie Löschen und Rect brauchen aber (displayseitig) etwas länger>so dass, wenn ich den nächsten Befehl gebe, das Display noch nicht>fertig ist und einfach den neuen Befehl abarbeitet. Das Ergebnis ist>ein halb gelöschter Bildschirm. ...>Zweckmäßig wäre es das Status-Register auszulesen und zu warten bis>alles fertig ist. Und genau das gelingt mir nicht.
Harry ich würde trotzdem mal nachfragen. Ist ja nicht so als ob die
täglich millionen von Anfragen von bastlern hätten und sowas deshalb
generell ignorieren.
Hallo Harry,
>wird das Status-Register jetzt korrekt eingelesen... ?
....
>Eben nicht!
ok, alle Klarheiten beseitigt ;)
Also das Hauptproblem ist noch nicht gelöst.
Nach meiner Meinung, kann der Staus noch jedem LCD-Kommando abgerfragt
werden.
Bsp. Ein Pixel setzen, anschließend Status abfragen
Diesen Status, also die Pegel aller LCD-PINS kannst Du Dir ja separat
anzeigen lassen.
Notfalls wird das Programm testweise an dieser Stelle mal gestoppt,
vorher alle µC Pins auf Eingang und PULL-UPS an bzw. aus schalteten.
Dann mal hochohmig mit einem Multimeter nachmessen.
Dann einen externen Pul-Up (10k...1M) anschließen und messen.
Nicht das die Ausgangsiderstände des LCDs zu hochohmig sind, und deshalb
bei einem µC Pull-up von 30k die Pins nicht gegen LOW ziehen können.
Sollte das alles nicht zum gewünschten Erfolg führen, dannn gibt es
immer noch eine Notlösung.
Und zwar das definierte Warten des µC, bis das LCD sich endlich
ausgemehrt
hat.
Ich übertreibe mal: Ein Pixel setzen 2 µs, LCD löschen 100ms
Bernhard
Also das Datenblatt gibt echt nicht viel zum Statusregister her. Das ist
das einzige was ich gefunden hab :
Table 7 - Read Command Table
(D/C=0, R/W (WR#)=1, E (RD#)=1 for 6800 or E (RD#)=0 for 8080)
Bit Pattern Command Description
D7D6D5D4D3D2D1D0
Status Register Read *
D7 : “1” for Command lock
D6 : “1” for display OFF / “0” for display ON
D5 : Reserve
D4 : Reserve
D3 : Reserve
D2 : Reserve
D1 : Reserve
D0 : Reserve
Note: Patterns other than that given in Command Table are prohibited to
enter to the chip as a command; otherwise, unexpected
result will occur.
Was wird denn da als Status ausgegeben ???? Doch nur ob Display On / Off
und ob der letzte Befehl angekommen ist oder ? Auch zu den Zeiten vom
Löschen steht echt nichts im Datenblatt aber an deiner Stelle würde ich
einfach warten as ist wahrscheinlich die einfachste Lösung und versuchen
ob man irgendwie herausfinden kann was die "längste" Dauer zum löschen
hat und das halt als Wartezeit nehmen. Entweder Ausprobieren oder bei
Osram halt anfragen ^^.
Gruß Andreas
Jetzt sag mir bitte nicht, dass "Command-Lock" kein Bussy-Flag ist!
Command-Lock auf Deutsch = Befehl gespert. Also das Display ist für
weitere Befehle gesperrt, weil es noch arbeitet. Oder???
Ich habe mich nun doch dazu entschlossen erstmal eine Warte-Schleife zu
programmiern, auch wenn mir es nich so richtig passt. Aber wer weiß ob
ich sonst überhaupt noch zu meinem Schwarzen Bildschirm komme :(
Warten:
push Temp
push Temp2
clr Temp
ldi Temp2,3 ;Durch Probieren ermittelt
Warten_loop:
dec Temp
brne Warten_loop
dec Temp2
brne Warten_loop
pop Temp2
pop Temp
ret
Das müsste dann bei 6,5536MHz so ca. ...ähhh... 158μs sein.?.
Und da ich nun auch schon eine Funktion geschrieben hat die einfarbige
Icons anzeigen kann macht das Ding auch wieder Spaß!!!
Ahh ok dann macht das auch als Status etwas her nur weil normalerweise
Lock ja auch bedeuten kann das es "eingeloggt" bzw erhalten wurde aber
ich habe mich vermutlich nur etwas in der Übersetzung bzw Interpretation
geirrt.
Gruß Andreas
Ich erlebe gerade eine Überraschung:
Wenn ich etwas zeichne, gehen entweder 2 Byte Pixelfarbe oder 2 Byte
0x00 für schwarz an das Display. Daher auch der Schwarze Rand um meinen
Text. Bei jedem Pixel was gezeichnet wird, wird der SRam-Pointer im
Display vollautomatisch incrementiert. d.h. das nächste übertragene
Pixel wird vollautomatisch daneben (oder darunter) gezeichnet.
Wenn ich aber garkeinen Schwarzen Rand haben möchte, müsste der
SRam-Pointer incrementiert werden ohne dass ich ein Pixel gezeichnet
hätte. Also habe ich ERSTMALS ein ReadData-Funktion aufgesetzt. Die
Daten interesieren mich nicht, nur der Pointer. Doch der incrementiert
einfach nicht, als ob ich garkeine Leseversuche machen würde :(
> Meist ist es in solchen Fällen ja irgendein Mist...
Evtl. hab ich ein einfach nur ein kaltes Lot am RW-Pin. Ich werde der
Sache heute nach der Arbeit mal auf den Grund gehen.
So, mir reicht es jetzt!
Eine kalte Lötstelle konnte ich nicht finden. Ich habe dann so lange im
Programmcode rumexperimentiert bis das gewünschte Ergebniss auftrat.
OLED_Inc_Pointer:
sbi OLED_Cntr,OLED_DC
sbi OLED_Cntr,OLED_RW
cbi OLED_Cntr,OLED_CS#
sbi OLED_Cntr,OLED_E
nop
nop
sbi OLED_Cntr,OLED_CS#
cbi OLED_Cntr,OLED_E
ret
Aber mit dem Timing-Diagramm im Datenblatt hat das wirklich nur noch
wenig zu tun.
Noch mal zum Mitmeißeln: Das Display hat intern einen SRam-Zeiger.
Dieser wird beim Lesen oder beim Schreiben (der Daten) automatisch
erhöht. Um einzelne Pixel zu überspringen, ohne sie zu überschreiben,
kann man es einfach auslesen. Die hier gezeigte Funktion sollte dies,
mit dem Zusatz "in Temp,PINB", eigentlich tun. Praktisch empfange ich
dann aber nur Nullen. Das Display hat auf jeden Fall begriffen, dass ich
es auslese. Es erhöht ja seinen SRam-Zeiger.
Weiteres, wie
>Dann einen externen Pul-Up (10k...1M) anschließen und messen.>Nicht das die Ausgangswiderstände des LCDs zu hochohmig sind, und deshalb>bei einem µC Pull-up von 30k die Pins nicht gegen LOW ziehen können.
..halfen auch nichts. Ich möchte das jetzt auch nicht weiter ausführen.
Denn wie gesagt:
Mir reicht es jetzt!
Ich werde keine weiteren Leseversuche unternehmen. Dieser Thread ist von
meiner Seite her beendet.
Danke an alle Beteiligten.