Die nur für oled_i2c_sw gültigen Einstellungen betreffen lediglich die Anschlusspins, auf denen der I2C-Bus kommunizieren soll. Per Default sind hier eingestellt PC1 für den SDA Anschluss, PC2 für den SCL Anschluss. Da der I2C-Bus mittels Bitbanging realisiert ist, können hierfür jede verfügbare GPIO-Pins verwendet werden. #define i2c_sda_hi() PC1_float_init() #define i2c_sda_lo() { PC1_output_init(); PC1_clr(); } #define i2c_is_sda() is_PC1() #define i2c_scl_hi() PC2_float_init() #define i2c_scl_lo() { PC2_output_init(); PC2_clr(); }
Die nur für die Hardwareversion oled_i2c gültige Einstellung betrifft die Taktrate des internen I2C-Taktgenerators. Ein OLED-Display kann bei nicht all zu langen Leitungen gut mit einer Taktrate von 1 MHz betrieben werden, mit #define i2c_clkrate 1000000kann dieses eingestellt werden. Die Werteangabe entspricht der Frequenz in Hz, hier also 1 MHz.
Die wichtigste Einstellung im Header ist die Deviceadresse des Displays. Hier kann es schon die erste "Verwirrung" im Umgang einem I2C-Displays geben. Grundsätzlich besteht eine I2C-Adresse aus 7 Bits, die in einem Byte jedoch die Position D1 bis D7 einnimmt. D0 eines Bytes beinhaltet ein sogenanntes r/w - Flag. Da in einem Byte diese 7 - Bit Adresse um eine Position nach links verschoben ist, entspricht dieses einer Multiplikation mit 2. Die Angabe hier im Header bezieht sich auf eine Adresse, die in einem Byte bereits um eine Stelle nach links verschoben ist. Die allermeisten Displaymodule werden mit der Adresse 0x78 ausgeliefert. Sollte ein Display eine andere Adresse haben, manche Display besitzen Lötbrücken um die Adresse einstellbar zu machen, so ist eine geänderte Adresse hier anzugeben. #define ssd1306_addr 0x78 // I2C-Adresse Display
Die Einstellungen im Header sind: /* -------------------------------------------------- Schriftstile -------------------------------------------------- */ #define font5x7_enable 0 // 1: Schriftstil verfuegbar, 0: nicht verfuegbar #define font8x8_enable 1 // 1: Schriftstil verfuegbar, 0: nicht verfuegbar #define use_full_ascii 1 // 0: Ascii-Zeichen bis 127 verfuegbar // 1: Ascii-Zeichen bis 255 verfuegbar, Codepage 850
Unter Displayeigenschaften sind #defines angegeben, die das Verhalten des Displays steuern. Derzeit betreffen diese Eigenschaften lediglich die Auflösung des Displays sowie das Einschalten eines Framebuffers. In der aktuellen Version der Sourcecodes wird noch keine andere Auflösung als 128x64 Pixel unterstützt (für andere Mikrocontrollerfamilien wurde dieses jedoch bereits erarbeitet und so wird es wahrscheinlich auch für CH32V003 in einer späteren Version Quellcode für weitere Auflösungen geben). Da derzeit jedoch, wie bereits geschrieben, keine weitere Auflösung unterstützt wird, sollten die Angaben für _xres und _yres uangetastet bleiben. Die zweite Eigenschaft betrifft den Framebuffer. Ein Framebuffer ist deshalb notwendig, weil das Ram des Display nur Byteweise beschrieben werden kann und nicht rücklesefähig ist. D.h. ein einzelnes Pixel ist nicht setzbar, ohne das weitere 8 Pixel geschrieben werden. Für Grafikausgaben, die eben das Setzen einzelner Pixel verlangen, muß die Ausgabe erst in einen Zwischenspeicher (eben dem Framebuffer) geschrieben und dieses dann als ganzes in das Displayram geschrieben werden. Aufgrund des wenigen RAM des CH32V003 kann es für manche Projekte jedoch ratsam sein, auf Grafikausgaben zu verzichten und das SSD1306 OLED-Display als reines Textdisplay zu verwenden. Hierfür ist der Framebuffer abschaltbar. Ein abgeschalteter Framebuffer bedeutet, dass der RAM (hier 1038 Byte von insgesamt 2048) nicht belegt wird und somit für das Anwenderprogramm zur Verfügung steht. Anmerkung: Textausgaben werden mit oled_i2c / oled_i2c_sw grundsätzlich nicht über den Framebuffer ausgegeben, sondern werden direkt in das Displayram geschrieben (für Textausgaben in den Framebuffer existiert eine gesonderte Funktion). Die Einstellungen im Header sind: /* -------------------------------------------------- Displayeigenschaften -------------------------------------------------- */ #define _xres 128 #define _yres 64 #define fb_enable 1 // Framebuffer enable // 1 = es wird RAM fuer Framebuffer // reserviert und Grafikfunktionen werden eingebunden // 0 = kein Displayram und keine Grafikfunktionen #define fb_size 1038 // Framebuffergroesse in Bytes (wenn fb_enable)
void lcd_init (void); void clrscr (void); void setfont (uint8_t fnr); void lcd_putchar (uint8_t ch); void showimage (uint16_t ox, uint16_t oy, const uint8_t* const image, char mode); void fb_init (uint8_t x, uint8_t y); void fb_clear (void); void fb_show (uint8_t x, uint8_t y); void fb_putpixel (uint8_t x, uint8_t y, uint8_t col); void line (int x0, int y0, int x1, int y1, uint8_t col); void rectangle (uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t col); void ellipse (int xm, int ym, int a, int b, uint8_t col ); void circle (int x, int y, int r, uint8_t col ); void fastxline (uint8_t x1, uint8_t y1, uint8_t x2, uint8_t col); void fillrect (int x1, int y1, int x2, int y2, uint8_t col); void fillellipse (int xm, int ym, int a, int b, uint8_t col ); void fillcircle (int x, int y, int r, uint8_t col ); void fb_putcharxy (int x, int y, uint8_t ch); void fb_outtextxy (int x, int y, char *p); void fb_showbmp (uint16_t ox, uint16_t oy, const uint8_t* const image, char mode ); Globale Variable;
uint8_t invchar; uint8_t textsize;
void lcd_init(void); initialisiert zuerst das I2C-Interface und anschließend das OLED-Display zur Benutzung
void clrscr(void); löscht den Displayinhalt mit der in der globalen Variable bkcolor angegebenen "Farbe" (0 = schwarz, 1 = hell).
void setfont(uint8_t fnr); legt die Schriftgröße für die Ausgabe sowohl im Textdirektmodus wie auch für den Framebuffer fest. Übergabe: fnr : 0 => Font 5x7 1 => Font 8x8Hinweis: Im Header ist ein Enumerator deklariert, dessen Mitglieder in Verbindung mit setfont die Schriftgröße ebenfalls auswählen: setfont(fnt5x7); setfont(fnt8x8);
void lcd_putchar(uint8_t ch); gibt ein Zeichen direkt ohne "Umweg" über den Framebuffer auf dem Display aus. Folgende Steuerzeichen für bspw. printf) sind implementiert:
10 = line feed 8 = delete last char ch : auszugebendes Zeichen
void showimage(uint16_t ox, uint16_t oy, const uint8_t* const image, char mode); zeigt ein monochromes Bitmap an den Koordinaten x,y an, wie es bspw. vom Konverterprogramm IMAGE2C (im Archiv enthalten) erzeugt worden ist. showimage schreibt hier NICHT in den Framebuffer, sondern zeigt das Bitmap direkt auf dem Display an! Übergabe: ox,oy : Koordinaten, an dem das Bitmap ausgegeben werden soll. Da in Y-Auflösung immer nur 8 Pixel gleichzeitig gesetzt werden können, entspricht die Y-Koordinate einer Textkoordinate, d.h.: für oy= 0 entspricht dieses der Grafikkoordinate 0, für oy= 1 entspricht dieses der Grafikkoordinate 8! Die Angabe für ox entspricht einer Grafikkoordinate. Deshalb sind gültige Werte für ox 0..127, für oy 0..7. mode : Zeichenmodus 0 = Bitmap wird mit der in bkcolor angegebenen Farbe gelöscht 1 = Bitmap wird so wie es ist gezeichnet 2 = Bitmap wird invertierend gezeichnetSpeicherorganisation des Bitmaps: X-Koordinate ---------------------------------------------------------------------- 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ... Byte (0) Byte (1) Y= Zeile 0 D7 D6 D5 D4 D3 D2 D1 D0 D7 D6 D5 D4 D3 D2 D1 D0 Byte (Y*X_Bytebreite) Byte (Y*X_Bytebreite)+1 Y =Zeile 1 D7 D6 D5 D4 D3 D2 D1 D0 D7 D6 D5 D4 D3 D2 D1 D0 ----------------------------------------------------------------------
void fb_init(uint8_t x, uint8_t y); initialisiert den Framebuffer Übergabe: x = Framebuffergröße in x Richtung y = Framebuffergröße in y Richtung Aufloesung der y-Pixel muss durch 8 geteilt werden Beispiel für einen Framebuffer der Pixelgröße 84x48 fb_init(84, 6);
void fb_clear(void): löscht den Inhalt des Framebuffers
void fb_show(uint8_t x, uint8_t y); zeigt den Framebufferspeicher ab der Koordinate x,y (linke obere Ecke) auf dem Display an. Da die Speicherorganisation in Y-Achse jeweils 8 Pixel per Byte umfassen, ist die möglichste unterste Y- Koordinate 7 (entspricht Pixelkoordinate 7 * 8 = 56) Übergabe: x,y : Position, an der der Inhalt des Framebuffers angezeigt wird
void fb_putpixel(uint8_t x, uint8_t y, uint8_t col); setzt im Framebuffer einen Pixel an Position der Koordinate x,y. Übergabe: x, y : Koordinate, an der der einzelne Pixel ausgegeben wird col : 0 = Pixel wird gelöscht 1 = Pixel wird gesetzt 2 = Pixel wird mit dem bisherigen Inhalt des Framebuffers XOR-verknüpft
void line(int x0, int y0, int x1, int y1, uint8_t col); Zeichnet im Framebuffer eine Linie von den Koordinaten x0,y0 zu x1,y1 Übergabe: x0, y0 : Koordinate an der die Linie beginnt x1, y1 : Koordinate, an der die Linie endet col : 0 = Pixel werden gelöscht 1 = Pixel werden gesetzt 2 = Pixel werden mit dem bisherigen Inhalt des Framebuffers XOR-verknüpft
void rectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t col); zeichnet im Framebuffer ein Rechteck von den Koordinaten x0,y0 nach x1,y1 Übergabe: x0, y0 : Koordinate linke, obere Ecke des Rechtecks x1, y1 : Koordinate rechte, untere Ecke des Rechtecks col : 0 = Pixel werden gelöscht 1 = Pixel werden gesetzt 2 = Pixel werden mit dem bisherigen Inhalt des Framebuffers XOR-verknüpft
void ellipse(int xm, int ym, int a, int b, uint8_t col ); zeichnet im Framebuffer eine Ellipse mit Mittelpunkt an der Koordinate xm, ym und einem Höhen- Breitenverhältnis a:b Übergabe: x, y : Mittelpunktkoordinate der Ellipse a, b : Höhen- Breitenverhältnis der Ellipse col : 0 = Pixel werden gelöscht 1 = Pixel werden gesetzt 2 = Pixel werden mit dem bisherigen Inhalt des Framebuffers XOR-verknüpft
void circle(int x, int y, int r, uint8_t col ); zeichnet im Framebuffer einen Kreis mit Mittelpunt an der Koordinate xm,ym und dem Radius r Übergabe: x, y : Mittelpunktkoordinate des Kreises r : Radius col : 0 = Pixel wird gelöscht 1 = Pixel wird gesetzt 2 = Pixel wird mit dem bisherigen Inhalt des Framebuffers XOR-verknüpft
void fastxline(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t col); zeichnet im Framebuffer eine Linie in X-Achse mit den X Punkten x1 und x2 auf der Y-Achse y1 Übergabe: x1, y1 : Koordinate Startpunkt der X-Linie x2 : Endpunkt x-Koordinate der Linie col : 0 = Pixel werden gelöscht 1 = Pixel werden gesetzt 2 = Pixel werden mit dem bisherigen Inhalt des Framebuffers XOR-verknüpft
void fillrect(int x1, int y1, int x2, int y2, uint8_t col); zeichnet im Framebuffer ein ausgefülltes Rechteck von den Koordinaten x0,y0 nach x1,y1 Übergabe: x0, y0 : Koordinate linke, obere Ecke des Rechtecks x1, y1 : Koordinate rechte, untere Ecke des Rechtecks col : 0 = Pixel werden gelöscht 1 = Pixel werden gesetzt 2 = Pixel werden mit dem bisherigen Inhalt des Framebuffers XOR-verknüpft
void fillellipse(int xm, int ym, int a, int b, uint8_t col ); zeichnet im Framebuffer eine ausgefüllte Ellipse mit Mittelpunt an der Koordinate xm, ym und einem Höhen- Breitenverhältnis a:b Übergabe: x, y : Mittelpunktkoordinate der Ellipse a, b : Höhen- Breitenverhältnis der Ellipse col : 0 = Pixel werden gelöscht 1 = Pixel werden gesetzt 2 = Pixel werden mit dem bisherigen Inhalt des Framebuffers XOR-verknüpft
void fillcircle(int x, int y, int r, uint8_t col ); zeichnet im Framebuffer einen ausgefüllten Kreis mit Mittelpunt an der Koordinate xm,ym und dem Radius r Übergabe: x, y : Mittelpunktkoordinate der Ellipse r : Radius col : 0 = Pixel werden gelöscht 1 = Pixel werden gesetzt 2 = Pixel werden mit dem bisherigen Inhalt des Framebuffers XOR-verknüpft
void fb_putcharxy(int x, int y, uint8_t ch); gibt ein Zeichen auf dem Framebuffer aus Übergabe: x, y : Grafikkoordinate, an der das Zeichen im Framebuffer ausgegeben wird ch : auszugebendes Zeichen
void fb_outtextxy(int x, int y, char *p); zeigt einen String im Framebuffer an Übergabe: x, y : Grafikkoordinate, an der der String im Framebuffer ausgegeben wird *p : Zeiger auf den auszugebenden String
void fb_showbmp(uint16_t ox, uint16_t oy, const uint8_t* const image, char mode ); kopiert ein Bitmap in den Framebuffer an den Koordinaten ox, oy, wie es bspw. vom Konverterprogramm IMAGE2C erzeugt worden ist. Übergabe: ox,oy : Koordinaten, an dem das Bitmap im Framebuffer ausgegeben werden soll. mode : Zeichenmodus 0 = Bitmap wird mit der in bkcolor angegebenen Farbe gelöscht 1 = Bitmap wird so wie es ist gezeichnet 2 = Bitmap wird invertierend gezeichnetSpeicherorganisation des Bitmaps: X-Koordinate ---------------------------------------------------------------------- 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ... Byte (0) Byte (1) Y= Zeile 0 D7 D6 D5 D4 D3 D2 D1 D0 D7 D6 D5 D4 D3 D2 D1 D0 Byte (Y*X_Bytebreite) Byte (Y*X_Bytebreite)+1 Y =Zeile 1 D7 D6 D5 D4 D3 D2 D1 D0 D7 D6 D5 D4 D3 D2 D1 D0 ----------------------------------------------------------------------
Vom Benutzer können Variable zur Steuerung von Ausgabeoptionen verwendet werden, diese sind:
bkcolor= 1; clrscr();
invchar= 1; my_printf("Hallo Welt");
Für textsize == 0 (default) wird ein Zeichen in der Standardgröße ausgegeben, für textsize == 1 wird bei der Ausgabe ein Zeichen in Breite und Höhe durch Vergrößerung eines Zeichenpixels doppelt so groß ausgegeben: textsize= 0; my_printf("\n\rkleine Ausgabe"); textsize= 1; my_printf("\n\rGross"); textsize= 0; my_printf("\n\rwieder klein"); |