#include #include #include #define TFT_CS 10 // PB2 #define TFT_RST 6 // PD6 #define TFT_DC 7 // PD7 Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); // RGB565 Farbpallete der "EGA"-Farben uint16_t egapalette [] = { 0x0000, 0x0015, 0x0540, 0x0555, 0xa800, 0xa815, 0xaaa0, 0xad55, 0x52aa, 0x52bf, 0x57ea, 0x57ff, 0xfaaa, 0xfabf, 0xffea, 0xffff }; /* ---------------------------------------------------------- rgbfromvalue Setzt einen 16-Bitfarbwert aus 3 einzelnen Farbwerten fuer (r)ot, (g)ruen und (b)lau zusammen. r,g,b : 8-Bit Farbwerte fuer rot, gruen, blau. Aus diesen wird ein 16 Bit (RGB565) Farbwert generiert und dieser als Funktionsergebnis zurueck geliefert ---------------------------------------------------------- */ uint16_t rgbfromvalue(uint8_t r, uint8_t g, uint8_t b) { uint16_t value; r= r >> 3; g= g >> 2; b= b >> 3; value= b; value |= (g << 5); value |= (r << 11); return value; } /* ---------------------------------------------------------- rgbfromega liefert den 16-Bit Farbwert, der in der Ega-Farbpalette definiert ist. entry : Indexnummer der Farbe in egapalette ---------------------------------------------------------- */ uint16_t rgbfromega(uint8_t entry) { return egapalette[entry]; } #define putpixel(x, y, color) tft.drawPixel(x, y, color) #define gotoxy(x, y) tft.setCursor(x, y) #define printsxy(x,y,s) { gotoxy(x,y); tft.print(s); } int drw_aktx = 0; int drw_akty = 0; uint16_t drw_color = 0xffff; // Koordinaten, um die die Ausgabe einer Turtlegrafik "verschoben" werden kann int drw_xofs = 0; int drw_yofs = 0; /* ------------------------------------------------------------- drw_putpixel zeichnet einen einzelnen Bildpunkt auf das Display x, y : Koordinate, an der ein Bildpunkt gesetzt wird col : Farbe des Bildpunktes ------------------------------------------------------------- */ void drw_putpixel(int x, int y, uint16_t col) { putpixel(x + drw_xofs, y + drw_yofs, col); } /* ------------------------------------------------------------- drw_line Zeichnet eine Linie von den Koordinaten x0,y0 zu x1,y1 mit der angegebenen Farbe x0,y0 : Koordinate linke obere Ecke x1,y1 : Koordinate rechte untere Ecke color : Farbwert, der gezeichnet wird Linienalgorithmus nach Bresenham (www.wikipedia.org) ------------------------------------------------------------- */ void drw_line(int x0, int y0, int x1, int y1, uint16_t color) { // Linienalgorithmus nach Bresenham (www.wikipedia.org) int dx = abs(x1-x0), sx = x0 dy) { err += dy; x0 += sx; } /* e_xy+e_x > 0 */ if (e2 < dx) { err += dx; y0 += sy; } /* e_xy+e_y < 0 */ } } /* ------------------------------------------------------------- drw_ellipse Zeichnet eine Ellipse mit Mittelpunt an der Koordinate xm,ym mit den Hoehen- Breitenverhaeltnis a:b mit der angegebenen Farbe xm,ym : Koordinate des Mittelpunktes der Ellipse a,b : Hoehen- Breitenverhaeltnis color : Farbwert, der gezeichnet wird Ellipsenalgorithmus nach Bresenham (www.wikipedia.org) ------------------------------------------------------------- */ void drw_ellipse(int xm, int ym, int a, int b, uint16_t color ) { // Algorithmus nach Bresenham (www.wikipedia.org) int dx = 0, dy = b; // im I. Quadranten von links oben nach rechts unten long a2 = a*a, b2 = b*b; long err = b2-(2*b-1)*a2, e2; // Fehler im 1. Schritt */ do { drw_putpixel(xm+dx, ym+dy,color); // I. Quadrant drw_putpixel(xm-dx, ym+dy,color); // II. Quadrant drw_putpixel(xm-dx, ym-dy,color); // III. Quadrant drw_putpixel(xm+dx, ym-dy,color); // IV. Quadrant e2 = 2*err; if (e2 < (2*dx+1)*b2) { dx++; err += (2*dx+1)*b2; } if (e2 > -(2*dy-1)*a2) { dy--; err -= (2*dy-1)*a2; } } while (dy >= 0); while (dx++ < a) // fehlerhafter Abbruch bei flachen Ellipsen (b=1) { drw_putpixel(xm+dx, ym,color); drw_putpixel(xm-dx, ym,color); } } /* ---------------------------------------------------------- drw_fastxline zeichnet eine Linie in X-Achse mit den X Punkten x1 und x2 auf der Y-Achse y1 x1, x2 : Start-, Endpunkt der Linie y1 : Y-Koordinate der Linie color : 16 - Bit RGB565 Farbwert der gezeichnet werden soll ---------------------------------------------------------- */ void drw_fastxline(int x1, int y1, int x2, uint16_t color) { int x; if (x2 < x1) { x = x1; x1 = x2; x2 = x; } for (x= x1; x< (x2+1); x++) { drw_putpixel(x,y1, color); } } /* ------------------------------------------------------------- drw_rectangle Zeichnet ein Rechteck von den Koordinaten x0,y0 zu x1,y1 mit der angegebenen Farbe x0,y0 : Koordinate linke obere Ecke x1,y1 : Koordinate rechte untere Ecke color : Farbwert, der gezeichnet wird ------------------------------------------------------------- */ void drw_rectangle(int x1, int y1, int x2, int y2, uint16_t color) { if (x2 < x1) { int t = x1; x1 = x2; x2 = t; } if (y2 < y1) { int t = y1; y1 = y2; y2 = t; } drw_line(x1,y1,x2,y1, color); drw_line(x2,y1,x2,y2, color); drw_line(x1,y2,x2,y2, color); drw_line(x1,y1,x1,y2, color); } /* ------------------------------------------------------------- drw_fillrectangle Zeichnet ein gefuelltes Rechteck von den Koordinaten x0,y0 zu x1,y1 mit der angegebenen Farbe x0,y0 : Koordinate linke obere Ecke x1,y1 : Koordinate rechte untere Ecke color : Farbwert, der gezeichnet wird ------------------------------------------------------------- */ void drw_fillrectangle(int x1, int y1, int x2, int y2, uint16_t color) { if (x2 < x1) { int t = x1; x1 = x2; x2 = t; } if (y2 < y1) { int t = y1; y1 = y2; y2 = t; } int y; for (y = y1; y <= y2; y++) { drw_fastxline(x1, y, x2, color); } } /* ------------------------------------------------------------- drw_circle Zeichnet einen Kreis mit Mittelpunt an der Koordinate xm,ym und dem Radius r mit der angegebenen Farbe x ,y : Koordinate des Mittelpunktes der Ellipse r : Radius des Kreises color : Farbwert, der gezeichnet wird ------------------------------------------------------------- */ void drw_circle(int x, int y, int r, uint16_t color ) { drw_ellipse(x,y,r,r,color); } /* ------------------------------------------------------------- drw_fillellipse Zeichnet eine ausgefuellte Ellipse mit Mittelpunt an der Koordinate xm,ym mit den Hoehen- Breitenverhaeltnis a:b mit der angegebenen Farbe xm,ym : Koordinate des Mittelpunktes der Ellipse a,b : Hoehen- Breitenverhaeltnis color : Farbwert, der gezeichnet wird Ellipsenalgorithmus nach Bresenham (www.wikipedia.org) ------------------------------------------------------------- */ void drw_fillellipse(int xm, int ym, int a, int b, uint16_t color ) { int dx = 0, dy = b; long a2 = a*a, b2 = b*b; long err = b2-(2*b-1)*a2, e2; do { drw_fastxline(xm+dx, ym+dy,xm-dx, color); drw_fastxline(xm-dx, ym-dy,xm+dx, color); e2 = 2*err; if (e2 < (2*dx+1)*b2) { dx++; err += (2*dx+1)*b2; } if (e2 > -(2*dy-1)*a2) { dy--; err -= (2*dy-1)*a2; } } while (dy >= 0); while (dx++ < a) { drw_putpixel(xm+dx, ym,color); drw_putpixel(xm-dx, ym,color); } } /* ------------------------------------------------------------- drw_fillcircle Zeichnet einen ausgefuellten Kreis mit Mittelpunt an der Koordinate xm,ym und dem Radius r mit der angegebenen Farbe x,y : Koordinate des Mittelpunktes der Ellipse r : Radius des Kreises color : Farbwert, der gezeichnet wird ------------------------------------------------------------- */ void drw_fillcircle(int x, int y, int r, uint16_t color ) { drw_fillellipse(x,y,r,r,color); } /* ------------------------------------------------------------- cmd_getonearg liest einen Parameter als Integer ab der Stringposition 0 und gibt als Funktionsargument einen Zeiger auf den dem Argument folgenden String zurueck. *str : Zeiger auf String (PROGMEM) *value : Zeiger Speicherplatz, der den im String ent- haltenen Wert als Integer aufnimmt Rueckgabe : Zeiger auf den String, der dem Parameter folgt ------------------------------------------------------------- */ const char *cmd_getonearg(const char *str, int *value) { char ch, negativesign; char loop; int v; loop = 1; v = 0; negativesign = 0; while ((ch = pgm_read_byte(str)) && loop) { if (ch == '-') { negativesign = 1; str++; ch = pgm_read_byte(str); } if ((ch >= '0') && (ch <= '9')) { v = v * 10; v += ch - '0'; str++; } else { loop = 0; } } *value = negativesign ? -v : v; return str; } /* ------------------------------------------------------------- cmd_parse Interpretiert einen String als Anweisungen fuer einen Zeichenstift Kommandos innerhalb des Strings: P : bewegt den Zeichenstift auf eine absolue Koordinatenposition ohne etwas zu zeicnen p : zeichnet eine Line zur angegebenen absoluten Koordinatenposition M : bewegt den Zeichenstift auf eine relative Koordinatenposition ohne etwas zu zeicnen m : zeichnet eine Line zur angegebenen relative Koordinatenposition r : zeichnet eine Linie nach rechts mit einer ange- gebenen Anzahl Pixel (right) l : zeichnet eine Linie nach links mit einer ange- gebenen Anzahl Pixel (left) u : zeichnet eine Linie nach oben mit einer ange- gebenen Anzahl Pixel (up) d : zeichnet eine Linie nach unten mit einer ange- gebenen Anzahl Pixel (down) k : zeichnet einen Kreis mit einem angegebenen Radius K : zeichnet einen gefuellten Kreis mit einem angegebenen Radius t : zeichnet ein Recheck von der aktuellen Zeichen- position mit angegebener Pixelbreite und Pixel- hoehe T : zeichnet ein gefuelltes Recheck von der aktuellen Zeichenposition mit angegebener Pixelbreite und Pixelhoehe c : setzt die Zeichenfarbe mit der Farbe in der EGA-Palette (1 Argument) C : setzt die Zeichenfarbe mit Werten fuer rot, gruen, blau ------------------------------------------------------------- */ void cmd_parse(const char *str) { char ch; int arg1, arg2, arg3; while ((ch = pgm_read_byte(str))) { str++; switch (ch) { case 'c' : { str = cmd_getonearg(str, &arg1); drw_color = rgbfromega(arg1); break; } case 'C' : { str = cmd_getonearg(str, &arg1); if (pgm_read_byte(str) == ',') str++; str = cmd_getonearg(str, &arg2); if (pgm_read_byte(str) == ',') str++; str = cmd_getonearg(str, &arg3); drw_color = rgbfromvalue(arg1, arg2, arg3); break; } case 'r' : { str = cmd_getonearg(str, &arg1); drw_line(drw_aktx, drw_akty, drw_aktx + arg1, drw_akty, drw_color); drw_aktx += arg1; break; } case 'l' : { str = cmd_getonearg(str, &arg1); drw_line(drw_aktx, drw_akty, drw_aktx - arg1, drw_akty, drw_color); drw_aktx -= arg1; break; } case 'u' : { str = cmd_getonearg(str, &arg1); drw_line(drw_aktx, drw_akty, drw_aktx, drw_akty - arg1, drw_color); drw_akty -= arg1; break; } case 'd' : { str = cmd_getonearg(str, &arg1); drw_line(drw_aktx, drw_akty, drw_aktx, drw_akty + arg1, drw_color); drw_akty += arg1; break; } case 'k' : { str = cmd_getonearg(str, &arg1); drw_circle(drw_aktx, drw_akty, arg1, drw_color); break; } case 'K' : { str = cmd_getonearg(str, &arg1); drw_fillcircle(drw_aktx, drw_akty, arg1, drw_color); break; } case 't' : { str = cmd_getonearg(str, &arg1); str++; str = cmd_getonearg(str, &arg2); drw_rectangle(drw_aktx, drw_akty, drw_aktx + arg1, drw_akty + arg2, drw_color); break; } case 'T' : { str = cmd_getonearg(str, &arg1); str++; str = cmd_getonearg(str, &arg2); drw_fillrectangle(drw_aktx, drw_akty, drw_aktx + arg1, drw_akty + arg2, drw_color); break; } case 'P' : { str = cmd_getonearg(str, &arg1); str++; str = cmd_getonearg(str, &arg2); drw_aktx = arg1; drw_akty = arg2; break; } case 'p' : { str = cmd_getonearg(str, &arg1); str++; str = cmd_getonearg(str, &arg2); drw_line(drw_aktx, drw_akty, arg1, arg2, drw_color); drw_aktx = arg1; drw_akty = arg2; break; } case 'M' : { str = cmd_getonearg(str, &arg1); str++; str = cmd_getonearg(str, &arg2); drw_aktx += arg1; drw_akty += arg2; break; } case 'm' : { str = cmd_getonearg(str, &arg1); str++; str = cmd_getonearg(str, &arg2); drw_line(drw_aktx, drw_akty, drw_aktx + arg1, drw_akty + arg2, drw_color); drw_aktx += arg1; drw_akty += arg2; break; } default : break; } } } static const char cmd[] PROGMEM = "P0,0 c15 T159,79 M15,67 c2 K7 r12 K7 r13 K7 r13 K7 M-45,-1 c15 T55,8 c6 M52,-1 T53,-1 c8 M4,-2" "T47,-27 C27,66,10M6,0 T11,-13 C205,207,56 u13 r11 M-6,7 c6 l3 d1 c15 M15,-11 T10,6 M14,0 T8,6" "C27,66,10 M-15,7T12,1 M14,0 T10,1 c1 M-13,-1 u6 r10 l4 d6M8,0 c1 u6 r8 l3 d6 M-42,-18 c4 m10,-10" "r27 m10,10 M-37,-9 T27,9 M-1,1 T29,8 M-1,1 T31,7 M-1,1 t33,6 M-1,1 T35,5 M-1,1 T37,4 M-1,1" "T39,3 M-1,1 T41,2 M-1,1 T43,1 M-1,1 r45 c3 M-34,7 K5 c1 k5 C114,81,21 M-43,21 T1,-23 C25,96,27" "M1,-29 K16 c2 M-9,5 K3 M17,-1 K3 M-5,4 K3 M4,0 K3 M-18,-9 K2 c14 M1,5 K2 M13,2 K2 M8,-4 K2" "c4 M-5,7 K1 M-16,-3 K2 M55,-12 C65,6,6 T4,-8 M32,-17 c14 C198,70,0 K10 c14 M-2,1 K7 C153,193,241" "M-58,-3 M-1,-2 K5 M5,0 K4 r8 K4 l25 K6 r5 K4"; void setup() { uint16_t color; tft.initR(INITR_BLACKTAB); // wichtig! tft.fillScreen(ST77XX_BLACK); tft.setRotation(1); tft.setTextSize(1); color= rgbfromvalue(255, 255, 0); tft.setTextColor(color); printsxy(10,119, "www.mikrocontroller.net"); cmd_parse(&cmd[0]); } void loop() { }