MoinMoin,
ich hab mir vor einiger Zeit so ein Display:
Hm der Banggoodlink wird als Spam identifiziert. Es ist so ein 0.91Inch
128*32 Pixel OLED-Display mit SSD1306 Controller.
bestellt. Ich weiß nicht mehr genau woher, aber rein optisch ist es
genau dieses.
Ich verwende ein NUCLEO-L053R8 und SW4STM32 mit MXCube. Ich habe quasi
null Erfahrung mit I²C und HAL, aber wollte mich endlich mal ein wenig
dareinfuchsen.
Ich hab mit Cube ein neues Projekt erstellt, die I²C-Adresse vom Display
aus dem Datenblatt angegeben und eine Übertragung versucht. Bekam aber
kein Ack. Mit der verdoppelten Adresse bekomme ich aber immerhin mal
mein Ack. (um das read/write-Bit kümmert sich wohl die HAL_Lib)
Dann hab ich erstmal ganz unbedarft den Display_On-Befehl an die Adresse
gesendet, und nichts hat sich getan. Also noch einen Blick ins
Datenblatt geworfen. Da steht:
"5) After the transmission of the slave address, either the control byte
or the data byte may be sent across
the SDA. A control byte mainly consists of Co and D/C# bits following by
six “0” ‘s.
a. If the Co bit is set as logic “0”, the transmission of the following
information will contain
data bytes only.
b. The D/C# bit determines the next data byte is acted as a command or a
data. If the D/C# bit is
set to logic “0”, it defines the following data byte as a command. If
the D/C# bit is set to
logic “1”, it defines the following data byte as a data which will be
stored at the GDDRAM.
The GDDRAM column address pointer will be increased by one automatically
after each
data write."
Und dem Diagramm darüber entnehme ich, dass ich erst die Adresse vom
Display senden muss, dann ein Control-Byte und dann meine Daten.
Dieses Control-Byte setzt sich zusammen aus Co, D/C und 6 Nullen.
Aber wie ist dass denn nun mit diesem Co? Wenn es 0 ist, werden die
folgenden Informationen als Daten betrachtet. Heißt das im Umkehrschluß,
wenn ich einen Befehl übertragen will, muss es 1 sein? Aber egal ob ich
das "Command-Byte" nun als 0b11000000 oder 0b01000000 definiere, es tut
sich nichts.
Ich hab auch versucht, das Display zu invertieren, um etwas sehen zu
können.. Aber das Display bleibt schwarz.
Hat jemand eine Idee, woran das liegen kann?
MfG Chaos
Du willst das Rad unbedingt neu erfinden? Wie du willst,
aber lass dir beim Erfinden wenigstens helfen.
Ich hab nicht die Energie dir das haarklein auseinander-
zulegen.
Heisser Tip: Spicken hilft!
https://github.com/afiskon/stm32-ssd1306
Danke euch erst mal für die Links
@Stefanus
Ich lese gerade über deine oled.h rüber, dabei ist mir glaube ich ein
kleiner Fehler aufgefallen. Du schreibst :
" * The display is technically organized into "pages" which is a set of
8 horizontal lines.
* For a 128x32 display the memory contains 4 pages each of 128 bytes.
* Each byte represents 8 pixels. Bit 0 is the top pixel, bit 7 is the
bottom pixel."
Müsste das nicht "a set of 8 vertical lines" heißen? Horizontal ist doch
waagerecht? Oder verwechsel ich da was? Evtl ist das ja einer Korrektur
wert =).
Und des weiteren wird ein Reset-Pin erwähnt, mein Display hat jedoch nur
die VCC-, GND-, SCL- und SDA_Pins herausgeführt. Ist der nötig und ich
muss noch rumlöten? Wobei man ihn ja wegdefinieren kann, wenn ich deine
oled.h soweit richtig verstanden hab.
Naja ich versuche mich mal weiter durch die oled.cpp zu lesen. Mal sehen
ob ich das versteh, ich bin ja mehr nur son C-Grundlagiker, ich hoffe
cpp is ähnlich genug :D
Hi
>Ich lese gerade über deine oled.h rüber, dabei ist mir glaube ich ein>kleiner Fehler aufgefallen. Du schreibst :>" * The display is technically organized into "pages" which is a set of>8 horizontal lines.> * For a 128x32 display the memory contains 4 pages each of 128 bytes.> * Each byte represents 8 pixels. Bit 0 is the top pixel, bit 7 is the>bottom pixel."
Nö. Hast du dir mal im Dateblatt angesehen, wie die Pixel zugeordnet
sind? Ein Byte im Bildspeicher representiert 8 senkrechte Pixel. Und
eine Page besitzt 128 Bytes. Wenn du eine z.B. eine waagerechte Linie in
der 4.Zeile darstellen willst, musst du alle Bits3 in der Page0 setzen.
MfG Spess
@Stefan,
noch eine Frage zu deinem Code:
Du schreibst:
" i2c_send((i2c_address << 1) & 0xFF); // address + write
i2c_send(0x00); // command
i2c_send(0xAE); // display off
"
Du sendest also 0x00 um dem Display zu sagen "jetzt kommt ein Befehl".
Da versteh ich dann, wie im Eröffnungspost schon angedeutet, das
Datenblatt nicht.
a.Wenn das Co-Bit logisch 0 ist, enthält die folgende Übertragung nur
Data-Bytes.
b.Das D/C#-Bit bestimmt ob das nächste Data-Byte als Command oder Daten
interpretiert wird. Ist es 0 sinds Commands, ist es 1 sind es Daten.
Eigentlich würde ich aus a schließen, dass das Co-Bit 1 sein muss, damit
es halt Commands und nicht Daten sind. Aber es ist wohl das nur das
D/C#-Bit, dass das bestimmt. Was macht dann das komische C0-Bit
überhaupt? Braucht man das überhaupt?
Ansonsten denke ich aber, dass ich deine init soweit verstanden hab.
Also nochmal herzlichen Dank dafür.
spess53 schrieb:> Nö. Hast du dir mal im Dateblatt angesehen, wie die Pixel zugeordnet> sind? Ein Byte im Bildspeicher representiert 8 senkrechte Pixel. Und> eine Page besitzt 128 Bytes. Wenn du eine z.B. eine waagerechte Linie in> der 4.Zeile darstellen willst, musst du alle Bits3 in der Page0 setzen.>> MfG Spess
Da hab ich wohl irgendwie, senkrechten Bytes und waagerechten Pages
durcheinander geworfen. Mir kam es beim überfliegen nur komisch vor, das
erst von horizontal und dann von oberstem und unterstem "geredet" wurde.
Zusammen mit deinem Hinweis und nochmal nachlesen ist mir das jetzt
aufgegangen :D
J. T. schrieb:> Müsste das nicht "a set of 8 vertical lines" heißen? Horizontal ist doch> waagerecht?
Ja, das ist korrekt so. Die Bits des ersten Bytes sind auf dem Display
dort:
J. T. schrieb:> Super, nun leuchten Pixel auf dem Display. Mit der> Initialisierunssequenz von Stefanus ging es dann.
Blöderweise enthält das Datenblatt des SSD1306 keine klaren
Informationen zur korrekten Initialisierung. Die findest du aber (schön
mit Diagramm) im Datenblatt der Displays (OLED+Chip+Kabel).
Stefanus F. schrieb:> Blöderweise enthält das Datenblatt des SSD1306 keine klaren> Informationen zur korrekten Initialisierung.
Ja das ist mir allerdings auch aufgefallen. Aber mit deiner Initsequenz
hat es dann ja auch bei mir geklappt. Wobei ich aber meine, in einem
Datenblatt vom 1306 auch mal eine Auflistung von Registern gesehen hab,
die von der Reihenfolge her die Initsequenz gewesen sein könnte. Sollte
sie es gewesen sein, wurde allerdings nirgendwo erwähnt, das sie es ist.