st77xx_display_v2.c    


Die Sourcedateien von st77xx_display_v2 beinhalten Funktionen, die den Betrieb von farbigen LC-Displays mit SPI-Interface am Controller ermöglichen.

Grundsätzlich werden Displays in solche mit und ohne Controller unterschieden. Hier ist nicht der Mikrocontroller gemeint, der das Display ansteuert, sondern derjenige der im Display integriert wird. Diese Displays könnte man auch als "Monitor mit integrierter Grafikkarte" bezeichnen.

Die Sourcedateien von st77xx_display_v2 können Displays mit integriertem Controller ansprechen.

Leider gibt es keine Norm oder einen kleinen gemeinsamen Nenner, wie diese Displays angesprochen werden. So gestaltet sich es bei der Inbetriebnahme hierbei manchmal etwas schwierig, ein Display zum Funktionieren zu bekommen. Daher erscheint die Konfiguration von st77xx_display_v2 auf den ersten Blick etwas umfangreich, sind hier doch einige Einstellungen in st77xx_display_v2.h für ein ordnungsgemäßes Funktionieren zu machen.

Grundsätzlich ist der Header st77xx_display_v2.h so dokumentiert, dass die Einstellungen ersichtlich sein sollten, dennoch werden hier die wichtigsten Dinge noch einmal aufgeführt.

Inhaltsverzeichnis dieser Seite

    Header st77xx_display_v2.h


Die Anschlusspins

Zu Beginn des Headers ist einzustellen, mit welchen Anschlusspins der Controller mit dem Display kommuniziert:
  
/*
  Anschluss Display an den CH32V003
  Mosi und Sck sind aufgrund der Verwendung von Hardware-SPI fest vorgegeben und
  koennen nicht geaendert werden. Die anderen Anschluesse sind frei waehlbar
   
  CH32V003        ---->   SPI-Display
  --------------------------------------------------------------------------
  PC6-mosi   16   ---->   sda / sdi / A0 / din
  PC5-sck    15   ---->   sck
  PC4        14   ---->   dc
  PC3        13   ---->   ce / cs   (kann auch direkt auf GND gelegt werden)
  PC2        12   ---->   rst

*/
  // PC5 ist immer SPI-Clock (Hardware-SPI)
  // PC6 ist immer SPI-MOSI (Hardware-SPI)

  #define lcd_ce_init()        PC3_output_init()
  #define lcd_dc_init()        PC4_output_init()
  #define lcd_rst_init()       PC2_output_init()
  #define lcd_pin_init()       { lcd_ce_init(); lcd_dc_init(); lcd_rst_init(); }

  #define dc_set()             PC4_set()
  #define dc_clr()             PC4_clr()

  #define ce_set()             PC3_set()
  #define ce_clr()             PC3_clr()

  #define rst_set()            PC2_set()
  #define rst_clr()            PC2_clr()

  #define lcd_enable()         (ce_clr())
  #define lcd_disable()        (ce_set())
  
Auswahl des verwendeten Displaycontrollers
  
  /* ------------------------------------------------------------------
                            Displayauswahl

       es kann (und muss) nur ein einziges Display ausgewaehlt sein.
     ------------------------------------------------------------------ */

  // ----------------------- SPI- Displays ----------------------------

  #define  ili9163                  0
  #define  ili9340                  0
  #define  st7735r                  1
  #define  s6d02a1                  0
  #define  ili9225                  0
  #define  st7789                   0

  // -----------------  ST7735R, 2. Generation Controller ------------
  //  die 128er Display der 2. Generation haben in Verbindung mit
  //  ST7735 eine andere StartColum und RowColum

  #define  st7735r_g2               1
  
Die oben mittels #define aufgeführten Displaycontroller sind verfügbar. Hier muß (und darf) nur ein einziger Controller ausgewählt werden.

Zusätzlich, sollte ST7735R ausgewählt sein, kann st7735r_g2 aktiviert werden. Der Hintergrund ist der, dass es scheinbar eine Revision des Chips gegeben hat, die mit diesem Schalter angepasst werden kann. Wird hier der Wert 1 angegeben, so wird die Displayinitialisierung für die neuere Generation bei 128x128 Pixel-Displays aktiviert

Die obige Auswahl legt fest, mit welcher Initialisierungssequenz das Display in Betrieb genommen wird.


Displayauflösung
  
  /*  ------------------------------------------------------------
                         Displayaufloesung
      ------------------------------------------------------------ */

  #define _xres                   128
  #define _yres                   160          
  
Bei der Displayauflösung ist zu beachten, dass die Displays immer hochkant initialisiert werden. D.h. der größere Zahlenwert der Pixelauflösung ist als Y-Wert anzugeben. Sollen auf dem Display später Ausgaben im Querformat gemacht werden, so kann diese im Programm mittels lcd_orientation geändert werden.


Setupflags

Mittlerweile existiert eine Vielfalt unterschiedlichster Grafikdisplays, teilweise jedoch mit einem identischen Grafikcontroller. So gibt es Displays, die ihren Datenstrom nicht in der gängigen Farbreihenfolge rot-grün-blau erwarten, sondern in der Reihenfolge blau-grün-rot! Zudem werden ein und derselbe Controller für Displays unterschiedlicher Auflösungen verwendet. Zudem gibt es Displays mit 128x128 Pixel, die aber innerhalb des Displays so verdrahtet sind, als wäre es ein 160x128 Pixel Display. Hieraus ergibt sich dann, dass das interne Display-Ram im Gegensatz zu "normalen" 128x128 Display unterschiedlich adressiert ist und somit ein Offset in der Adressberechnung notwendig ist.

Manche Displays sind so verdrahtet, dass eine spiegelverkehrte Darstellung ausgegeben wird oder eine Abbildung als "Negativdarstellung" erscheint.

Zudem sind manche Displays auf dem Bus zu langsam bei der Abarbeitung der Befehle so dass eine Wartepause zwischen den Befehlen eingefügt werden muß (aufgetreten bisher bei Displays mit ST9225 Controllern).

Die Setupflags dienen dazu, bestimmte Betriebsmodi des Displays einzustellen (siehe Kommentare):
  
/*  ------------------------------------------------------------
                       Setupflags fuer SPI-Displays
      ------------------------------------------------------------ */

  // fuer Berechnung der Adressen des Video-Rams. ACHTUNG: manche Chinadisplays 
  // behandeln 128x128 Displays so, als haette es 160 Pixel in Y-Aufloesung.
  // Fuer diesen Fall kann in "tft128" angegeben werden um welches Display es
  // sich handelt. Hat man hier den falschen Typ gewählt, ist das auf dem
  // Display durch einen breiten Streifen mit rauschenden Bildpunkten zu
  // erkennen. tft128 hat keine Auswirkung auf Displays mit anderer Aufloesung
  // als 128x128

  #define tft128           2       // 1: Display ohne Offset (aelter)
                                   // 2: Display mit Offset (neuer)

  #define rgbseq           0       // Reihenfolge der erwarteten
                                   // Farbuebergabe bei ST7735 LCD-Controllern
                                   //    0: blau-gruen-rot
                                   //    1: rot-gruen-blau

  #define tft_wait         0       // 0 = keine Wartefunktion nach spi_out
                                   // 1 = es wird nach spi_out ein nop eingefuegt


  #define flickerreduce    0       // 0 : normal
                                   // 1 : Reduzierung fuer neuere KMR-1.8 SPI 
                                   // Displays

  #define negativout       0       // 0 : normal
                                   // 1 : Farben werden invertiert wiedergegeben     
  

Schriftzeichen

Da es sich bei den Displays um Grafikdisplays handelt, beinhalten diese keinerlei Schriftzeichensätze. Sollen auch Buchstaben und Texte auf dem Display ausgegeben werden, müssen die verwendeten Bitmaps der einzelnen Buchstaben mit in den Flash-Speicher aufgenommen werden. Da Zeichensatztabellen relativ viel Speicherplatz benötigen, kann man hier auswählen, welche Schriftzeichen dem Programm zur Verfügung stehen sollen.

Die verfügbaren Schriftzeichengrößen sind:
  • font5x7
  • font8x8
  • font12x16
welche wieder über #defines aktiviert werden können (Mehrfachauswahl ist hier möglich)
  
/* ------------------------------------------------------------------
        verfuegbare Textfonts auswaehlen (auch Kombinationen erlaubt)
     ------------------------------------------------------------------ */

  #define fnt5x7_enable        1             // 1 : Font verfuegbar
                                             // 0 : nicht verfuegbar
  #define fnt8x8_enable        1             // 1 : Font verfuegbar
                                             // 0 : nicht verfuegbar
  #define fnt12x16_enable      1             // 1 : Font verfuegbar
                                             // 0 : nicht verfuegbar

  #define lastascii            126           // letztes verfuegbares Asciizeichen
  
Mit dem define "lastascii" wird angegeben, welches das höchste Ascii-Zeichen ist, das ausgegeben werden kann. Somit ist es möglich, den Zeichensatz um weitere gewünschte Zeichen zu erweitern. Ascii-Zeichen mit dem Code kleiner als 32 werden nicht ausgegeben.


Farbenstruktur des Displays / 65536 Farben

Da die hier unterstützten Displays nur 16-Bit Farben darstellen können, verwenden die Displays das RGB565 Format. Dieses bedeutet:
  • höherwertige 5 Bits für rot entspricht 25 = 32 Farbabstufungen
  • mittelwertige 6 Bits für grün entspricht 26 = 64 Farbabstufungen
  • niederwertige 5 Bits für blau entspricht 25 = 32 Farbastufungen
Aufgrund der Tatsache, dass aus einem 16-Bit Farbenraum die Farbabmischung nicht direkt ablesbar ist gibt es 2 Funktionen, die Farbzuweisungen vornehmen können. Eine hiervon, rgbfromvalue, reduziert aus 3 Einzelbytewerten (je eines für rot, grün und blau) diese auf 16 Bit (und somit können 65535 Farben abgemischt werden). Die andere verwendet ein Farbschema wie es eine (ur)alte EGA-Farbgrafikkarte vorgegeben hat. Diese Farbwerte sind im Header bereits definiert und können von einer Funktion rgbfromega verwendet werden (erleichtert bei einfachen Farben die Farbauswahl).

Die Deklarationen dieser Farben ist:
  
/*  ------------------------------------------------------------
                      EGA - Farbzuweisungen
      ------------------------------------------------------------ */

  #define black                   0
  #define blue                    1
  #define green                   2
  #define cyan                    3
  #define red                     4
  #define magenta                 5
  #define brown                   6
  #define grey                    7
  #define darkgrey                8
  #define lightblue               9
  #define lightgreen              10
  #define lightcyan               11
  #define lightred                12
  #define lightmagenta            13
  #define yellow                  14
  #define white                   15  
  
Folgende Farbzuweisung
  
       textcolor= rgbfromega(lightgreen);
  
hätte zur Folge, dass die Schriftfarbe für die nächste Textausgabe auf hellgrün gesetzt ist.



    Funktionen von st77xx_display_v2


Die Funktionen des Softwaremoduls im einzelnen:


lcd_init

void lcd_init (void);

Initialisiert das Hardware SPI des Mikrocontrollers und sendet die zur Verwendung des Displays notwendigen Initialisierungswerte an das Display. Nach Aufruf von lcd_init ist das Display betriebsbereit.


lcd_orientation

void lcd_orientation (uint8_t ori);

Gibt die Ausrichtung bei der Ausgabe auf dem Display vor. 0..3 sind zulässige Übergabewerte für ori. 0 entspricht hier, bspw. bei nicht quadratischen 160x128 Pixel Displays, einer hochkanten Ausgabe.
  • 0 : Ausgabe 0° gedreht, Hochformat
  • 1 : Ausgabe 90° gedreht, Querformat
  • 2 : Ausgabe 180° gedreht, Hochformat
  • 3: Ausgabe 270° gedreht, Querformat

Übergabe:
        ori     : legt die Ausgaberichtung fest
      
Beispiel.:
  
       lcd_orientation(1);    // Ausgabe im Querformat
  

putpixel

void putpixel (int x, int y, uint16_t color);

zeichnet einen einzelnen Punkt auf dem Display an der Koordinate x,y mit der Farbe color.

putpixel berücksichtigt die globale Variable outmode mithilfe derer es möglich ist, eine Ausgabe auf dem Display zu drehen.

Übergabe:
        x,y     : Koordinate, an der ein Farbpixel ausgegeben wird
        color   : RGB565 Farbwert, der ausgegeben wird
      

clrscr

void clrscr (void);

löscht den Displayinhalt mit der in der Variable bkcolor angegebenen Farbe


fastxline

void fastxline (uint16_t x1, uint16_t y1, uint16_t x2, uint16_t color);

zeichnet eine waagerechte Linie mit dem Startwert x1 und Endwert x2 auf der Y-Position y1

Übergabe:
        x1, x2  : Start-, Endpunkt der Linie
        y1      : Y-Koordinate der Linie
        color   :  16 - Bit RGB565 Farbwert mit dem gezeichnet  werden soll
      

fillrect

void fillrect (int x1, int y1, int x2, int y2, uint16_t color);

zeichnet ein ausgefülltes Rechteck mit den Koordinatenpaaren x1 / y1 (linke obere Ecke) und x2 / y2 (rechte untere Ecke)

Übergabe:
        x0, y0  : Koordinate linke obere Ecke
        x1,y1   : Koordinate rechte untere Ecke
        color   : Zeichenfarbe
      

rgbfromvalue

uint16_t rgbfromvalue (uint8_t r, uint8_t g, uint8_t b);
Setzt einen 16-Bitfarbwert aus 3 einzelnen Farbwerten für (r)ot, (g)ruen und (b)lau zu einem 16-Bit Wert zusammen.

Übergabe:
        r,g,b   : 8-Bit Farbwerte für rot, grün, blau. Aus diesen wird ein 16 Bit 
                  (RGB565 = 65536 Farben) Farbwert generiert 
        x1, x2  : Start-, Endpunkt der Linie
        y1      : Y-Koordinate der Linie
      
Rückgabe:
                  generierter 16-Bit Farbwert
      

rgbfromega

uint16_t rgbfromega (uint8_t entry);

liefert den 16-Bit Farbwert, der in der EGA-Farbpalette deklariert ist.

Übergabe:
        entry   : Indexnummer der Farbe in egapalette
      
Rückgabe:
                  generierter 16-Bit Farbwert
      

gotoxy

void gotoxy (unsigned char x, unsigned char y);

Setzt den Textcursor (NICHT Pixelkoordinate) an die angegebene Textkoordinate.

Übergabe:
        entry   : Indexnummer der Farbe in egapalette
        x       : X-Koordinate
        y       : Y-Koordinate
      

setfont

void setfont (uint8_t nr);

legt den Schriftstil fest, der bei einer Textausgabe verwendet werden soll. Die gewählte Schriftgröße muß im Header st77xx_display_v2.h aktiviert sein.

Übergabe:
        nr      : Schriftstil
                     0 ( fnt8x8 )   : 8 x 8 Font
                     1 ( fnt12x16 ) : 12 x 16 Font
                     2 ( fnt5x7 )   : 5 x 7 Font
      
Hinweis: Im Header ist ein Enumerator deklariert, dessen Mitglieder in Verbindung mit setfont die Schriftgröße ebenfalls auswählen können:
  
       setfont(fnt5x7);
       setfont(fnt8x8);
       setfont(fnt12x16);
  
lcd_putchar

void lcd_putchar (char ch);

gibt ein Zeichen mit der in setfont gewählten Schriftgröße aus.

Übergabe:
        ch      : auszugebendes Zeichen
      
putcharxy

void putcharxy (int x, int y, uint8_t ch);

gibt ein einzelnes Zeichen an der Grafikkoordinate x, y aus.

Der Hintergrund auf dem das Zeichen ausgegeben wird, wird NICHT mit Leerpixeln überschrieben, es werden lediglich die Pixel des Zeichens platziert.

Übergabe:
        x, y    : Grafikkoordinate, an der das Zeichen ausgegeben wird
        ch      : auszugebendes Zeichen
      
outtextxy

void outtextxy (int x, int y, uint8_t dir, char *dataPtr);

Ausgabe eines Ascii-Zero Strings an den Grafik-Koordinaten x,y. Der Text wird hierbei über den Hintergrund gelegt (der Hintergrund der Ausgabe wird nicht mit Leerpixeln der Zeichenbitmap überschrieben).

Übergabe:
        x,y      : Grafikkoordinaten, ab der der Text ausgegeben wird (linke, obere Ecke)
        dir      : Ausgaberichtung (Funktionen noch nicht implementiert)
                       0 = horizontal
                       1 = vertikal
        *dataPtr : 	Zeiger auf den Text    
      
Beispiel in Verbindung mit Makro PSTR:
  
       outtextxy(12,13,0,PSTR("Hallo Welt"));    
  

line

void line (int x0, int y0, int x1, int y1, uint16_t color);

Zeichnet eine Linie von den Koordinaten x0,y0 zu x1,y1 mit der angegebenen Farbe color

Übergabe:
        x0,y0    : Koordinate linke obere Ecke
        x1,y1    : Koordinate rechte untere Ecke
        color    : 16 - Bit RGB565 Farbwert der gezeichnet werden soll
      

rectangle

void rectangle (int x1, int y1, int x2, int y2, uint16_t color);

Zeichnet ein Rechteck von den Koordinaten x0,y0 zu x1,y1 mit der angegebenen Farbe color

Übergabe:
        x0,y0    : Koordinate linke obere Ecke
        x1,y1    : Koordinate rechte untere Ecke
        color    : 16 - Bit RGB565 Farbwert der gezeichnet werden soll
      

ellipse

void ellipse (int xm, int ym, int a, int b, uint16_t color);

Zeichnet eine Ellipse mit Mittelpunkt an Koordinate xm,ym , einem Höhen- Breitenverhaeltnis a:b und der angegebenen Farbe color

Übergabe:
        xm,ym    : Koordinate des Mittelpunktes der Ellipse
        a,b      : Höhen- Breitenverhältnis
        color    : 16 - Bit RGB565 Farbwert der gezeichnet werden soll
      

fillellipse

void fillellipse (int xm, int ym, int a, int b, uint16_t color);

zeichnet eine ausgefüllte Ellipse mit Mittelpunkt an Koordinate xm,ym , einem Höhen- Breitenverhaeltnis a:b und der angegebenen Farbe color

Übergabe:
        xm,ym    : Koordinate des Mittelpunktes der Ellipse
        a,b      : Höhen- Breitenverhältnis
        color    : 16 - Bit RGB565 Farbwert der gezeichnet werden soll
      

circle

void circle(int x, int y, int r, uint16_t color );

Zeichnet einen Kreis mit Mittelpunkt an der Koordinate xm,ym und dem Radius r

Übergabe:
        x, y     : Mittelpunktkoordinate des Kreises
        r        : Radius
        color    : 16 - Bit RGB565 Farbwert der gezeichnet werden soll
      

fillcircle

void fillcircle(int x, int y, int r, uint16_t color );

Zeichnet einen ausgefüllten Kreis mit Mittelpunkt an der Koordinate xm,ym und dem Radius r

Übergabe:
        x, y     : Mittelpunktkoordinate des Kreises
        r        : Radius
        color    : 16 - Bit RGB565 Farbwert der gezeichnet werden soll
      

showimage

void showimage(uint16_t ox, uint16_t oy, const unsigned char* const image, uint16_t fwert);

Kopiert ein im Flash abgelegtes Bitmap in den Screenspeicher. Das Bitmap muß byteweise in Zeilen gespeichert vorliegen Hierbei entspricht 1 Byte 8 Pixel.

Bsp.: eine Reihe mit 6 Bytes entsprechen 48 Pixel in der X-Achse

Hinweis: ein Array mit den Daten des anzuzeigendes Pixelbildes kann mittels des Kommandozeilentools image2c aus einem monochromen Bild aus dem Format .bmp erzeugt werden.

Übergabe:
        ox, oy   : Koordinate der linken oberen Ecke an der das Bitmap angezeigt wird
        image    : Zeiger auf ein in einem Array vorliegendes Pixelbild (Bitmap)
        fwert    :Farbwert mit der das Image gezeichnet wird    
      
Speicherorganisation 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
       ----------------------------------------------------------------------      
        
      

lcd_puts

void lcd_puts (char *c);

gibt einen Text an der aktuellen Textcursorposition aus

Übergabe:
        c        : Zeiger auf den AsciiZ - STring
      

turtle_moveto

void turtle_moveto (int x, int y);
Turtlegrafik

Mit der Turtlegrafik können "Linienbilder" (Vektoren) gezeichnet werden. Hierzu wird immer vom Endpunkt einer vorangegangenen Zeichenaktion eine Linie zur angegebenen Koordinate x,y gezeichnet.

turtle_moveto setzt einen neuen Anfangspunkt für eine Turtlegrafik, ohne etwas zu zeichnen.

Übergabe:
    	 x,y      : Koordinaten, an der das Zeichnen beginnt
      

turtle_lineto

void turtle_lineto (int x, int y,uint16_t col);
Turtlegrafik

Mit der Turtlegrafik können "Linienbilder" (Vektoren) gezeichnet werden. Hierzu wird immer vom Endpunkt einer vorangegangenen Zeichenaktion eine Linie zur angegebenen Koordinate x,y gezeichnet.

turtle_lineto zeichnet eine Linie vom Endpunkt der vorausgegangenen Zeichenaktion zu dem Koordinatenpaar x,y mit der Farbe col

Übergabe:
       x,y      : Koordinatenpaar, bis zu der eine Linie gezeichnet wird
       col      : 16 - Bit RGB565 Farbwert mit dem gezeichnet werden soll   
      

    Globale Variable von st77xx_display_v2 und deren Funktion


Für das Arbeiten mit st77xx_display_v2 gibt es globale Variable, die vom Benutzer zur Steuerung der Displayausgaben verwendet werden können.

Die Bedeutung der Variable im einzelnen:
  • uint16_t bkcolor;

      Beinhaltet einen 16-Bit RGB565 Farbwert. Dieser Farbwert bestimmt die Hintergrundfarbe bei Textausgaben sowie die Farbe, mit der ein Displayinhalt mittels clrscr() gelöscht wird

  • uint16_t textcolor;

      Beinhaltet einen 16-Bit RGB565 Farbwert. Dieser Farbwert bestimmt bei Textausgaben die Schriftfarbe, mit der ein Text ausgegeben wird.

  • uint16_t egapalette[ ];

      Array, welches 16 RGB565 Farbwerte aufnimmt. Durch Beschreiben eines der Elemente des Arrays kann die Farbpalette verändert werden.

  • int aktxp; int aktyp;

      Variable für Textkoordinate. aktxp / aktyp beinhaltet die Koordinate, an der das nächste Textzeichen ausgegeben wird. Die Koordinate wird nach jeder Zeichenausgabe mittels lcd_putchar und gotoxy automatisch aktualisiert.

  • uint8_t textsize;

      textsize bestimmt die Größe der Schriftausgabe. Beinhaltet textsize den Wert 0, werden Zeichen so ausgegeben wie sie in den Fontarrays definiert sind. Beinhaltet textsize den Wert 1, wird jeder Pixel bei der Zeichenausgabe in x- und y-Ausrichtung gedoppelt. D.h. bei einem 8 x 8 Font wird ein (pixeliges) 16 x 16 Zeichen ausgegeben werden.

  • uint8_t fntfilled;

      gibt an, ob eine Zeichenausgabe über einen Hintergrund gelegt wird, oder ob es mit der Hintergrundfarbe aufgefüllt wird.

      1 = Hintergrundfarbe wird gesetzt
      0 = es wird nur das Fontbitmap gesetzt, der Hintergrund wird belassen und somit überdiesen gelegt