Forum: Mikrocontroller und Digitale Elektronik 0,91" OLED Display (SSD1306) I2C Ansteuerung


von Alexander F. (gustin)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
ich befasse mich gerade zum ersten mal mit dem TWI/I2C Bus
und versuche mit einem ATmega8 (in Assembler) eins dieser
0,91" OLED Displays (128x32 Px, SSD1306, zB. EBay 162891883868)
ans leuchten zu bringen (An 5V, soll angeblich gehen).
Wälze jetzt schon seit einigen Stunden die Datenblätter,
und das Internet durch, aber es will einfach nicht.

Stand jetzt startet der ATmega und wartet eine halbe
Sekunde um dem Display Zeit zu lassen hochzufahren.
Laut Datenblatt vom Displaycontroller müssten alle
Werte (Kontrast, etc.) nach dem Reset für meine Zwecke passen,
es soll erstmal nur leuchten.
Dann spreche ich es an.

Nachfolgend mein Verständnis:
Laut Datenblatt ist der Displaycontroller über die Adressen
3C oder 3D ansprechbar.
Wie im angehängten "command table" zu sehen benötige ich die
Befehle
0xA5 => alle Pixel auf AN
0xAF => Display einschalten/aufwecken

Damit das Display die Befehle als solche interpretiert,
muss ich ein 0x80 voran schicken. (auf 0x00 folgt ein Datenbyte,
auf 0x40 folgt ein Datensatz).

Also sende ich:
START -> SLA_W -> 0x80 -> 0xA5 -> 0x80 -> 0xAF -> STOP
(Reihenfolge nach Datenblatt Displaycontroller)

Was passiert? Das Diplay leuchtet nach dem Datenempfang
ganz kurz (ca. 0,5s) komplett auf, aber recht dunkel,
und geht dann sofort wieder aus.

Was habe ich bereits probiert?
- Zuerst das Display wecken, schlafend kann es ja keine Daten empfangen.
- Nach dem Aufwecken eine Pause eingefügt, damit es in Ruhe starten kann
- Nur mit 0xA5 angesprochen
- Nur mit 0xAF angesprochen
Das Ergebnis ist immer das gleiche: kurzes aufblinken.

Die Pakete werden ordnungsgemäß verschickt und der Empfang quittiert,
im Anhang ist eine Beispielmessung.
Online finde ich nur Beispiele mit irgendwelchen Libraries,
prinzipiell ist das Vorgehen, also die gesendeten Pakete,
aber das gleiche wie bei mir, allerdings kann ich da ja nicht 
nachvollziehen was noch alles (von den Libraries im Hintergrund)
mitgesendet wird (Stichwort: Initialisierung).

Kann es gar sein, dass das Display die 5V doch nicht so gut
verträgt und nach dem Empfang einfach abstürzt/resettet?
(Habe gerade leider keine 3,3V Quelle zum testen)
Würden die Signale dann aber so sauber quittiert?
Oder hab ich einfach etwas essentielles übersehen?

Vielleicht kann mir ja jemand auf die Sprünge helfen.

Liebe Grüße

von Timmo H. (masterfx)


Lesenswert?

So sieht meine Init vom SSD1306 aus, funzt gut bei mir
1
void GLCD_LcdInit(void)  {
2
    // Recommended power up sequence
3
    clrbit(LCD_CTRL, LCD_RESET);         // Reset Low for 3 uS
4
    _delay_us(3);
5
    setbit(LCD_CTRL, LCD_RESET);         // Reset Low for 3 uS
6
    _delay_us(3);
7
    // Recommended initialization sequence
8
    LcdInstructionWrite(LCD_DISP_OFF);
9
    LcdInstructionWrite(LCD_SET_RATIO_OSC);
10
    LcdInstructionWrite(0x80);
11
    LcdInstructionWrite(LCD_MULTIPLEX);
12
    LcdInstructionWrite(0x3F);
13
    LcdInstructionWrite(LCD_SET_OFFSET);
14
    LcdInstructionWrite(0x00);
15
    LcdInstructionWrite(LCD_SET_LINE);
16
    LcdInstructionWrite(LCD_CHARGE_PUMP);
17
    LcdInstructionWrite(LCD_PUMP_ON);
18
    LcdInstructionWrite(LCD_SET_PADS);
19
    LcdInstructionWrite(0x12);
20
    LcdInstructionWrite(LCD_SET_CONTRAST);
21
    LcdInstructionWrite(0x8F);
22
    LcdInstructionWrite(LCD_SET_CHARGE);
23
    LcdInstructionWrite(0xF1);
24
    LcdInstructionWrite(LCD_SET_VCOM);
25
    LcdInstructionWrite(0x40);
26
    LcdInstructionWrite(LCD_EON_OFF);
27
    LcdInstructionWrite(LCD_DISP_NOR);
28
    LcdInstructionWrite(LCD_MEM_ADDRESSING);
29
    LcdInstructionWrite(0x00);          // Horizontal Addressing mode
30
    LcdInstructionWrite(LCD_DISP_ON);
31
  
32
}
hier noch die defines
1
// commands SSD1306 controller
2
#define LCD_SET_COL_HI    0x10
3
#define LCD_SET_COL_LO    0x00
4
#define LCD_SET_LINE    0x40
5
#define LCD_SET_CONTRAST  0x81
6
#define LCD_SET_SEG_REMAP0  0xA0
7
#define LCD_SET_SEG_REMAP1  0xA1
8
#define LCD_EON_OFF      0xA4
9
#define LCD_EON_ON      0xA5
10
#define LCD_DISP_NOR    0xA6
11
#define LCD_DISP_REV    0xA7
12
#define LCD_MULTIPLEX       0xA8
13
#define LCD_CHARGE_PUMP      0x8D
14
#define LCD_PUMP_OFF      0x10
15
#define LCD_PUMP_ON       0x14
16
#define LCD_DISP_OFF     0xAE
17
#define LCD_DISP_ON      0xAF
18
#define LCD_SET_PAGE    0xB0
19
#define LCD_SET_SCAN_FLIP  0xC0
20
#define LCD_SET_SCAN_NOR  0xC8
21
#define LCD_SET_OFFSET    0xD3
22
#define LCD_SET_RATIO_OSC  0xD5
23
#define LCD_SET_CHARGE    0xD9
24
#define LCD_SET_PADS      0xDA
25
#define LCD_SET_VCOM      0xDB
26
#define LCD_NOP         0xE3
27
#define LCD_SCROLL_RIGHT  0x26
28
#define LCD_SCROLL_LEFT    0x27
29
#define LCD_SCROLL_VR      0x29
30
#define LCD_SCROLL_VL    0x2A
31
#define LCD_SCROLL_OFF    0x2E
32
#define LCD_SCROLL_ON     0x2F
33
#define LCD_SCROLL_ON     0x2F
34
#define LCD_VERT_SCROLL_A    0xA3
35
#define LCD_MEM_ADDRESSING   0x20
36
#define LCD_SET_COL_ADDR  0x21
37
#define LCD_SET_PAGE_ADDR  0x22

von Alexander F. (gustin)


Lesenswert?

Timmo H. schrieb:
> So sieht meine Init vom SSD1306 aus, funzt gut bei mir

Super, hab den Fehler dank dem Beispiel gefunden.
Die Ladungspumpe muss eingeschaltet werden, heißt:
0x8D (charge pump setting)
und
0x14 (enable charge pump)
müssen vor dem Einschalten des Displays noch gesendet werden.

Vielen Dank :-)

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.