STM8, SPI und SSD1306 - seltsames Verhalten

OP #6200966
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
Angehängte Dateien:
Gast
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?
OP
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.
Gast
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.
OP
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
}
OP
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.
Gast
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
Gast
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.
Gast
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.
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)
Gast
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.
OP
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.