Forum: Projekte & Code OLED128x128 SSD1351 RGB Initialisierung Color Farbe bunt SPI 3.3V AVR ATmega8 ATmega328p Assembler


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Kleine Beispiele, einfach und unkompliziert, schnell zusammengefummelt 
zur Initialisierung eines

1.44 "zoll Serielle SPI 128x128 Farbe TFT LCD Display Moduls in
Assembler mit AVR Studio 4.

Vorsicht, das Display verträgt nur 3.3V und benötigt, wenn alle Pixel 
kräftig leuchten ca. 200mA. Gegebenefalls einen Level-Shifter oder 
gemeine Widerstände zur Pegelanpassung verwenden.

Version-1, mit einem 8MHz getakteten ATmega328p.

Das Display wird grundlegend initialisiert, kurz nach dem Anlegen der 
Betriesspannung sehen wir ein verrauschtes Bild, normalerweise ist das 
nicht so informativ, aber in diesem Fall schon, denn es funktioniert 
grundlegend.

Und nun wartet das Display geduldig auf Pixeldaten.

Zuerst ein Kommando 5Ch senden, DC ist dabei low, dann DC auf high und 
immer 2Bytes Farbwerte senden.

2Bytes Farbcodierung:
__high____|low______
0b00000|000000|00000
__rot__|grün__|blau_
0...31 |0..63 |0...31

Um das Display komplett zu beschreiben, das dauert...

128x128=16.384 Pixel x 2Bytes(Farbwert)=32.768 Bytes + diverse Kommandos

Das Nadelöhr ist die Hardware-SPI, warten, bis ein Byte nun endlich 
übertragen worden ist.

Nochmals ein ganz großes Dankeschön an Steffen, er spendierte mir eine 
herrliche Vorlage.

Siehe TWI/I2C OED128x64 Display:
Beitrag "DEBO OLED2 0.96 0,96" OLED-Display SSD1306 SSD1312 Initialisierung TWI I2C AVR ATmeg8 Assembler ASM"

Den Assembler-Code habe ich versucht gut zu kommentieren,
damit Ihr Ver- und Optimierungen vornehmen könnt.

Für Vorschläge, Tipps und konstruktive Kritik bin ich sehr dankbar.

Bernhard

: Bearbeitet durch User
von Steffen H. (avrsteffen)


Lesenswert?

Bernhard S. schrieb:
> Um das Display komplett zu beschreiben, das dauert...

Wenn es optimal läuft sollte das bei 8Mhz Systemtakt und daraus 
resultierender maximalem SPI Takt von 2MHz ein Bild in ca. 17ms 
übertragen lassen. Das ist immerhin noch mehr als 50Hz 
Bildwiederholfrequenz wenn man daraus ein Loop macht.

Also bei 4MHz SPI Takt geht das noch flotter..

Gruß Steffen

: Bearbeitet durch User
von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Steffen H. schrieb:
> Wenn es optimal läuft sollte das bei 8Mhz Systemtakt und daraus
> resultierender maximalem SPI Takt von 2MHz ein Bild in ca. 17ms
> übertragen lassen.

Sehr seltsam, real habe ich bei 8MHz µC Takt 101ms
und bei 16MHz 51ms gemessen, warum diese große Abweichung?

Ich erkenne kaum noch Optimierungspotential:
1
OLED_CLEAR:
2
  ldi ZL,low (128*32)
3
  ldi ZH,high(128*32)
4
OLED_CLEAR_s:
5
  SPI_TX_NULL
6
  SPI_TX_NULL
7
  SPI_TX_NULL
8
  SPI_TX_NULL
9
  SPI_TX_NULL
10
  SPI_TX_NULL
11
  SPI_TX_NULL
12
  SPI_TX_NULL
13
  sbiw ZL,1
14
  brne OLED_CLEAR_s  
15
ret
1
.macro SPI_TX_NULL
2
  out SPDR,NULL      ; Start transmission of data 
3
  in temp,SPSR
4
  sbrs temp,SPIF
5
  rjmp PC-2          ; Wait for transmission complete
6
.endm

: Bearbeitet durch User
von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Version-2

ASCII mit vier Fonts durch Bitstretching Bitverdopplung aus einem 8x8 
Zeichensatz, ADC und Timer.

Font-0  8x8
Font-1  8x16
Font-2 16x16
Font-3 32x32

Bild "B3" Zeit für OLED.clear 103ms bei MHz µC Takt,
viel schneller geht vermutlich nicht :(


Im Bild "B4" wird die Zeit für den Bildaufbau angezeigt, ca. 70ms

die Zeit seit Programmstart und die Betriebsspannung.

14% Flash, da passt noch viel rein^^

: Bearbeitet durch User
von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Version-2 mit ATmega8

Zusätzlich wird der Registerinhalt von MCUCSR ausgewertet, um den Grund 
des letzten Resets zu erfahren, z.B. wurde die Resettaste betätigt, so 
als Spielerei^^

Momentan ist der ATmega8 schon zu 50% gefüllt, werden diverse 
Testprogramme entfernt, dann sieht's diesbezüglich freundlicher aus.

Strombedarf im Haupmenue: ca.50mA

Display komplett weiß gefüllt: ca.200mA

: Bearbeitet durch User
von Stefan (bitflipser) (Gast)


Lesenswert?

Steffen H. schrieb:
> Bernhard S. schrieb:
>> Um das Display komplett zu beschreiben, das dauert...
>
> Wenn es optimal läuft sollte das bei 8Mhz Systemtakt und daraus
> resultierender maximalem SPI Takt von 2MHz ein Bild in ca. 17ms
> übertragen lassen. Das ist immerhin noch mehr als 50Hz
> Bildwiederholfrequenz wenn man daraus ein Loop macht.
>
> Also bei 4MHz SPI Takt geht das noch flotter..
>
> Gruß Steffen

Im double-speed Modus max. Fclk/2, also 4 MHz auf einem 8 MHz-ATmega328
und 8 MHz SPI-Takt auf einem 16 MHz-ATmega328.

Bernhard S. schrieb:
> Sehr seltsam, real habe ich bei 8MHz µC Takt 101ms
> und bei 16MHz 51ms gemessen, warum diese große Abweichung?
>
> Ich erkenne kaum noch Optimierungspotential:
> OLED_CLEAR:
>   ldi ZL,low (128*32)
>   ldi ZH,high(128*32)
> OLED_CLEAR_s:
>   SPI_TX_NULL
>   SPI_TX_NULL
>   SPI_TX_NULL
>   SPI_TX_NULL
>   SPI_TX_NULL
>   SPI_TX_NULL
>   SPI_TX_NULL
>   SPI_TX_NULL
>   sbiw ZL,1
>   brne OLED_CLEAR_s
> ret
> .macro SPI_TX_NULL
>   out SPDR,NULL      ; Start transmission of data
>   in temp,SPSR
>   sbrs temp,SPIF
>   rjmp PC-2          ; Wait for transmission complete
> .endm

Wenn es richtig schnell gehen soll, dann - ohne SPDR-Abfrage - alle 18 
Takte einen Wert ins SPI Datenregister schreiben.
Der entscheidende Satz aus dem datasheet ist: "Writing to the register 
initiates data transmission." (23.5.3. SPI Data Register 0)
Warum es jetzt nicht 16 sind, kann ich nicht sagen. Ich habe 16 und 17 
ausprobiert, aber funktionieren tut es erst ab 18 Takten.

von Steffen H. (avrsteffen)


Lesenswert?

Geht nicht, da der SSD1351 eine minimale Clock time von 220ns hat. Und 
das ist ergibt einen maximalen SPI Takt von 4,55 Mhz.

: Bearbeitet durch User
von Stefan (bitflipser) (Gast)


Lesenswert?

Das ist ja immerhin mehr als die auf einem 8 MHz-ATmega möglichen 4 MHz 
...
Da ließe sich an den erwähnten 101 ms bei 8 MHz bestimmt etwas machen.

Steffen H. schrieb:
> Wenn es optimal läuft sollte das bei 8Mhz Systemtakt und daraus
> resultierender maximalem SPI Takt von 2MHz ein Bild in ca. 17ms
> übertragen lassen. Das ist immerhin noch mehr als 50Hz
> Bildwiederholfrequenz wenn man daraus ein Loop macht.
>
> Also bei 4MHz SPI Takt geht das noch flotter..
>
> Gruß Steffen

17 ms bei 2 MHz ?? echt ??

128 x 128 Pixel x 2 Byte = 32.768 Bytes -> 262.144 bits
bei 2 MHz SPI-Takt wären das theoretisch: 131,072 ms (!)
bei 4 MHz SPI-Takt wären das theoretisch:  65,536 ms
in der Praxis (18 Takte pro Byte) ->       73.728 ms
Wie gesagt bei 8 MHz Fclk und 4 MHz SPI-Clock

Gruß Stefan

von Steffen H. (avrsteffen)


Lesenswert?

Da hast du Recht Stefan. Ich habe in Bytes und nicht in Bits gerechnet. 
Gut dass es nochmal jemand nachrechnet.

Danke

von Reneg (Gast)


Lesenswert?

Hallo Leute, sorry wenn ich jetzt - schon etwas spät - noch meinen Senf 
(echten Born-Senf) hinzugeben muss :D

Keine Ahnung, ob ich ein besonders ausgefallenes SSD1351 Display habe. 
Meines funktioniert jenseits aller Datenblätter aber auch mit 39MHz SPI, 
max. Framerate von 148Hz.
Ok, ich nutze auch eine 78MHz sys clk. Wollte nur anbringen, dass die 
Displays oft mehr können, als die Datenblätter einen Glauben machen 
wollen.

Ich nehme übrigens an, dass es nur alle 18 Takte funktioniert, weil das 
Display (zumindest im angehängten Sourcecode) mit 18bit-pro-pixel 
initialisiert wird.

von Bernhard S. (bernhard)


Lesenswert?

...Born-Senf schmeckt köstlich ;-)


> weil das
> Display (zumindest im angehängten Sourcecode) mit 18bit-pro-pixel
> initialisiert wird.

Wie kommst Du auf die 18 Bit pro Pixel?

von Reneg (Gast)


Lesenswert?

>> Ich nehme übrigens an, dass es nur alle 18 Takte funktioniert, weil das
Display (zumindest im angehängten Sourcecode) mit 18bit-pro-pixel
initialisiert wird.

Edit, Kommando zurück, 0+1 sind beides 16bit, ich habe 0 benutzt

von Reneg (Gast)


Lesenswert?

>Für Vorschläge, Tipps und konstruktive Kritik bin ich sehr dankbar.

SPI_TX_RX_TEMP_w:
  WDR
  LED_GELB_ON
  in temp,SPSR
  sbrs temp,SPIF
  rjmp SPI_TX_RX_TEMP_w  ; Wait for transmission complete

Du machst die LED zu oft an

von Reneg (Gast)


Lesenswert?

Und eine Frage habe ich hier, da ich AVR asm gar nich kenne - ich war 
nur mal neugierig:

OLED_SET_PIXEL:
  mov temp,FARBE_H    ;  PIX COLOR H
  rcall SPI_TX_TEMP
  mov temp,FARBE_L    ;  PIX COLOR L
  rjmp SPI_TX_TEMP

Warum wird einmal rcall und einmal rjmp benutzt? Kommt mir gerade recht 
willkürlich vor.

von Reneg (Gast)


Lesenswert?

oder ersetzt das am Ende einer Funktion ein rcall/ret?

von Bernhard S. (bernhard)


Lesenswert?

Reneg schrieb:
> Du machst die LED zu oft an

Da hast Du Recht.

Aber, es ist eh eine Warteschleife, ob sich das wesentlich auf die 
Übertragungsgeschwindigkeit auswirkt?

Idealer Wiese könnte man durch einige NOPs, also ohne Sprungbefehl, die 
maximale übertragungsrate erreichen, ohne vorher den Übertragungszustand 
abzufragen.

Danke

Reneg schrieb:
> Warum wird einmal rcall und einmal rjmp benutzt? Kommt mir gerade recht
> willkürlich vor.

...spart Takte

>oder ersetzt das am Ende einer Funktion ein rcall/ret?

ja

: Bearbeitet durch User
von Reneg (Gast)


Lesenswert?

Kommt halt drauf an, wie schnell die CPU gegenüber dem SPI ist, also wie 
lange sie warten muss. In diesem speziellen Falle wirkt es sich wohl 
nicht aus. War auch nur ein Tipp zum Codefluß.

Was man mal ausprobieren könnte, SPI_TX_TEMP zu einem Makro zu machen 
mit einem etwas anderen Namen und das an zeitkritischen Stellen 
verwenden.
Damit würde man die rcall/ret Takte sparen. Wäre das eine Idee?

von Reneg (Gast)


Lesenswert?

Traurigerweise muss ich meine Frequenzangabe noch korrigieren. 39MHz 
laufen zwar, aber nicht komplett stabil. Vermutlich sind hier 
irgendwelche Parasiten am Werke, ob nun Kapaziterien oder EMViren hier 
neben meinem PC-Platz ist mir nicht bekannt. Nach 1-2min gibts nur noch 
Pixelmüll. 38MHz laufen jetzt aber schon seit 2h ohne Probleme.

von Johannes S. (jojos)


Lesenswert?

bis die Sonne rauskommt und den Testaufbau erwärmt. Mit Kältespray kann 
man vielleicht noch ein paar MHz rausholen. Gut wenn man die Limits 
kennt, aber allgemeingültig und praktisch ist sowas nicht.

von Reneg (Gast)


Lesenswert?

@bernhard
Ich nehme übrigens an, dass du kein weiteres Gerät an deinen SPI 
pinubbels hast. Du kannst also CS auch direkt festverdrahten und dir das 
pin für was wichtigeres verwenden.

von Bernhard S. (bernhard)


Lesenswert?

Reneg schrieb:
> ... und dir das pin für was wichtigeres verwenden.

Was würde passieren, wenn dadurch bei Programmstart "versehentlich" ein 
Bit gesendet wird?

von Reneg (Gast)


Lesenswert?

die Initialisierungssequenz des Displays basiert auf dem Timing des RST 
pins

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.