PicAsSo-Adventskalender: Wir basteln am zweiten Advent fleißig weiter

Seite 4: Softwaremäßige Ansteuerung des OLEDs

Inhaltsverzeichnis

Damit die Ausgabe der Daten an das OLED möglichst schnell geschieht, wird die Taktgeschwindigkeit des Picaxe mit dem Befehl setfreq auf 32 MHz erhöht (symbol PICAXE_SPEED = m32). Dadurch ändern sich auch andere Timings, z.B. die I2C-Taktgeschwindigkeit oder die Zeitdauer beim pause-Befehl. Anstatt i2cfast muss beispielsweise i2cfast_32 verwendet werden. Bei pause muss der 8-fache Wert übergeben werden, da die Taktgeschwindigkeit acht mal höher ist als die nominalen 4 MHz. Über die Symbole PICAXE_SPEED, I2C_SPEED und DELAY sind die entsprechenden Werte definiert.

Nach Anlegen der Versorgungsspannung muss man das OLED-Modul zunächst initialisieren. Das passiert über das Unterprogramm oledInit. Dort wird durch das Makro i2c_enable_oled als erstes das I2C-Interface des Picaxe als I2C-Host mit einer Übertragungsrate von ca. 400 kHz (Fast-Mode) konfiguriert und als Client die I2C-Adresse des SSD1306 angegeben, einstellbar über Symbol SSD1306_ADDR. Makros und die Initialisierung von Displays beschreiben wir auch im Make Picaxe Special im Detail – im Artikel "Lotto Olé!". Dort nutzen wir das gleiche OLED für einen Lottotipp-Generator.

Außerdem wird mit dem Befehl pokesfr das Register SSP1STAT des Picaxe beschrieben. In diesem Register befindet sich an Bitposition 6 das Bit CKE, um im I2C-Interface den SMBus Mode zu aktivieren, damit die I2C-Pins bereits bei 2,1 Volt einen HIGH-Pegel erkennen.Achtung: Dieses Bit muss nach jedem hi2csetup Befehl gesetzt werden, da es dort wieder auf Null gesetzt wird!

Dafür brauchen wir noch die Adresse von SSP1STAT. Im Picaxe-14M2 arbeitet ein PIC16F1825-Controller, in dessen Datenblatt die Adressen der Spezialregisterfunktionen (SFR) im Abschnitt DEVICE MEMORY MAPS zu finden sind. Das Register SSP1STAT befindet sich an Adresse 0x214 in Bank4. Beim Befehl pokesfr location, data setzt sich die Angabe location wie folgt zusammen:

  • Bit 7-5: Memory Bank $00-$07 – hier also binär 100 für Bank4
  • Bit 4-0: Addresses $0C to $1F on this bank – hier also $14 bzw. binär 10100

So ergibt sich der binäre Wert 10010100 bzw. hexadezimal 0x94, den wir als Symbol angeben:

symbol SSP1STAT_SFR = 0x94

Für die OLED-Initialisierung sind eine Reihe von Befehlen notwendig. Diese werden jeweils mit dem Picaxe-Befehl hi2cout in Form von zwei Bytes übertragen, wobei das erste Byte immer Null sein muss und das zweite Byte das entsprechende Kommando überträgt. Bei jedem Aufruf von hi2cout wird automatisch am Anfang ein I2C-Start sowie die Clientadresse und am Ende ein I2C-Stop gesendet.

Nach der Initialisierung wird über das Unterprogramm oledClearDisplay der Bildschirm gelöscht. Hierzu muss zunächst über die OLED-Befehle SSD1306_PAGEADDR und SSD1306_COLUMNADDR ein Fenster mit Angabe der linken oberen sowie der rechten unteren Koordinate aufgezogen werden. Die x-Werte können dabei im Bereich von 0 bis 127 und die y-Werte im Bereich von 0 bis 7 liegen. Die x-Werte beziehen sich auf 128 jeweils 1-Pixel breite Spalten, aber die y-Werte geben eine acht Pixel hohe Zeile an, sodass sich bei 64 Pixeln insgesamt acht mögliche Zeilen ergeben. Der Pixel in der linken obersten Ecke des Displays hat die Koordinate (0,0).

Um das Display zu löschen, setzen wir die Fensterkoordinaten auf (0,0) und (127,7), um den kompletten Displaybereich zu verwenden. Nun können Datenbytes übertragen werden, die durch den SSD1306 fortlaufend in den definierten Anzeigebereich geschrieben werden. Hirbei wird bei Erreichen des rechten Fensterrands automatisch in der nächsten Zeile am linken Fensterrand weitergeschrieben. Dabei wird jedes Datenbyte als acht vertikale Anzeigepixel interpretiert, wobei sich das Bit 0 (LSB) oben befindet. Wenn also 128 Null-Bytes gesendet werden, wurde die oberste Zeile gelöscht. Für alle acht Zeilen sind also insgesamt 128*8 = 1024 Nullbytes notwendig.

Wir verwenden im Aufruf nur 32 Bytes und wiederholen das Schreiben per Schleife 32 mal, um insgesamt auf 1024 Bytes zu kommen. Bei jeder Schreibsequenz muss als erstes Byte 0x40 gesendet werden, damit der SSD1306 die Bytes korrekt als Daten und nicht als Befehle interpretiert.

Um Daten in bestimmte Displaybereiche zu schreiben, kann man die Makros OLED_CURSOR oder OLED_WINDOW verwenden. Hierbei werden als Startkoordinate die x (0..127) und y (0..7, eine Zeile umfasst 8 vertikale Pixel) Werte übergeben, so dass ähnlich wie beim Löschen des Bildschirms ein Fensterbereich aufgezogen wird mit (x,y) als linke obere Ecke. OLED_CURSOR setzt automatisch den letzten Displaypixel unten rechts, wohingegen bei OLED_WINDOW der gewünschte zweite Eckpunkt mit angegeben wird. So kann ein beliebig großes Rechteckfenster ausgewählt werden.

Mithilfe des Makros OLED_DATA können die gewünschten Daten geschrieben werden, die immer als 8 vertikale Pixel zeilenweise dargestellt werden. Solange wir mit Vielfachen von 8 Pixeln vertikal arbeiten, können wir wahlfrei auf das Display schreiben, ohne dass in der Picaxe-Firmware ein Displaybuffer benötigt wird. Ein solcher Buffer müsste für den kompletten Anzeigebereich 128 * 8 = 1024 Bytes groß sein, was jedoch die Ressourcen des Picaxe-14M2 sprengen würde. Stattdessen wird hier einfach nur in den Speicher des SSD1306 geschrieben.

Damit haben wir unseren ersten Test des OLEDs erfolgreich absolviert! Am dritten Advent werden wir uns anschauen, wie man mehr Bilder extern speichern kann und wie die Bilder komfortabler in den Speicher kommen.

Wir wünschen einen schönen 2. Advent! (stri)