Die von Bernhard vorgestellten Codes funktionieren bei mir auch alle problemlos, allerdings mit einem Haken.
Besonders deutlich zu sehen ist das bei der Version 1. Beim Aufbau des Bildes wird immer die oberste Zeile doppelt geschrieben und die unterste damit gar nicht. Ich kann das zwar ausgleichen, indem ich einfach eine weitere Zeile hinzufüge, aber das beseitigt ja nicht die Ursache.
o.m.g.
Wie wäre es mit einem Photo, auf dem der Bildinhalt des OLED scharf abgebildet ist. Das PNG-Format hilft auch nicht, wenn die Aufnahme verhunzt ist. Nur weil es sich um ein Photo von einem Bildschirm handelt, wird daraus noch kein Screenshot im Sinne der Forenregeln.
Wichtige Regeln - erst lesen, dann posten!
Bitte das JPG-Format (nur) für Fotos und Scans verwenden!
Besonders deutlich zu sehen ist das bei der Version 1. Beim Aufbau des
Bildes wird immer die oberste Zeile doppelt geschrieben und die unterste
damit gar nicht.
Welches Bild? In der Software wird das OLED nur mit kompletten Pixeln 0xFF vollgeschrieben. Keine Texte oder so.
Ich kann das zwar ausgleichen, indem ich einfach eine
weitere Zeile hinzufüge, aber das beseitigt ja nicht die Ursache.
Naja, der Verfasser der Software hat beim Thema Grundlagen von Assembler noch einiges nachzuholen. Die Software funtkioniert zwar irgendwie, aber das ist alles arg zusammengebastelt. Hier gibt es Verbesserungsvorschläge, wenn gleich für eine andere Software.
In der Schaltung fehlen außerdem die Pull-Up Widerstände für SDA und SCL. Je einmal 3,3K oder ähnlich gegen 5V sollten reichen. Ist ein Wunder, daß es überhaupt funktioniert, vermutlich hat das OLED welche eingebaut.
Volltreffer! Ich habe das GO_HOME mal komplett rausgenommen und jetzt
paßt es!
Ja, im Moment. Das passt nur, weil die Resetwerte der Register passen. Wenn man aber mal im Programmablauf die Funktion braucht, muss man sie reparieren. Man muss sich in die Adressierungsarten einlesen und die richtigen Einstellungen einstellen. Damit man dann auch mal gezielt an Stellen auf dem OLED schreiben kann, sprich den Cursor setzen.
Beitrag "Re: I2C Display einfache Frage"
Da stehen meine "gesammelten" Erfahrungen drin.
Selbstgestecktes Ziel war:
"kann man den ATtiny2313 oder 4313 zur Zusammenarbeit mit einem OLED-Display bewegen?"
Die ganzen Libraries und KI-Vorschläge sind zwar recht löblich, oft fehlt aber etwas. Und zwar sehr Wichtiges.
Die ersten Befehlsfolgen entscheiden darüber, wie das Display reagiert.
Dann:
Die drei Arten der Ansteuerung sind wieder etwas zu Erlernendes.
Bis zum Memory adressing Mode horizontal bin ich schon gekommen.
Viele OLEDs lassen sich vom Prinzip her schon aber nur mit dem mir noch ein Rätsel seienden Page-Mode adressieren.
Gerade die 1.3-er, wie ich feststellen musste.
Gut, dass Du mit einem 0.96-er arbeitest.
Das hat dieses Problem offenbar nicht.
Viel Spaß!
Naja, der Verfasser der Software hat beim Thema Grundlagen von Assembler
noch einiges nachzuholen.
Yep. Genau meine Meinung.
Völlig unnötig aufgeblasener, verwirrender Spaghetticode.
Man kann die Parametereingabe zum Beispiel auch als Tabelle schreiben.
Dazu braucht man keine Extra-Vordefinitionen und Label. Die Initialisierungsvarianten muss man so wie so im passenden Datenblatt nachsehen. Alles andere ist nicht nur nicht hilfreich, sondern völlig überflüssiger Programm-Müll. Habe mir diese Programmbeispiele vorher auch angeschaut, kommt für meine Umsetzung keineswegs in Frage.
Das merkt man aber erst so richtig, wenn es um jedes Byte Speicherplatz geht, wie bei dem "ATtiny"-Projekt.
Zum Beispiel setze ich das untige Gerödel wie im Programmschnipsel oben gezeigt um:
Befehl (Hex) Beschreibung
0xAE Display OFF (Schlafmodus)
0xD5, 0x80 Setze Display Clock Divide Ratio/Oscillator Frequency
0xA8, 0x3F Setze Multiplex Ratio (63 für 64 Zeilen)
0xD3, 0x00 Setze Display Offset (kein Versatz)
0x40 Setze Start Line auf 0
0x8D, 0x14 Charge Pump aktivieren (Wichtig: Ohne dies bleibt das Display dunkel!)
0x20, 0x00 Memory Addressing Mode: Horizontal Mode
0xA1 Segment Re-map (Spalten 0-127)
0xC8 COM Output Scan Direction (reversiert für Standard-Montage)
0xDA, 0x12 COM Pins Hardware Configuration (Alternative für 128x64)
0x81, 0xCF Kontrast einstellen (0xCF ist ein guter Mittelwert)
0xD9, 0xF1 Setze Pre-charge Period
0xDB, 0x40 Setze VCOMH Deselect Level
0xA4 Entire Display ON (folgt RAM-Inhalt)
0xA6 Normaler Modus (nicht invertiert)
0xAF Display ON
usw. usf.
Ein Programm, das alle Eventualitäten und Varianten als Passepartout vorgibt zu sein, kenne ich, gerade in ASM, nicht. Gelegentlich muss man da schon einmal etwas weiter in die Untiefen der maschinennahen Sprache abtauchen. Sowas geht in der C++ Arduino-Sprache schon komfortabler, allerdings stark libraryabhängig.
Ich war mal so frei, das Programm ein wenig aufzuräumen und zu erweitern. Siehe Anhang. Funktioniert prima. Allerdings braucht man EXTERNE Pull-Up-Widerstände an SDA und SCL, die internen reichen nicht! 2-10kOhm sind OK.
Viel Spaß damit
Ach so. Getestet mit ATmega328P, aka Arduino Uno. Der ATmega8 geht auch, allerdings muss man in ini.asm zweil Zeilen auskommentieren und andere wieder aktvieren, ist sichtbar.
vorab herzlichen Dank für deinen Code, funktioniert super!
Ich habe aber noch eine Frage, u.z.wie kommst du zu dieser Zeile: .db
SSD1306_CMD_SET_DISPLAY_START_LINE, SSD1306_CMD_DISPLAY_TEST_OFF
Das sind im wesentlichen die Kommandos, um ein paar Grundeinstellungen herzustellen, wenn gleich die identisch zum Reset-Wert sind. Die sind alle im Datenblatt beschrieben.
SSD1306_CMD_SET_DISPLAY_START_LINE setzt den Anfang der RAM-Adresse für das Display.
SSD1306_CMD_DISPLAY_TEST_OFF schaltet den Testmodus aus und den Normalmodus ein.
Außerdem bin ich dabei ein 0,66" (64x48) OLED anzusteuern. Mir gelingt
es dabei nicht die Displaygröße mit.db SSD1306_CMD_SET_COLUMN_ADDRESS, 0
.db 63, SSD1306_CMD_SET_PAGE_ADDRESS
.db 0, 5
einzustellen. Ich kann zwar so tun als hätte ich ein 128x64 Display und
dafür nur die Startpunkte ändern, aber das ist natürlich nur ein Behelf.
Puhhh, schwiegrig, der Controller ist ja der gleiche. Und so weit ich es erkennen kann, kann man da nicht allzuviel bezüglich der echten Displaygröße einstellen, bestenfalls das Multiplexverhältnis. Ergo muss man so tun, al ob ein volles 128x64 Display dran hängt und nur auf den echten Teil des Speichers schreiben. Der Rest wird zwar vom Controller ausgegeben, landet aber im Nirvana (ohne Schrotflinte ;-)