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
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..
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.
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
Steffen H. schrieb: > Noch wird kein Abbild (virtueller Displayspeicher) im SRAM benötigt. Tippfehler? Du verwendest also doch einen Puffer?
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
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
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
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.
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
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
Wenn ich eine FFh an das Display sende wird mir ein vertikaler Strich angezeigt. Kann durch senden eines FFh auch ein horizontaler angezeigt werden?
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
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?
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
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
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
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
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
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
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
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.