Forum: Mikrocontroller und Digitale Elektronik STM8, SPI und SSD1306 - seltsames Verhalten


von Viktor B. (coldlogic)


Angehängte Dateien:

Lesenswert?

Hi Leute,
Hatte jemand schon ein OLED SSD1306 erfolgreich zum Laufen bekommen? Ich 
versuche gerade, eine etwas optimierte graphische Library (am STM8 
laufend) für das Display zu schreiben - also nicht das in den Tutorials 
übliche Warten auf Flags, sondern reiner Interruptbetrieb (Wieso ich 
keine fertige Lib nehme wie ug8lib? Weil der Weg das Ziel ist). Was mir 
Kopfzerbrechen bereitet, ist die Auswahl der Adressierungsmodi. Dem 
Datenblatt nach - https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf - 
sollte dafür das Kommando 0x20 + 0x0[0...3] dienen. Diesen Wert 
übermittle ich per SPI, in diesem Fall 0x20 & 0x01. (Siehe erstes Bild: 
Initialisierungssequenz und gleich danach der Befehl). Das sollte dem 
Datenblatt nach senkrechte Adressierung sein, das Display verbleibt aber 
in Page Adressing Mode - das Testmuster (Bild 2) füllt eine Zeile und 
fängt am Anfang der Zeile wieder an. Die Frage ist: Ist das Display hin? 
Es stammt zwar aus der E-Bucht, aber dass NUR dieser eine Befehl nicht 
geht ist schon arg ungewöhnlich. Manche der anderen Befehle, z.B. set 
page adress funktionieren (hab aber noch nicht alle ausprobiert). Hatte 
das schon jemand? Ist es ein gewöhnliches Problem oder hat ausgerechnet 
bei mir ein hochenergetisches Neutrino genau den einen Transistor 
zerschossen, der im OLED-Chip für diesen Befehl zuständig war?

MfG,
coldlogic

von John Doe (Gast)


Lesenswert?

Viktor B. schrieb:
> Hi Leute,
> Hatte jemand schon ein OLED SSD1306 erfolgreich zum Laufen bekommen?


Nein, garantiert noch nicht...


> sollte dafür das Kommando 0x20 + 0x0[0...3] dienen. Diesen Wert
> übermittle ich per SPI, in diesem Fall 0x20 & 0x01. (Siehe erstes Bild:
> Initialisierungssequenz und gleich danach der Befehl). Das sollte dem
> Datenblatt nach senkrechte Adressierung sein, das Display verbleibt aber
> in Page Adressing Mode - das Testmuster (Bild 2) füllt eine Zeile und
> fängt am Anfang der Zeile wieder an. Die Frage ist: Ist das Display hin?


Poste lieber den Quellcode. Oder soll jetzt jeder aus der Grafik sich 
die Befehle zurechtfrickeln?

Hast Du Befehl 21h (Set Column Address) und 22h (Set Page Address) ans 
Display geschickt?

von Viktor B. (coldlogic)


Lesenswert?

John Doe schrieb:
> Viktor B. schrieb:
>> Hi Leute,
>> Hatte jemand schon ein OLED SSD1306 erfolgreich zum Laufen bekommen?
>
> Nein, garantiert noch nicht...

Dann freut es mich, der Erste zu sein! /s

John Doe schrieb:
> Poste lieber den Quellcode. Oder soll jetzt jeder aus der Grafik sich
> die Befehle zurechtfrickeln?

Mit blauen Kästchen sind die Werte unterlegt, die an dem SPI-Bus vom 
Logic Analyser erkannt werden. Da muss man sich nichts zurechtfrickeln. 
Soll ich den Quelltext meiner main.c, SPI.c oder der SSD1306.c anhängen? 
Alle wäre ein wenig zu viel, fürchte ich.

> Hast Du Befehl 21h (Set Column Address) und 22h (Set Page Address) ans
> Display geschickt?

Ja, diese funktionieren.

von John Doe (Gast)


Lesenswert?

Viktor B. schrieb:
> Mit blauen Kästchen sind die Werte unterlegt, die an dem SPI-Bus vom
> Logic Analyser erkannt werden. Da muss man sich nichts zurechtfrickeln.
> Soll ich den Quelltext meiner main.c, SPI.c oder der SSD1306.c anhängen?
> Alle wäre ein wenig zu viel, fürchte ich.


Die Init-Sequenz und die Datensendesequenz reichen.

von Viktor B. (coldlogic)


Lesenswert?

John Doe schrieb:
> Die Init-Sequenz und die Datensendesequenz reichen.

Init-Sequenz:
1
//Display constants
2
const unsigned char OLED_init[27]= {      // Initialization Sequence
3
0xAE,                          // Display OFF (sleep mode)
4
0x20, 0b00,                        // Set Memory Addressing Mode
5
                                            // 00=Horizontal; 01=Vertical;
6
                                            // 10=Page(RESET); 11=Invalid
7
0xC8,                          // Set COM Output Scan Direction
8
0x00,                                // --set low column address
9
0x10,                          // --set high column address
10
0x40,                          // --set start line address
11
0x81, 0x1F,                        // Set contrast control register
12
0xA1,                                // Set Segment Re-map. A0=0;A1 =127
13
0xA6,                                // Set display mode. A6=Normal; A7=Inverse
14
0xA8, 63,                        // Set multiplex ratio(1 to 64)
15
0xA4,                          // Output RAM to Display
16
                                            // 0xA4=Output follows RAM content; 0xA5,Output ignores RAM content
17
0xD3, 0x00,                        // Set display offset. 00 = no offset
18
0xD5,                          // --set display clock divide ratio/oscillator frequency
19
0xF0,                          // --set divide ratio
20
0xD9, 0x22,                        // Set pre-charge period
21
0xDA, 0x12,                        // Set com pins hardware configuration
22
0xDB, 0x20,                        // --set vcomh 0x20,0.77xVcc
23
0x8D, 0x14,                        // Set DC-DC enable
24
0xAF                                        // normal mode
25
};
26
27
void Init_display(void){
28
    PG_ODR = 0xFF;
29
    PG_DDR |= 0x03;     //PG0,1 ->outputs
30
    PG_CR1 |= 0x03;     //PG0,1 ->push-pull
31
    PG_ODR &= ~(0x01);  //PG0 set low, reset display
32
    Init_SPI();
33
    PG_ODR |= (0x01);   //PG0 set high
34
    display_send_command (OLED_init, 27);
35
    display_status |= (1<<7);   //set display status as "initialised"
36
}

Datensendesequenz:
1
if (ticks > 2000){
2
    if (!(display_status & (1<<7))){
3
        Init_display();
4
        //display_change_addressing_mode(0b01);
5
        //display_erase();
6
    }else{
7
        //display_set_cursor_x (127);
8
        //display_set_cursor_y (counter_pixelwrite);
9
        display_send_data (test, 8);
10
        counter_pixelwrite++;
11
    }
12
    ticks = 0;
13
}

von Viktor B. (coldlogic)


Lesenswert?

Nachträgliche Berichtigung: Die Befehle 21h (Set Column Address) und 22h 
(Set Page Address) funktionieren NICHT. Hab mich vertan und nicht 
gesehen, dass sie exklusiv für vertikale bzw horizontale Adressierung 
sind. Das Programm mit den oben genannten Befehlen produziert schöne 
Muster, das wärs aber auch. Auf dem Logic Analyser sieht alles richtig 
aus. Achja, durch das Wackeln an den Kontakten lässt sich das Display 
übrigens auch aus dem Tritt bringen, da muss ich auch aufpassen.

von John Doe (Gast)


Lesenswert?

Nach Überfliegen sieht die Initialisierung fast brauchbar aus.

Nur schreibst Du von vertikaler Adressierung, initialisierst aber 
horizontale:
1
0x20, 0b00,                        // Set Memory Addressing Mode

Ausserdem setzt Du Config für Page-Adressing, obwohl Du vertikale haben 
willst und horizontale konfigurierst, die solltest Du weglassen:
1
0x00,                                // --set low column address
2
0x10,                          // --set high column address

von John Doe (Gast)


Lesenswert?

Achja, meine Frage nach 21h und 22h war deswegen, weil der Reset-Default 
ein  128x64-Display konfiguriert.
Wenn Du was anderes hast, musst Du die Befehle entsprechend ausführen.

von Viktor B. (coldlogic)


Lesenswert?

Die beiden Befehle (0x00, 0x10) wurden weggelassen, das Ergebnis hat 
sich nicht geändert.

Und ja, das Display ist 128x64. Hab ich vergessen zu erwähnen, sorry.

von John Doe (Gast)


Lesenswert?

So, habe mal genau Deine oben gepostete (nicht ganz korrekte) 
Initialisierung auf einen STM32F407 mit 128x64-SSD1306-OLED geschmissen.
Funktioniert soweit einwandfrei, Unterschied ist nur, dass das bei mir 
so spiegelverkehrt erscheint und dunkler ist mit Deiner Config.

Check am besten mal Deine Verkabelung. Du schreibst ja, dass Wackeln ein 
Problem ist. An der Config liegt es nicht.

von Erwin E. (kuehlschrankheizer)


Lesenswert?

Wenn du den Vertical Address Mode benutzen willst, musst du ihn 
einschalten. Nach dem Reset ist erstmal der Page Adressing Mode aktiv.
1
0x20 0x01  //set vertical adressing mode
2
3
0x21  //Set Column Adress
4
0     //Column Start Address = 0
5
127   //Column End Address = 127
6
7
0x22  //Set Page Address
8
0     //Page Start Address = 0
9
3     //3 = 4 Pages (128x32), 7 = 8 Pages (128x64)

von John Doe (Gast)


Lesenswert?

Erwin E. schrieb:
> Wenn du den Vertical Address Mode benutzen willst, musst du ihn
> einschalten. Nach dem Reset ist erstmal der Page Adressing Mode aktiv.
>
>
1
> 0x20 0x01  //set vertical adressing mode
2
> 
3
> 0x21  //Set Column Adress
4
> 0     //Column Start Address = 0
5
> 127   //Column End Address = 127
6
> 
7
> 0x22  //Set Page Address
8
> 0     //Page Start Address = 0
9
> 3     //3 = 4 Pages (128x32), 7 = 8 Pages (128x64)
10
>

Das Thema hatten wir schon abgehakt. Daran liegt es bei ihm nicht.

von Viktor B. (coldlogic)


Lesenswert?

Die Verbindungen von dem Display hab ich überprüft, es sind nur zwei 
Stecker: einmal zur Platine und einmal zum Logic Analyzer. Nach etwas 
Rumexperimentieren ist nun das Display unbenutzbar geworden: eine Hälfte 
lässt sich nicht mehr ansteuern, sieht aus als ob das Mapping von RAM zu 
den Segmenten flöten gegangen ist. Das ist jetzt ein etwas größeres 
Problem als das nicht verfügbare Horizontal Address Mode. Ein Reset 
bringt nichts, ich versuch noch was dran zu machen.

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.