1" Full-Color-OLED

Gast #474613
Lesenswert?

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
Angehängte Dateien:
Gast #474649
Lesenswert?

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.
Angehängte Dateien:
#474709
Lesenswert?

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.
#474726
Lesenswert?

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

Gast #474754
Lesenswert?

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..
#474795
Lesenswert?

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.
Gast #474823
Lesenswert?

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
Gast #474841
Lesenswert?

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
Gast #475014
Lesenswert?

@ 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!
#475358
Lesenswert?

@Harry

so habe ich's bei einem LCD 128x64 KS0108 gelöst,

ich hoffe, ich habe den Code ausreichend dokumentiert?


Bernhard



;#####################################################################
;erzeugt den Enable-Puls
LCD_ENABLE:
  rcall wait_1us    ; kurze Pause
  rcall wait_1us    ; kurze Pause
  sbi PORTB,LCD_B_E           ; Enable high
  rcall wait_1us    ; kurze Pause
  rcall wait_1us    ; kurze Pause
  rcall wait_1us    ; kurze Pause
  rcall wait_1us    ; kurze Pause
     cbi PORTB,LCD_B_E           ; Enable low
  rcall wait_1us    ; kurze Pause
  rcall wait_1us    ; kurze Pause
ret
; ####################################################################
LCD_STATUS_WAIT:

  ; PORT D auf Eingang
  clr temp
  out DDRD,temp

  ; PULL-UPs off
  clr temp
  out PORTD,temp

  ; LESEMODUS
  sbi PORTB, LCD_B_RW  ; RW=>READ   (HIGH)
LCD_STATUS_WAIT_w:
  rcall LCD_ENABLE        ; Enable-Routine aufrufen

  ; EINLESEN
  in temp, PIND

         ; Bitmuster (hier ggf. anpassen   !!!!!!!!!!!!!!!!)
  andi temp, 0b10000000
  tst temp
  brne LCD_STATUS_WAIT_w

  ; PORTB auf AUSGANG
  ldi temp, 0b11111111
  out DDRD,temp
ret
; ####################################################################
Gast #475417
Lesenswert?

@ 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 *****!
Angehängte Dateien:
Gast #475435
Lesenswert?

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 :)
#475444
Lesenswert?


> 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




Gast #475507
Lesenswert?

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.
Gast #475651
Lesenswert?

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.
Angehängte Dateien:
Gast #475654
Lesenswert?

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 )
Gast #475720
Lesenswert?

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.
Gast #475735
Lesenswert?

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!
#475765
Lesenswert?


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
Gast #475789
Lesenswert?

>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.
#475806
Lesenswert?

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




Gast #475961
Lesenswert?

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
Gast #475984
Lesenswert?

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ß!!!
Gast #476170
Lesenswert?

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
Gast #476193
Lesenswert?

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.
Gast #477826
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren