Forum: Projekte & Code [ASM] SSD1306 text library für oled displays + AVR 0- und 1-Series


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 Steffen H. (avrsteffen)


Angehängte Dateien:

Lesenswert?

Da ich immer noch sehr viel in Assembler programmiere und auch mal diese 
kleinen OLed Displays ausprobieren wollte ist mir aufgefallen, dass es 
nur Treiber in C, C++ oder Bascom gibt. Deswegen hab ich mich dran 
gesetzt und versucht das ganze einmal in AVR Assembler umzusetzen.

Raugekommen ist dabei eine kleine Library für den Oled-Displaytreiber 
SSD1306 zum Darstellen von Text im 8x8 Font. Das benutzte Interface ist 
hierbei I2C (TWI).

Das ganze ist allerdings auf die neuen AVR Controller der 0-Serie oder 
1-Serie ausgelegt. Dabei sind noch viel mehr kleine Include Datein 
entstanden die bei den neuen Serien sehr vorteilhaft sind. So zum 
Beispiel die der Interruptvectoren.

Ich habe dazu auch mal ein Beispiel wie man die Library benutzt mit 
angehangen.

Bis jetzt stehen Funktionen wie:
- oled_init
- oled_clr_screen
- oled_home
- oled_gotoxy(x,y)
- oled_write_char(c)
- oled_write_string(x,y,*Y)
- oled_write_fstring(x,y,*Z)
zur Verfügung.

Die Beschreibung der Funktionen stehen in der SSD1306_driver.inc mit 
drin.

An alle ASM Fans der AVR Familie, über Rückmeldung würde ich mich 
freuen.

MfG Steffen

von Steffen H. (avrsteffen)



Lesenswert?

Hallo Leute,

Ich hab das ganze mal noch ein bisschen aufgebohrt. Jetzt können 
verschiedene Fonts in verschiedenen Größen benutzt werden. Durch 
Bit-Schubserei kann dieser sogar an beliebiger Stelle im Display 
positioniert werden, keine Pageweise Adressierung sondern Pixelgenaue. 
Noch wird kein Abbild (virtueller Displayspeicher) im SRAM benötigt.

Die Fontdaten stammen vom GLCDCreator2.1 und mussten noch zur Benutzung 
in Assembler modifiziert werden. Diese Daten sind allerdings so eine Art 
"packed". Das heißt, dass jedes Zeichen so seine eigene 
Zeichen-Pixel-Breite hat und so auch mal mehr oder weniger Speicher 
benötigt. Denn ein "!" ist schmaler als ein "W". Und genau das wird hier 
genutzt.

Was mich hier gerade noch stört ist, dass der Assembler in jeder 
Datenzeile noch ein "padding Zero" anhängt wenn die Summe der Datenbytes 
ungerade ist.

Desweiteren ärgert mich die Möglichkeit den Inhalt der aktuelle 
Speicherstelle vom DRAM des SSD1306 auslesen zu können. Zumindest 
mittels I2C geht es nicht.


Mfg Steffen

*die 1. "SSD1306_APEdriver.inc" Datei ist leider eine noch im Test 
befindliche Include Datei um Fonts in ein serielles SPI EEPROM 
auszulagern..

von Erwin E. (kuehlschrankheizer)


Angehängte Dateien:

Lesenswert?

Steffen H. schrieb:
> Durch
> Bit-Schubserei kann dieser sogar an beliebiger Stelle im Display
> positioniert werden, keine Pageweise Adressierung sondern Pixelgenaue.
> Noch wird kein Abbild (virtueller Displayspeicher) im SRAM benötigt.

Die Pixelgenaue Ausgabe finde ich sehr interessant. Wie schaffst du es 
aber, ein Zeichen mit 10 Pixeln beispielsweise an der y-Pos 10 
auszugeben und anschließend ein weiteres Zeichen an der gleichen x-Pos 
mit z.B. y-pos 24? Da du den Inhalt des GRAM nicht lesen kannst (und 
auch keinen Buffer verwendest), sollte eigentlich das zuerst ausgegebene 
Zeichen teilweise überschrieben werden. Zur Verdeutlichung: In der 
Skizze der grüne Bereich ist gemeint.

Ich habe einen SSD1306-Treiber in C geschrieben, der ebenfalls 
verschiedene Fontgrößen erlaubt und ohne Buffer auskommt, aber für 
dieses Problem habe ich keine Lösung gefunden. Eigentlich war ich bisher 
der Meinung, das ist schlicht nicht möglich, wenn man nicht lesend auf 
das GRAM zugreifen kann und auch keinen Buffer verwendet.

von Steffen H. (avrsteffen)



Lesenswert?

Erwin E. schrieb:
> Eigentlich war ich bisher
> der Meinung, das ist schlicht nicht möglich, wenn man nicht lesend auf
> das GRAM zugreifen kann und auch keinen Buffer verwendet.

Ja, genau so ist es auch. Weil normalerweise löst man dies über eine 
Maske. Man muss den von dir gemeinten (Page) grünen Bereich einlesen und 
dann mit den neuen Daten "ODER" verknüpfen.
Das kann man nur über ein Abbild (Buffer im SRAM) schaffen. Somit wird 
es auch schwieriger eine Grafik-Library zu schreiben.

Deswegen mag ich diese Displaytreiber auch nicht so.

Mir geht es hier viel mehr um die Fonts. Hier auf einem EPSON Controller 
(S1D13700)

MfG Steffen

von Erwin E. (kuehlschrankheizer)


Lesenswert?

Steffen H. schrieb:
> Noch wird kein Abbild (virtueller Displayspeicher) im SRAM benötigt.

Tippfehler? Du verwendest also doch einen Puffer?

von Steffen H. (avrsteffen)


Lesenswert?

Nein, noch verwende ich keinen Displayspeicher. Also wenn man da nicht 
Obacht gibt, dann überschreibt man ganz schnell eine andere Zeile.

Deswegen werde ich versuchen einen Displayspeicher im SRAM zu 
integrieren. Mal schauen, wie hoch da dann noch die Performance ist.

Jetzt gerade arbeite ich an der Anbindung eines seriellen SPI EEPROMs um 
die Fonts darin unterzubringen. So bleibt der Flash der MCU frei..

MfG Steffen

von Steffen H. (avrsteffen)


Angehängte Dateien:

Lesenswert?

Es gibt Neuigkeiten!

Die Erste Neuerung:
ist die Auslagerung der Fontdaten in ein externes SPI-EEPROM. Das 
funktioniert gut. Dazu muss eine spezielle SSD1306 EPP Library 
eingebunden werden und der EEPROM natürlich vorher mit den Fontdaten 
programiert/geschrieben werden.
Den Unterschied wieviel Flash Speicher man dadurch spart seht ihr an 
Bild(1) ohne, und Bild(2) mit EEPROM.


Die Zweite Neuerung:
ist wie schon vorher gesagt, die Nutzung des SRAM als Displayspeicher. 
Bei einem Display von 128x64 Pixeln benötigt man da 8219 Bit. Macht also 
bei 8Bit Speicherbreite genau 1024 Bytes an Speicher. Da für eine 
Nutzung des SRAM als virtuellen Display Speicher noch einiges mehr an 
Zwischenspeicher für die ein oder andere Variable gebraucht wird, kommen 
da mindestens nochmal 180 Bytes SRAM hinzu. Damit fällt ein ATmega8 
schonmal raus!

Allerdings gibt es ja hier nun endlich die neuen AVR's der 1er und 0er 
Serie.
Durch die Nutzung des Display Speichers ist nun auch Grafik auf den 
kleinen OLED Displays möglich. Ich habe dazu auch eine Library 
geschrieben. Alles in ASM!

Text mit unterschiedlichen Fonts in unterschiedlichen Größen und eben 
ein wenig Grafik wie Rechtecke, Linien, Kreise und abgerundete 
Rechtecke.

In der Grafik SSD1306_GFX.inc stehen folgende Funktionen zur Verfügung:
- oled_set_pixel
- oled_draw_hline
- oled_draw_vline
- oled_draw_line
- oled_draw_rect
- oled_draw_fill_rect
- oled_draw_round_rect
- oled_draw_round_fill_rect
- oled_draw_circle
- oled_draw_fill_circle

Ach ja, wenn man das T-Flag vor Aufruf der Funktion setzt, dann wird 
nicht gezeichnet, sondern das das Objekt gelöscht. Und es existieren 
auch MAKROS um die Funktionen einfacher aufzurufen, zumindest wenn man 
mit festen Werten (Konstanten) für Koordinaten und Längen arbeitet.
Somit kann man dann zum Beispiel eine Linie mit
1
ldi    XL,0   ; Startpunkt X
2
ldi    YL,3   ; Startpunkt Y
3
ldi    XH,10  ; Endpunkt X
4
ldi    YH,20  ; Endpunkt Y
5
rcall  oled_draw_line
oder mit MACRO
1
draw_line   0,3,10,20    ; (Xstart,Ystart,Xende,Yende)
eine Linie zeichnen. Möchte man allerdings eine Linie (oder welches 
Objekt auch immer) löschen, setzt man einfach vor dem Funktionsaufruf 
das T-Flag.
Beispiel: Löschen eines eines gefüllten Rechtecks mit abgerundeten Ecken
1
set                          ; setze T-Flag
2
draw_rfrect  10,10,30,14,4   ; (Xstart,Ystart,Xweite,Yhoehe,radius)
3
clt                          ; lösche T-Flag wieder
als MACRO


Mal schauen wer es gebrauchen kann
MfG Steffen

von Steffen H. (avrsteffen)


Angehängte Dateien:

Lesenswert?

Hier mal ein Beispiel zur Nutzung

Ein ATtiny1614 generiert eine PWM um einen Modellbau Servo zu testen. 
Dazu wird ein ADC Kanal im 10Bit Modus benutzt und auf 8Bit runter 
geteilt.
--> Anzeige des ADC Wertes mit "ADC-RAW" und Animation als 
Balkendiagramm
Die errechnete Pulszeit dann in "ms" in der nächsten Zeile
--> mit einer kleinen Puls Animation.
Als letzter Wert dann den zugehörigen Compare Wert für den Timer TCA.


MfG Steffen

von Bernhard S. (bernhard)


Lesenswert?

Hallo Steffen,

Deine Beispiele in Assember sind Dir sehr gut gelungen, klasse!

Frage: Wie lange dauert es, um das DEBO OLED2 0.96 Entwicklerboards - 
Display, 0,96", OLED-Display, 128 x 64 Pixel, komplett zu löschen?

Dank Deines Beispiels bekam ich erst mein TWI I2C Display zum laufen.

von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

so geht's nach meiner Meinung schneller, soll jetzt keine Kritik sein:

SCL, bei 8MHz Takt: 222kHz

Auf das TWI-Stop habe ich verzichtet, TWI Master Transmitter bewirkt das 
gleiche, spart Zeit :-)
1
OLED_CLEAR:
2
3
  ldi temp1,(SSD1306_ADR)
4
  rcall TWI_MT_START_TEMP1 ; MT-Start
5
  ldi  temp1,(SSD1306_CONTROL_BYTE_DATA_STREAM)  ; CONTROL Byte: DATA STREAM
6
  rcall TWI_MT_TX_TEMP1                  ;i2c write DATA
7
8
  ldi ZL, low(1024)                ; Schleife    
9
  ldi ZH,high(1024)
10
OLED_CLEAR_s:
11
  ldi temp1,0x00                  ;i2c write DATA
12
  rcall TWI_MT_TX_TEMP1
13
  sbiw ZL,1
14
  tst ZL                ; Schleife 
15
  brne OLED_CLEAR_s
16
  tst ZH                ; Schleife 
17
  brne OLED_CLEAR_s
18
ret

: Bearbeitet durch User
von Bernhard S. (bernhard)


Lesenswert?

Was ich nicht verstehe:

Du sendest einen TWI-Start und anschließend 
"SSD1306_CONTROL_BYTE_DATA_STREAM" (0x40) und anschließend die 
anzuzeigenden Daten.

Ich hätte das nie so aus dem Datenblatt herausgelesen, dort steht:

10.1.6 Set Display Start Line (40h~7Fh)
This command sets the Display Start Line register to determine starting 
address of display RAM, by selecting
a value from 0 to 63. With value equal to 0, RAM row 0 is mapped to 
COM0. With value equal to 1, RAM
row 1 is mapped to COM0 and so on.

Übersetzung:
10.1.6 Startlinie der Anzeige einstellen (40h ~ 7Fh)
Dieser Befehl setzt das Display Start Line-Register, um die Startadresse 
des Anzeige-RAM durch Auswahl zu bestimmen
ein Wert von 0 bis 63. Mit einem Wert gleich 0 wird die RAM-Zeile 0 auf 
COM0 abgebildet. Bei einem Wert von 1 RAM
Zeile 1 ist COM0 usw. zugeordnet.

: Bearbeitet durch User
von Bernhard S. (bernhard)


Lesenswert?

Wenn ich eine FFh an das Display sende wird mir ein vertikaler Strich 
angezeigt.

Kann durch senden eines FFh auch ein horizontaler angezeigt werden?

von Steffen H. (avrsteffen)


Lesenswert?

Bernhard S. schrieb:
> TWI Master Transmitter bewirkt das
> gleiche

Was bedeutet "TWI Master Transmitter"? Und ohne ein "STOP" gibt man ja 
die I2C Schnittstelle nicht wieder frei. Die meisten Anwendungen 
verwenden mehrere Teilnehmer am I2C Bus.
1
  ldi ZL, low(1024)                ; Schleife    
2
  ldi ZH,high(1024)
3
OLED_CLEAR_s:
4
  ldi temp1,0x00                  ;i2c write DATA
5
  rcall TWI_MT_TX_TEMP1
6
  sbiw ZL,1
7
  tst ZL                ; Schleife 
8
  brne OLED_CLEAR_s
9
  tst ZH                ; Schleife 
10
  brne OLED_CLEAR_s
11
ret
Den Test auf NULL deines Z Registers kannst du dir nach einer 
mathematischen Operation sparen. Denn
1
sbiw   ZL,1
manipuliert schon all deine Status-Flags..
Es reicht hier folgender Code:
1
  ldi ZL, low(1024)                ; Schleife    
2
  ldi ZH,high(1024)
3
OLED_CLEAR_s:
4
  ldi temp1,0x00                  ;i2c write DATA
5
  rcall TWI_MT_TX_TEMP1
6
  sbiw ZL,1
7
  brne OLED_CLEAR_s               ; Schleife
8
ret


Bernhard S. schrieb:
> Was ich nicht verstehe:
>
> Du sendest einen TWI-Start und anschließend
> "SSD1306_CONTROL_BYTE_DATA_STREAM" (0x40) und anschließend die
> anzuzeigenden Daten.
Danke für den Hinweis. Ich habe jetzt wirklich lange recherchiert, um 
nachzuvollziehen, warum und woher ich diese Befehle hatte. ---> Ich kann 
es nicht sagen. :(
Hast du es denn mal ohne diese BYTESTREAM und SINGLEBYTE Befehle 
probiert?
Ich sehe hier gerade nur das man in der I2C Kommunikation zwischen 
COMMAND und DATA Befehlen unterscheidet und so ein CONTROLLBYTE 
nach dem ADRESSBYTE gesendet werden muss, um dem SSD1306/SSD1309 zu 
sagen was die folgenden Daten zu bedeuten haben.

Gruß Steffen

von Steffen H. (avrsteffen)


Lesenswert?

Bernhard S. schrieb:
> Wenn ich eine FFh an das Display sende wird mir ein vertikaler Strich
> angezeigt.
>
> Kann durch senden eines FFh auch ein horizontaler angezeigt werden?

Kannst du davon bitte mal ein Foto machen?
Welches OLED Display benutzt du?

von Steffen H. (avrsteffen)


Angehängte Dateien:

Lesenswert?

Jetzt hab ich doch etwas dazu gefunden. Im Datasheet zum SSD1306 steht 
etwas dazu (Seite 21 - 8.1.5.1 I2C-Bus Write Data).
Ganz so schlau werde ich davon nicht, aber irgendwo her hatte ich da 
meine Informationen :)

PS:
Hier noch ein Link wo es erklärt ist:
https://www.instructables.com/Getting-Started-With-OLED-Displays/

: Bearbeitet durch User
von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Steffen H. schrieb:
>> Wenn ich eine FFh an das Display sende wird mir ein vertikaler Strich
>> angezeigt.
>>
>> Kann durch senden eines FFh auch ein horizontaler angezeigt werden?
>
> Kannst du davon bitte mal ein Foto machen?
> Welches OLED Display benutzt du?

Sende ich ein 0xFF dann wird mir ein vertikaler Strich bestehend aus 8 
Pixeln gezeichnet, siehe "ist.jpg" (ist eine Fotomontage), gern hätte 
ich die Variante "soll.jpg", geht das überhaupt??

Momentan verwende ich dieses Display:

DEBO OLED2 0.96 Entwicklerboards - Display, 0,96", OLED-Display, SSD1306

https://www.reichelt.de/nl/de/entwicklerboards-display-0-96-oled-display-ssd1306-debo-oled2-0-96-p266107.html?search=SSD1306&&r=1

von Bernhard S. (bernhard)


Lesenswert?

Steffen H. schrieb:
> Den Test auf NULL deines Z Registers kannst du dir nach einer
> mathematischen Operation sparen. Denn sbiw   ZL,1
> manipuliert schon all deine Status-Flags..
> Es reicht hier folgender Code:

Danke für den Tipp, ab sofort werde ich es so tun,
wieder etwas dazugelernt :-)
1
   ldi ZL, low(1024)                
2
   ldi ZH,high(1024)
3
OLED_CLEAR_s:
4
   ldi temp1,0x00                  ;i2c write DATA
5
   rcall TWI_MT_TX_TEMP1
6
   sbiw ZL,1
7
   brne OLED_CLEAR_s               ; Schleife
8
  ret

noch etwas effizienter, werde mal bei Gelegenheit mit einem Oszi messen, 
wie lange es tatsächlich dauert das Diplay komplett zu löschen:
1
   ldi ZL, low(1024/8)                
2
   ldi ZH,high(1024/8)
3
OLED_CLEAR_s:
4
   ldi temp1,0x00                  ;i2c write DATA
5
   rcall TWI_MT_TX_TEMP1           ; TX 8x Null
6
   rcall TWI_MT_TX_TEMP1
7
   rcall TWI_MT_TX_TEMP1
8
   rcall TWI_MT_TX_TEMP1
9
   rcall TWI_MT_TX_TEMP1
10
   rcall TWI_MT_TX_TEMP1
11
   rcall TWI_MT_TX_TEMP1
12
   rcall TWI_MT_TX_TEMP1
13
   brne OLED_CLEAR_s               ; Schleife
14
  ret

: Bearbeitet durch User
von Bernhard S. (bernhard)


Lesenswert?

Steffen H. schrieb:
> Was bedeutet "TWI Master Transmitter"? Und ohne ein "STOP" gibt man ja
> die I2C Schnittstelle nicht wieder frei. Die meisten Anwendungen
> verwenden mehrere Teilnehmer am I2C Bus.0

Richtig, ein Stop gibt den Bus wieder frei.

Häufig wird diese Variante verwendet Master + SlaveA + SlaveB + SlaveC 
usw., also ein Master und seine Sklaven.

Selten findet man Multi-Master-Systeme: MasterA + MasterB usw + SlaveA + 
SlaveB usw., nur dann wird's kompliziert, wenn jeder mit jedem und wenn 
dann noch die Master zu Slaves mutieren... na dann viel Spaß bei der 
Programmierung.

TWi/I2C Kommunikation:

Im Ruhezustand befindet sich SDA und SCL immer auf High.

Zuerst sendet der Master ein "TWI-Start". SCL und SDA werden vom Master 
gegen LOW gezogen und nach kurzer Zeit SDA wieder hochohmig, also auch 
wieder High.

Und auf diese Pegelzustände bzw. Änderungen warten alle am Bus 
angeschlossenen Slaves.

Nun sendet der Master das "Adressbyte", ein ganz wichtiges Byte, nämlich 
die Adresse das gewünschten Sklaven und ob als nächstes der Master etwas 
senden oder etwas von seinem Sklaven empfangen möchte.

Das ganze kan mann als Startkondition bezeichen. ("TWI-Start" + 
"Adressbyte")

Der angesprochene Sklave sendet einen ASK, also ein Antwortimpuls (damit 
signalisiert er seine Bereitschaft für die nächste Aktion.

Alle anderen Sklaven halten die Klappe bis zum nächsten "TWI-Start".

Nun sendet der Master ein Daten-Bit, welches wieder vom Slave durch 
einen Impuls bestätigt wird (ACK), fehlt die Antwort, z.B. wegen 
Hardwareproblemen, dann hat der Master ein Problem, welches durch eine 
vernünftige Erroroutine kompensiert werden sollte.

Nachdem der Master sine Daten gesendet oder empfangen hat kann er ein 
TWI-Stop senden, muss er aber nicht,
er kann auch sofort wieder eine erneute "Startkondition" senden, gut 
programmierte Sklave verstehen das.

Gern sende ich bei Programmstarts und auch zwischendurch 
Startkonditionen, um zu prüfen, ob die Sklaven schon oder noch willig 
sind.

Und aus diesem Grung kannst Du getrost
1. "Startkondition"
2. (SSD1306_CONTROL_BYTE_CMD_STREAM)
3. Daten
5. Daten
6. ....

senden, ein TWI-Stop ist nicht zwingend erforderlich.

Du kannst, musst aber nicht :-)



Master-Transmitter-Start:
1
ldi    r16,OLED_ADDR
2
lsl    r16
3
mov    i2c_addr,r16
4
rcall  twi_send_wr_start


Master-TX-DATA:
1
ldi r16, (SSD1306_CONTROL_BYTE_CMD_STREAM)          ; 
2
sts    (TWI0_MDATA),r16
3
rcall  get_twi_wr_ack

: Bearbeitet durch User
von Bernhard S. (bernhard)


Lesenswert?

Hallo Steffen, ich hoffe, ich verletze keine Urheberrechte^^

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

Gruß

Bernhard

von Steffen H. (avrsteffen)


Angehängte Dateien:

Lesenswert?

Hallo Bernhard

Bernhard S. schrieb:
> Sende ich ein 0xFF dann wird mir ein vertikaler Strich bestehend aus 8
> Pixeln gezeichnet, siehe "ist.jpg" (ist eine Fotomontage), gern hätte
> ich die Variante "soll.jpg", geht das überhaupt??

Das ist ja komisch, dass dein Display unten rechts anfängt zu zeichnen. 
Ist das wirklich der Nullpunkt? Also Position X0, Y0?

Ich kenne die Displays nur so, dass oben die Anschlüsse sind und dann 
auch oben links angefangen wird zu zeichnen. Also der Nullpunkt X0 Y0 
dort ist.

Jetzt noch zu der Sache mit den Display RAM Adressen. Das musst du dir 
folgendermaßen vorstellen. Dieser Controller (SSD1306) legt an einer 
Speicherstelle im Displayspeicher (RAM) die Pixeldaten in 8Bit = 1Byte 
ab. Dabei ist jedes Bit = 1Pixel auf dem Display. Diese 8Bits werden 
senkrecht von oben (LSB) nach unten (MSB) in einer Spalte (COLUMN) 
dargestellt. Demzufolge bildet man mit 1Byte = 8Bits = 8Pixel immer 
genau 1Spalte (1Column) und 8 Zeilen (8 Rows) ab. Dies wird im 
Datenblatt auf Seite 37 super dargestellt.

Diese Adressbelegung kann man nicht ändern. Man nennt diese 8Bit 
Zeilenadressierung auch Pageweise Adressierung (64 Zeilen/8Bits = 8 
Pages). Man kann in der Y-Richtung also nur von 0..7 adressieren.

Somit ist die von dir gewünschte waagerechte Linie nur mit einem zu 
schreibenden Byte nicht möglich.

Ich hoffe ich habe jetzt keinen Blödsinn geschrieben..


Bernhard S. schrieb:
> so geht's nach meiner Meinung schneller, soll jetzt keine Kritik sein:
>
> SCL, bei 8MHz Takt: 222kHz
>
> Auf das TWI-Stop habe ich verzichtet, TWI Master Transmitter bewirkt das
> gleiche, spart Zeit :-)

Jetzt mal noch hierzu etwas:
Ich habe versucht den ganzen Display RAM (Display Seite) auf einmal, 
genau so wie du mit 1024 Bytes zu löschen. Dies hat bei mir irgendwie 
nie funktioniert. Ich konnte immer nur Pageweise (Seitenweise), also 
immer nur eine Zeile löschen. Deswegen auch nach jeder Zeile ein 
"I2C-Stop" und eine neue Adressierung der Pageadresse zum Display mit 
folgendem Schreiben der Daten.


Gruß Steffen

von Bernhard S. (bernhard)


Lesenswert?

Hallo Steffen,

Danke für Deine Erklärung

Steffen H. schrieb:
> Ich kenne die Displays nur so, dass oben die Anschlüsse sind und dann
> auch oben links angefangen wird zu zeichnen. Also der Nullpunkt X0 Y0
> dort ist.

Nun sind auch meine Anschlüsse oben und es zeichnet auch von links oben 
nach rechts unten^^

Steffen H. schrieb:
> Ich habe versucht den ganzen Display RAM (Display Seite) auf einmal,
> genau so wie du mit 1024 Bytes zu löschen.

Wenn Du einen ATmega8 oder ATmega328p herumkullern und etwas Zeit dafür 
hast, einfach mal testen, das hex-File liegt mit bei:

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

Es könnte auch eine andere SSD1306 Version sein, ev. hat der Hersteller 
hier nachgebessert.

Gruß Bernhard

: Bearbeitet durch User
von Steffen H. (avrsteffen)


Angehängte Dateien:

Lesenswert?

Steffen H. schrieb:
> Ich habe versucht den ganzen Display RAM (Display Seite) auf einmal,
> genau so wie du mit 1024 Bytes zu löschen. Dies hat bei mir irgendwie
> nie funktioniert. Ich konnte immer nur Pageweise (Seitenweise), also
> immer nur eine Zeile löschen. Deswegen auch nach jeder Zeile ein
> "I2C-Stop" und eine neue Adressierung der Pageadresse zum Display mit
> folgendem Schreiben der Daten.

Ich habe den Fehler gefunden. Es lag an dem Memory Addressing Mode. Hier 
habe ich bei der Initialisierung und auch der Funktion "oled_gotoxy" den 
PageAdressingMode mit dem HorizontalAdressingMode gemischt und 
falsche Startadressen angegeben.

Dies hab ich nun auf "Horizontal Addressing" geändert. Und was soll ich 
sagen.. Super flink jetzt geworden um ein komplett neues Bild zu 
zeichnen.

Komplettes Display löschen oder zeichnen dauert jetzt nur noch ca. 28ms 
bei fTWI = 400.000 Hz.

von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Steffen H. schrieb:
> Komplettes Display löschen oder zeichnen dauert jetzt nur noch ca. 28ms
> bei fTWI = 400.000 Hz.

Das ist aber noch nicht das Ende der Fahnenstange^^

Mit diesem Code sind es nur noch 22,8ms

Wird TWBR auf Null gesetzt, dann nur 11,6ms

TWBR=0---> empfiehlt aber nicht das Datenblatt (mind.10),
könnte ev. Probleme geben, ausprobieren.



1
; #############################################################################
2
; #############################################################################
3
; #############################################################################
4
GO_HOME:
5
  ldi temp1,(SSD1306_ADR)                    ;i2c start          
6
  rcall TWI_MT_START_TEMP1  
7
8
  ldi  temp1,(SSD1306_CONTROL_BYTE_CMD_STREAM)          ; CONTROL Byte: CMD STREAM  
9
  rcall TWI_MT_TX_TEMP1
10
11
  clr temp1
12
  ori  temp1,(SSD1306_CMD_SET_PAGE_START_ADDRESS)        ; SET_PAGE START_ADDRESS  
13
  rcall TWI_MT_TX_TEMP1
14
15
  ldi  temp1,(SSD1306_CMD_SET_COLUMN_ADDRESS)          ; SET_COLUMN_ADDRRSS    
16
  rcall TWI_MT_TX_TEMP1
17
18
  ldi temp1,0        ; Start Address
19
  rcall TWI_MT_TX_TEMP1
20
21
  ldi  temp1,127      ; End Address
22
  rcall TWI_MT_TX_TEMP1
23
24
  ldi temp1,(SSD1306_CMD_SET_DISPLAY_START_LINE)+(0)    ; SET_DISPLAY_START_LINE
25
  rjmp TWI_MT_TX_TEMP1
26
; #############################################################################
27
; #############################################################################
28
; #############################################################################
29
OLED_CLEAR:
30
  LED_GELB_ON
31
  rcall GO_HOME
32
33
.equ SCHLEIFEC=1024/16
34
  ldi temp1,(SSD1306_ADR)              ;i2c start          
35
  rcall TWI_MT_START_TEMP1
36
  ldi  temp1,(SSD1306_CONTROL_BYTE_DATA_STREAM)  ; CONTROL Byte: DATA STREAM
37
  rcall TWI_MT_TX_TEMP1
38
39
  ldi ZL, low(SCHLEIFEC)              ; Schleife    
40
  ldi ZH,high(SCHLEIFEC)
41
OLED_CLEAR_s:
42
  ldi temp1,0x00                  ;i2c write DATA
43
  rcall TWI_MT_TX_TEMP1
44
  ldi temp1,0x00                  ;i2c write DATA
45
  rcall TWI_MT_TX_TEMP1
46
  ldi temp1,0x00                  ;i2c write DATA
47
  rcall TWI_MT_TX_TEMP1
48
  ldi temp1,0x00                  ;i2c write DATA
49
  rcall TWI_MT_TX_TEMP1
50
  ldi temp1,0x00                  ;i2c write DATA
51
  rcall TWI_MT_TX_TEMP1
52
  ldi temp1,0x00                  ;i2c write DATA
53
  rcall TWI_MT_TX_TEMP1
54
  ldi temp1,0x00                  ;i2c write DATA
55
  rcall TWI_MT_TX_TEMP1
56
  ldi temp1,0x00                  ;i2c write DATA
57
  rcall TWI_MT_TX_TEMP1
58
  ldi temp1,0x00                  ;i2c write DATA
59
  rcall TWI_MT_TX_TEMP1
60
  ldi temp1,0x00                  ;i2c write DATA
61
  rcall TWI_MT_TX_TEMP1
62
  ldi temp1,0x00                  ;i2c write DATA
63
  rcall TWI_MT_TX_TEMP1
64
  ldi temp1,0x00                  ;i2c write DATA
65
  rcall TWI_MT_TX_TEMP1
66
  ldi temp1,0x00                  ;i2c write DATA
67
  rcall TWI_MT_TX_TEMP1
68
  ldi temp1,0x00                  ;i2c write DATA
69
  rcall TWI_MT_TX_TEMP1
70
  ldi temp1,0x00                  ;i2c write DATA
71
  rcall TWI_MT_TX_TEMP1
72
  ldi temp1,0x00                  ;i2c write DATA
73
  rcall TWI_MT_TX_TEMP1
74
  sbiw ZL,1
75
  brne OLED_CLEAR_s
76
LED_GELB_OFF
77
ret
78
; #############################################################################
79
; #############################################################################
80
; #############################################################################

: Bearbeitet durch User

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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