Library for 1.8 inch 160*180 TFT Display. Nice fonts in different formats.
Embed:
(wiki syntax)
Show/hide line numbers
ST7735.cpp
00001 #include "mbed.h" 00002 #include "ST7735.h" 00003 00004 #ifdef LOAD_FONT2 00005 #include "Font16.h" 00006 #endif 00007 00008 #ifdef LOAD_FONT4 00009 #include "Font32.h" 00010 #endif 00011 00012 #ifdef LOAD_FONT6 00013 #include "Font64.h" 00014 #endif 00015 00016 #ifdef LOAD_FONT7 00017 #include "Font7s.h" 00018 #endif 00019 00020 #ifdef LOAD_FONT8 00021 #include "Font72.h" 00022 #endif 00023 00024 00025 ST7735::ST7735(PinName cePin, PinName dcPin, PinName mosiPin, PinName sclkPin) 00026 { 00027 spi = new SPI(mosiPin, NC, sclkPin); // create new SPI instance and initialise 00028 initSPI(); 00029 00030 // set up other pins as required 00031 ce = new DigitalOut(cePin,1); 00032 dc = new DigitalOut(dcPin,0); 00033 00034 // Defaults after power-up 00035 textsize = 1; 00036 textcolor = ST7735_GREEN; 00037 textbgcolor = ST7735_BLACK; 00038 } 00039 00040 // function to initialise SPI peripheral 00041 void ST7735::initSPI() 00042 { 00043 spi->format(8,0); // 8 bits, Mode 0 00044 spi->frequency(20000000); // SPI clock frequency 00045 } 00046 00047 // Write data word 00048 void ST7735::writecommand(char c) 00049 { 00050 dc->write(0); 00051 ce->write(0); 00052 spi->write(c); 00053 ce->write(1); 00054 } 00055 00056 // Write command word 00057 void ST7735::writedata(char c) 00058 { 00059 dc->write(1); 00060 ce->write(0); 00061 spi->write(c); 00062 ce->write(1); 00063 } 00064 00065 00066 // Rather than a bazillion writecommand() and writedata() calls, screen 00067 // initialization commands and arguments are organized in tables 00068 // The table may look bulky, but that's mostly the 00069 // formatting -- storage-wise this is hundreds of bytes more compact 00070 // than the equivalent code. Companion function follows. 00071 #define DELAY 0x80 00072 static const uint8_t Bcmd[] = { // Initialization commands for 7735B screens 00073 18, // 18 commands in list: 00074 ST7735_SWRESET, DELAY, // 1: Software reset, no args, w/delay 00075 50, // 50 ms delay 00076 ST7735_SLPOUT , DELAY, // 2: Out of sleep mode, no args, w/delay 00077 255, // 255 = 500 ms delay 00078 ST7735_COLMOD , 1+DELAY, // 3: Set color mode, 1 arg + delay: 00079 0x05, // 16-bit color 00080 10, // 10 ms delay 00081 ST7735_FRMCTR1, 3+DELAY, // 4: Frame rate control, 3 args + delay: 00082 0x00, // fastest refresh 00083 0x06, // 6 lines front porch 00084 0x03, // 3 lines back porch 00085 10, // 10 ms delay 00086 ST7735_MADCTL , 1 , // 5: Memory access ctrl (directions), 1 arg: 00087 0x08, // Row addr/col addr, bottom to top refresh 00088 ST7735_DISSET5, 2 , // 6: Display settings #5, 2 args, no delay: 00089 0x15, // 1 clk cycle nonoverlap, 2 cycle gate 00090 // rise, 3 cycle osc equalize 00091 0x02, // Fix on VTL 00092 ST7735_INVCTR , 1 , // 7: Display inversion control, 1 arg: 00093 0x0, // Line inversion 00094 ST7735_PWCTR1 , 2+DELAY, // 8: Power control, 2 args + delay: 00095 0x02, // GVDD = 4.7V 00096 0x70, // 1.0uA 00097 10, // 10 ms delay 00098 ST7735_PWCTR2 , 1 , // 9: Power control, 1 arg, no delay: 00099 0x05, // VGH = 14.7V, VGL = -7.35V 00100 ST7735_PWCTR3 , 2 , // 10: Power control, 2 args, no delay: 00101 0x01, // Opamp current small 00102 0x02, // Boost frequency 00103 ST7735_VMCTR1 , 2+DELAY, // 11: Power control, 2 args + delay: 00104 0x3C, // VCOMH = 4V 00105 0x38, // VCOML = -1.1V 00106 10, // 10 ms delay 00107 ST7735_PWCTR6 , 2 , // 12: Power control, 2 args, no delay: 00108 0x11, 0x15, 00109 ST7735_GMCTRP1,16 , // 13: Magical unicorn dust, 16 args, no delay: 00110 0x09, 0x16, 0x09, 0x20, // (seriously though, not sure what 00111 0x21, 0x1B, 0x13, 0x19, // these config values represent) 00112 0x17, 0x15, 0x1E, 0x2B, 00113 0x04, 0x05, 0x02, 0x0E, 00114 ST7735_GMCTRN1,16+DELAY, // 14: Sparkles and rainbows, 16 args + delay: 00115 0x0B, 0x14, 0x08, 0x1E, // (ditto) 00116 0x22, 0x1D, 0x18, 0x1E, 00117 0x1B, 0x1A, 0x24, 0x2B, 00118 0x06, 0x06, 0x02, 0x0F, 00119 10, // 10 ms delay 00120 ST7735_CASET , 4 , // 15: Column addr set, 4 args, no delay: 00121 0x00, 0x02, // XSTART = 2 00122 0x00, 0x81, // XEND = 129 00123 ST7735_RASET , 4 , // 16: Row addr set, 4 args, no delay: 00124 0x00, 0x02, // XSTART = 1 00125 0x00, 0x81, // XEND = 160 00126 ST7735_NORON , DELAY, // 17: Normal display on, no args, w/delay 00127 10, // 10 ms delay 00128 ST7735_DISPON , DELAY, // 18: Main screen turn on, no args, w/delay 00129 255 }, // 255 = 500 ms delay 00130 00131 Rcmd1[] = { // Init for 7735R, part 1 (red or green tab) 00132 15, // 15 commands in list: 00133 ST7735_SWRESET, DELAY, // 1: Software reset, 0 args, w/delay 00134 150, // 150 ms delay 00135 ST7735_SLPOUT , DELAY, // 2: Out of sleep mode, 0 args, w/delay 00136 255, // 500 ms delay 00137 ST7735_FRMCTR1, 3 , // 3: Frame rate ctrl - normal mode, 3 args: 00138 0x01, 0x2C, 0x2D, // Rate = fosc/(1x2+40) * (LINE+2C+2D) 00139 ST7735_FRMCTR2, 3 , // 4: Frame rate control - idle mode, 3 args: 00140 0x01, 0x2C, 0x2D, // Rate = fosc/(1x2+40) * (LINE+2C+2D) 00141 ST7735_FRMCTR3, 6 , // 5: Frame rate ctrl - partial mode, 6 args: 00142 0x01, 0x2C, 0x2D, // Dot inversion mode 00143 0x01, 0x2C, 0x2D, // Line inversion mode 00144 ST7735_INVCTR , 1 , // 6: Display inversion ctrl, 1 arg, no delay: 00145 0x07, // No inversion 00146 ST7735_PWCTR1 , 3 , // 7: Power control, 3 args, no delay: 00147 0xA2, 00148 0x02, // -4.6V 00149 0x84, // AUTO mode 00150 ST7735_PWCTR2 , 1 , // 8: Power control, 1 arg, no delay: 00151 0xC5, // VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD 00152 ST7735_PWCTR3 , 2 , // 9: Power control, 2 args, no delay: 00153 0x0A, // Opamp current small 00154 0x00, // Boost frequency 00155 ST7735_PWCTR4 , 2 , // 10: Power control, 2 args, no delay: 00156 0x8A, // BCLK/2, Opamp current small & Medium low 00157 0x2A, 00158 ST7735_PWCTR5 , 2 , // 11: Power control, 2 args, no delay: 00159 0x8A, 0xEE, 00160 ST7735_VMCTR1 , 1 , // 12: Power control, 1 arg, no delay: 00161 0x0E, 00162 ST7735_INVOFF , 0 , // 13: Don't invert display, no args, no delay 00163 ST7735_MADCTL , 1 , // 14: Memory access control (directions), 1 arg: 00164 0xC8, // row addr/col addr, bottom to top refresh 00165 ST7735_COLMOD , 1 , // 15: set color mode, 1 arg, no delay: 00166 0x05 }, // 16-bit color 00167 00168 Rcmd2green[] = { // Init for 7735R, part 2 (green tab only) 00169 2, // 2 commands in list: 00170 ST7735_CASET , 4 , // 1: Column addr set, 4 args, no delay: 00171 0x00, 0x02, // XSTART = 0 00172 0x00, 0x7F+0x02, // XEND = 127 00173 ST7735_RASET , 4 , // 2: Row addr set, 4 args, no delay: 00174 0x00, 0x01, // XSTART = 0 00175 0x00, 0x9F+0x01 }, // XEND = 159 00176 Rcmd2red[] = { // Init for 7735R, part 2 (red tab only) 00177 2, // 2 commands in list: 00178 ST7735_CASET , 4 , // 1: Column addr set, 4 args, no delay: 00179 0x00, 0x00, // XSTART = 0 00180 0x00, 0x7F, // XEND = 127 00181 ST7735_RASET , 4 , // 2: Row addr set, 4 args, no delay: 00182 0x00, 0x00, // XSTART = 0 00183 0x00, 0x9F }, // XEND = 159 00184 00185 Rcmd3[] = { // Init for 7735R, part 3 (red or green tab) 00186 4, // 4 commands in list: 00187 ST7735_GMCTRP1, 16 , // 1: Magical unicorn dust, 16 args, no delay: 00188 0x02, 0x1c, 0x07, 0x12, 00189 0x37, 0x32, 0x29, 0x2d, 00190 0x29, 0x25, 0x2B, 0x39, 00191 0x00, 0x01, 0x03, 0x10, 00192 ST7735_GMCTRN1, 16 , // 2: Sparkles and rainbows, 16 args, no delay: 00193 0x03, 0x1d, 0x07, 0x06, 00194 0x2E, 0x2C, 0x29, 0x2D, 00195 0x2E, 0x2E, 0x37, 0x3F, 00196 0x00, 0x00, 0x02, 0x10, 00197 ST7735_NORON , DELAY, // 3: Normal display on, no args, w/delay 00198 10, // 10 ms delay 00199 ST7735_DISPON , DELAY, // 4: Main screen turn on, no args w/delay 00200 100 }; // 100 ms delay 00201 00202 00203 00204 // Companion code to the above tables. Reads and issues 00205 // a series of LCD commands stored in PROGMEM byte array. 00206 void ST7735::commandList(const uint8_t *addr){ 00207 uint8_t numCommands, numArgs; 00208 uint16_t ms; 00209 00210 numCommands = pgm_read_byte(addr++); // Number of commands to follow 00211 while(numCommands--) { // For each command... 00212 writecommand(pgm_read_byte(addr++)); // Read, issue command 00213 numArgs = pgm_read_byte(addr++); // Number of args to follow 00214 ms = numArgs & DELAY; // If hibit set, delay follows args 00215 numArgs &= ~DELAY; // Mask out delay bit 00216 while(numArgs--) { // For each argument... 00217 writedata(pgm_read_byte(addr++)); // Read, issue argument 00218 } 00219 00220 if(ms) { 00221 ms = pgm_read_byte(addr++); // Read post-command delay time (ms) 00222 if(ms == 255) ms = 500; // If 255, delay for 500 ms 00223 wait_ms(ms); 00224 } 00225 } 00226 } 00227 00228 // Initialization code common to both 'B' and 'R' type displays 00229 void ST7735::commonInit(const uint8_t *cmdList){ 00230 wait_ms(100); // Wait for reset to be stable after power-up 00231 colstart = rowstart = 0; // May be overridden in init func 00232 if(cmdList) commandList(cmdList); 00233 } 00234 00235 // Initialization for ST7735B screens 00236 void ST7735::initB() { 00237 commonInit(Bcmd); 00238 } 00239 00240 // Initialization for ST7735R screens (green or red tabs) 00241 void ST7735::initR(uint8_t options) { 00242 commonInit(Rcmd1); 00243 if(options == INITR_GREENTAB) { 00244 commandList(Rcmd2green); 00245 colstart = 2; 00246 rowstart = 1; 00247 } else { 00248 // colstart, rowstart left at default '0' values 00249 commandList(Rcmd2red); 00250 } 00251 commandList(Rcmd3); 00252 00253 // if black, change MADCTL color filter 00254 if (options == INITR_BLACKTAB) { 00255 writecommand(ST7735_MADCTL); 00256 writedata(0xC0); 00257 } 00258 00259 tabcolor = options; 00260 } 00261 00262 void ST7735::setRotation(uint8_t m) { 00263 00264 writecommand(ST7735_MADCTL); 00265 rotation = m % 4; // can't be higher than 3 00266 switch (rotation) { 00267 case 0: 00268 if (tabcolor == INITR_BLACKTAB) { 00269 writedata(MADCTL_MX | MADCTL_MY | MADCTL_RGB); 00270 } else { 00271 writedata(MADCTL_MX | MADCTL_MY | MADCTL_BGR); 00272 } 00273 _width = ST7735_TFTWIDTH; 00274 _height = ST7735_TFTHEIGHT; 00275 break; 00276 case 1: 00277 if (tabcolor == INITR_BLACKTAB) { 00278 writedata(MADCTL_MY | MADCTL_MV | MADCTL_RGB); 00279 } else { 00280 writedata(MADCTL_MY | MADCTL_MV | MADCTL_BGR); 00281 } 00282 _width = ST7735_TFTHEIGHT; 00283 _height = ST7735_TFTWIDTH; 00284 break; 00285 case 2: 00286 if (tabcolor == INITR_BLACKTAB) { 00287 writedata(MADCTL_RGB); 00288 } else { 00289 writedata(MADCTL_BGR); 00290 } 00291 _width = ST7735_TFTWIDTH; 00292 _height = ST7735_TFTHEIGHT; 00293 break; 00294 case 3: 00295 if (tabcolor == INITR_BLACKTAB) { 00296 writedata(MADCTL_MX | MADCTL_MV | MADCTL_RGB); 00297 } else { 00298 writedata(MADCTL_MX | MADCTL_MV | MADCTL_BGR); 00299 } 00300 _width = ST7735_TFTHEIGHT; 00301 _height = ST7735_TFTWIDTH; 00302 break; 00303 } 00304 } 00305 00306 void ST7735::fillScreen(uint16_t color) { 00307 fillRect(0, 0, _width, _height, color); 00308 } 00309 00310 00311 00312 void ST7735::pushColor(uint16_t color) { 00313 dc->write(1); 00314 ce->write(0); 00315 spi->write(color >> 8); 00316 spi->write(color); 00317 ce->write(1); 00318 } 00319 00320 // fill a rectangle 00321 void ST7735::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { 00322 00323 // rudimentary clipping (drawChar w/big text requires this) 00324 if((x >= _width) || (y >= _height)) return; 00325 if((x + w - 1) >= _width) w = _width - x; 00326 if((y + h - 1) >= _height) h = _height - y; 00327 00328 setAddrWindow(x, y, x+w-1, y+h-1); 00329 00330 uint8_t hi = color >> 8, lo = color; 00331 00332 dc->write(1); 00333 ce->write(0); 00334 00335 for(y=h; y>0; y--) { 00336 for(x=w; x>0; x--) { 00337 spi->write(hi); 00338 spi->write(lo); 00339 } 00340 } 00341 ce->write(1); 00342 } 00343 00344 00345 00346 void ST7735::invertDisplay(bool i) { 00347 writecommand(i ? ST7735_INVON : ST7735_INVOFF); 00348 } 00349 00350 void ST7735::drawPixel(int16_t x, int16_t y, uint16_t color) { 00351 00352 if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; 00353 00354 setAddrWindow(x,y,x+1,y+1); 00355 dc->write(1); 00356 ce->write(0); 00357 spi->write(color >> 8); 00358 spi->write(color); 00359 ce->write(1); 00360 } 00361 00362 void ST7735::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { 00363 00364 // Rudimentary clipping 00365 if((x >= _width) || (y >= _height)) return; 00366 if((y+h-1) >= _height) h = _height-y; 00367 setAddrWindow(x, y, x, y+h-1); 00368 00369 uint8_t hi = color >> 8, lo = color; 00370 00371 dc->write(1); 00372 ce->write(0); 00373 while (h--) { 00374 spi->write(hi); 00375 spi->write(lo); 00376 } 00377 ce->write(1); 00378 } 00379 00380 void ST7735::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { 00381 00382 // Rudimentary clipping 00383 if((x >= _width) || (y >= _height)) return; 00384 if((x+w-1) >= _width) w = _width-x; 00385 setAddrWindow(x, y, x+w-1, y); 00386 uint8_t hi = color >> 8, lo = color; 00387 00388 dc->write(1);; 00389 ce->write(0);; 00390 00391 while (w--) { 00392 spi->write(hi); 00393 spi->write(lo); 00394 } 00395 00396 ce->write(1); 00397 } 00398 00399 // Pass 8-bit (each) R,G,B, get back 16-bit packed color 00400 uint16_t ST7735::Color565(uint8_t r, uint8_t g, uint8_t b) { 00401 return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); 00402 } 00403 00404 // Bresenham's algorithm - thx wikpedia 00405 void ST7735::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) { 00406 int16_t steep = abs(y1 - y0) > abs(x1 - x0); 00407 if (steep) { 00408 swap(x0, y0); 00409 swap(x1, y1); 00410 } 00411 00412 if (x0 > x1) { 00413 swap(x0, x1); 00414 swap(y0, y1); 00415 } 00416 00417 int16_t dx, dy; 00418 dx = x1 - x0; 00419 dy = abs(y1 - y0); 00420 00421 int16_t err = dx / 2; 00422 int16_t ystep; 00423 00424 if (y0 < y1) { 00425 ystep = 1; 00426 } else { 00427 ystep = -1; 00428 } 00429 00430 for (; x0<=x1; x0++) { 00431 if (steep) { 00432 drawPixel(y0, x0, color); 00433 } else { 00434 drawPixel(x0, y0, color); 00435 } 00436 err -= dy; 00437 if (err < 0) { 00438 y0 += ystep; 00439 err += dx; 00440 } 00441 } 00442 } 00443 00444 // Draw a rectangle 00445 void ST7735::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { 00446 drawFastHLine(x, y, w, color); 00447 drawFastHLine(x, y+h-1, w, color); 00448 drawFastVLine(x, y, h, color); 00449 drawFastVLine(x+w-1, y, h, color); 00450 } 00451 00452 // Draw a circle outline 00453 void ST7735::drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color) { 00454 int16_t f = 1 - r; 00455 int16_t ddF_x = 1; 00456 int16_t ddF_y = -2 * r; 00457 int16_t x = 0; 00458 int16_t y = r; 00459 00460 drawPixel(x0 , y0+r, color); 00461 drawPixel(x0 , y0-r, color); 00462 drawPixel(x0+r, y0 , color); 00463 drawPixel(x0-r, y0 , color); 00464 00465 while (x<y) { 00466 if (f >= 0) { 00467 y--; 00468 ddF_y += 2; 00469 f += ddF_y; 00470 } 00471 x++; 00472 ddF_x += 2; 00473 f += ddF_x; 00474 00475 drawPixel(x0 + x, y0 + y, color); 00476 drawPixel(x0 - x, y0 + y, color); 00477 drawPixel(x0 + x, y0 - y, color); 00478 drawPixel(x0 - x, y0 - y, color); 00479 drawPixel(x0 + y, y0 + x, color); 00480 drawPixel(x0 - y, y0 + x, color); 00481 drawPixel(x0 + y, y0 - x, color); 00482 drawPixel(x0 - y, y0 - x, color); 00483 } 00484 } 00485 00486 void ST7735::drawCircleHelper( int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color) { 00487 int16_t f = 1 - r; 00488 int16_t ddF_x = 1; 00489 int16_t ddF_y = -2 * r; 00490 int16_t x = 0; 00491 int16_t y = r; 00492 00493 while (x<y) { 00494 if (f >= 0) { 00495 y--; 00496 ddF_y += 2; 00497 f += ddF_y; 00498 } 00499 x++; 00500 ddF_x += 2; 00501 f += ddF_x; 00502 if (cornername & 0x4) { 00503 drawPixel(x0 + x, y0 + y, color); 00504 drawPixel(x0 + y, y0 + x, color); 00505 } 00506 if (cornername & 0x2) { 00507 drawPixel(x0 + x, y0 - y, color); 00508 drawPixel(x0 + y, y0 - x, color); 00509 } 00510 if (cornername & 0x8) { 00511 drawPixel(x0 - y, y0 + x, color); 00512 drawPixel(x0 - x, y0 + y, color); 00513 } 00514 if (cornername & 0x1) { 00515 drawPixel(x0 - y, y0 - x, color); 00516 drawPixel(x0 - x, y0 - y, color); 00517 } 00518 } 00519 } 00520 00521 void ST7735::fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color) { 00522 drawFastVLine(x0, y0-r, 2*r+1, color); 00523 fillCircleHelper(x0, y0, r, 3, 0, color); 00524 } 00525 00526 // Used to do circles and roundrects 00527 void ST7735::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t color) { 00528 00529 int16_t f = 1 - r; 00530 int16_t ddF_x = 1; 00531 int16_t ddF_y = -2 * r; 00532 int16_t x = 0; 00533 int16_t y = r; 00534 00535 while (x<y) { 00536 if (f >= 0) { 00537 y--; 00538 ddF_y += 2; 00539 f += ddF_y; 00540 } 00541 x++; 00542 ddF_x += 2; 00543 f += ddF_x; 00544 00545 if (cornername & 0x1) { 00546 drawFastVLine(x0+x, y0-y, 2*y+1+delta, color); 00547 drawFastVLine(x0+y, y0-x, 2*x+1+delta, color); 00548 } 00549 if (cornername & 0x2) { 00550 drawFastVLine(x0-x, y0-y, 2*y+1+delta, color); 00551 drawFastVLine(x0-y, y0-x, 2*x+1+delta, color); 00552 } 00553 } 00554 } 00555 00556 00557 // Draw a triangle 00558 void ST7735::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) { 00559 drawLine(x0, y0, x1, y1, color); 00560 drawLine(x1, y1, x2, y2, color); 00561 drawLine(x2, y2, x0, y0, color); 00562 } 00563 00564 // Fill a triangle 00565 void ST7735::fillTriangle ( int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) { 00566 00567 int16_t a, b, y, last; 00568 00569 // Sort coordinates by Y order (y2 >= y1 >= y0) 00570 if (y0 > y1) { 00571 swap(y0, y1); swap(x0, x1); 00572 } 00573 if (y1 > y2) { 00574 swap(y2, y1); swap(x2, x1); 00575 } 00576 if (y0 > y1) { 00577 swap(y0, y1); swap(x0, x1); 00578 } 00579 00580 if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing 00581 a = b = x0; 00582 if(x1 < a) a = x1; 00583 else if(x1 > b) b = x1; 00584 if(x2 < a) a = x2; 00585 else if(x2 > b) b = x2; 00586 drawFastHLine(a, y0, b-a+1, color); 00587 return; 00588 } 00589 00590 int16_t 00591 dx01 = x1 - x0, 00592 dy01 = y1 - y0, 00593 dx02 = x2 - x0, 00594 dy02 = y2 - y0, 00595 dx12 = x2 - x1, 00596 dy12 = y2 - y1, 00597 sa = 0, 00598 sb = 0; 00599 00600 // For upper part of triangle, find scanline crossings for segments 00601 // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 00602 // is included here (and second loop will be skipped, avoiding a /0 00603 // error there), otherwise scanline y1 is skipped here and handled 00604 // in the second loop...which also avoids a /0 error here if y0=y1 00605 // (flat-topped triangle). 00606 if(y1 == y2) last = y1; // Include y1 scanline 00607 else last = y1-1; // Skip it 00608 00609 for(y=y0; y<=last; y++) { 00610 a = x0 + sa / dy01; 00611 b = x0 + sb / dy02; 00612 sa += dx01; 00613 sb += dx02; 00614 /* longhand: 00615 a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); 00616 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 00617 */ 00618 if(a > b) swap(a,b); 00619 drawFastHLine(a, y, b-a+1, color); 00620 } 00621 00622 // For lower part of triangle, find scanline crossings for segments 00623 // 0-2 and 1-2. This loop is skipped if y1=y2. 00624 sa = dx12 * (y - y1); 00625 sb = dx02 * (y - y0); 00626 for(; y<=y2; y++) { 00627 a = x1 + sa / dy12; 00628 b = x0 + sb / dy02; 00629 sa += dx12; 00630 sb += dx02; 00631 /* longhand: 00632 a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); 00633 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 00634 */ 00635 if(a > b) swap(a,b); 00636 drawFastHLine(a, y, b-a+1, color); 00637 } 00638 } 00639 00640 // Draw a rounded rectangle 00641 void ST7735::drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color) { 00642 // smarter version 00643 drawFastHLine(x+r , y , w-2*r, color); // Top 00644 drawFastHLine(x+r , y+h-1, w-2*r, color); // Bottom 00645 drawFastVLine(x , y+r , h-2*r, color); // Left 00646 drawFastVLine(x+w-1, y+r , h-2*r, color); // Right 00647 // draw four corners 00648 drawCircleHelper(x+r , y+r , r, 1, color); 00649 drawCircleHelper(x+w-r-1, y+r , r, 2, color); 00650 drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color); 00651 drawCircleHelper(x+r , y+h-r-1, r, 8, color); 00652 } 00653 00654 // Fill a rounded rectangle 00655 void ST7735::fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color) { 00656 // smarter version 00657 fillRect(x+r, y, w-2*r, h, color); 00658 00659 // draw four corners 00660 fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color); 00661 fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color); 00662 } 00663 00664 void ST7735::setCursor(int16_t x, int16_t y) { 00665 cursor_x = x; 00666 cursor_y = y; 00667 } 00668 00669 void ST7735::setTextSize(uint8_t s) { 00670 textsize = (s > 0) ? s : 1; 00671 } 00672 00673 00674 void ST7735::setTextColor(uint16_t c) { 00675 // For 'transparent' background, we'll set the bg 00676 // to the same as fg instead of using a flag 00677 textcolor = textbgcolor = c; 00678 } 00679 00680 void ST7735::setTextColor(uint16_t c, uint16_t b) { 00681 textcolor = c; 00682 textbgcolor = b; 00683 } 00684 00685 void ST7735::setTextWrap(bool w) { 00686 wrap = w; 00687 } 00688 00689 uint8_t ST7735::getRotation(void) { 00690 return rotation; 00691 } 00692 00693 void ST7735::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) { 00694 00695 int16_t i, j, byteWidth = (w + 7) / 8; 00696 00697 for(j=0; j<h; j++) { 00698 for(i=0; i<w; i++ ) { 00699 if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) { 00700 drawPixel(x+i, y+j, color); 00701 } 00702 } 00703 } 00704 } 00705 00706 00707 /*************************************************************************************** 00708 ** Function name: drawUnicode 00709 ** Descriptions: draw a unicode 00710 ***************************************************************************************/ 00711 int ST7735::drawUnicode(unsigned int uniCode, int x, int y, int font) 00712 { 00713 00714 if (font) uniCode -= 32; 00715 00716 unsigned int width = 0; 00717 unsigned int height = 0; 00718 unsigned int flash_address = 0; 00719 int8_t gap = 0; 00720 00721 // if (size == 1) { 00722 // flash_address = pgm_read_word(&chrtbl_f8[uniCode]); 00723 // width = pgm_read_byte(widtbl_f8+uniCode); 00724 // height = chr_hgt_f8; 00725 // gap = 1; 00726 // } 00727 #ifdef LOAD_FONT2 00728 if (font == 2) { 00729 flash_address = pgm_read_word(&chrtbl_f16[uniCode]); 00730 width = pgm_read_byte(widtbl_f16+uniCode); 00731 height = chr_hgt_f16; 00732 gap = 1; 00733 } 00734 #endif 00735 // if (font == 3) { 00736 // flash_address = pgm_read_word(&chrtbl_f24[uniCode]); 00737 // width = pgm_read_byte(widtbl_f24+uniCode); 00738 // height = chr_hgt_f24; 00739 // gap = 0; 00740 // } 00741 #ifdef LOAD_FONT4 00742 if (font == 4) { 00743 flash_address = pgm_read_word(&chrtbl_f32[uniCode]); 00744 width = pgm_read_byte(widtbl_f32+uniCode); 00745 height = chr_hgt_f32; 00746 gap = -3; 00747 } 00748 #endif 00749 // if (font == 5) { 00750 // flash_address = pgm_read_word(&chrtbl_f48[uniCode]); 00751 // width = pgm_read_byte(widtbl_f48+uniCode); 00752 // height = chr_hgt_f48; 00753 // gap = -3; 00754 // } 00755 #ifdef LOAD_FONT6 00756 if (font == 6) { 00757 flash_address = pgm_read_word(&chrtbl_f64[uniCode]); 00758 width = pgm_read_byte(widtbl_f64+uniCode); 00759 height = chr_hgt_f64; 00760 gap = -3; 00761 } 00762 #endif 00763 #ifdef LOAD_FONT7 00764 if (font == 7) { 00765 flash_address = pgm_read_word(&chrtbl_f7s[uniCode]); 00766 width = pgm_read_byte(widtbl_f7s+uniCode); 00767 height = chr_hgt_f7s; 00768 gap = 2; 00769 } 00770 #endif 00771 #ifdef LOAD_FONT8 00772 if (font == 8) { 00773 flash_address = pgm_read_word(&chrtbl_f72[uniCode]); 00774 width = pgm_read_byte(widtbl_f72+uniCode); 00775 height = chr_hgt_f72; 00776 gap = 2; 00777 } 00778 #endif 00779 00780 00781 int w = (width+7)/8; 00782 int pX = 0; 00783 int pY = y; 00784 //int color = 0; 00785 char line = 0; 00786 00787 //fillRect(x,pY,width+gap,height,textbgcolor); 00788 00789 for(int i=0; i<height; i++) 00790 { 00791 if (textcolor != textbgcolor) { 00792 if (textsize == 1) drawFastHLine(x, pY, width+gap, textbgcolor); 00793 else fillRect(x, pY, (width+gap)*textsize, textsize, textbgcolor); 00794 } 00795 for (int k = 0;k < w; k++) 00796 { 00797 line = pgm_read_byte(flash_address+w*i+k); 00798 if(line) { 00799 if (textsize==1){ 00800 pX = x + k*8; 00801 if(line & 0x80) drawPixel(pX, pY, textcolor); 00802 if(line & 0x40) drawPixel(pX+1, pY, textcolor); 00803 if(line & 0x20) drawPixel(pX+2, pY, textcolor); 00804 if(line & 0x10) drawPixel(pX+3, pY, textcolor); 00805 if(line & 0x8) drawPixel(pX+4, pY, textcolor); 00806 if(line & 0x4) drawPixel(pX+5, pY, textcolor); 00807 if(line & 0x2) drawPixel(pX+6, pY, textcolor); 00808 if(line & 0x1) drawPixel(pX+7, pY, textcolor); 00809 } 00810 else { 00811 pX = x + k*8*textsize; 00812 if(line & 0x80) fillRect(pX, pY, textsize, textsize, textcolor); 00813 if(line & 0x40) fillRect(pX+textsize, pY, textsize, textsize, textcolor); 00814 if(line & 0x20) fillRect(pX+2*textsize, pY, textsize, textsize, textcolor); 00815 if(line & 0x10) fillRect(pX+3*textsize, pY, textsize, textsize, textcolor); 00816 if(line & 0x8) fillRect(pX+4*textsize, pY, textsize, textsize, textcolor); 00817 if(line & 0x4) fillRect(pX+5*textsize, pY, textsize, textsize, textcolor); 00818 if(line & 0x2) fillRect(pX+6*textsize, pY, textsize, textsize, textcolor); 00819 if(line & 0x1) fillRect(pX+7*textsize, pY, textsize, textsize, textcolor); 00820 } 00821 } 00822 } 00823 pY+=textsize; 00824 } 00825 return (width+gap)*textsize; // x + 00826 } 00827 00828 /*************************************************************************************** 00829 ** Function name: drawNumber unsigned with size 00830 ** Descriptions: drawNumber 00831 ***************************************************************************************/ 00832 int ST7735::drawNumber(long long_num,int poX, int poY, int font) 00833 { 00834 char tmp[10]; 00835 if (long_num < 0) sprintf(tmp, "%li", long_num); 00836 else sprintf(tmp, "%lu", long_num); 00837 return drawString(tmp, poX, poY, font); 00838 } 00839 00840 /*************************************************************************************** 00841 ** Function name: drawChar 00842 ** Descriptions: draw char 00843 ***************************************************************************************/ 00844 int ST7735::drawChar(char c, int x, int y, int font) 00845 { 00846 return drawUnicode(c, x, y, font); 00847 } 00848 00849 /*************************************************************************************** 00850 ** Function name: drawString 00851 ** Descriptions: draw string 00852 ***************************************************************************************/ 00853 int ST7735::drawString(char *string, int poX, int poY, int font) 00854 { 00855 int sumX = 0; 00856 00857 while(*string) 00858 { 00859 int xPlus = drawChar(*string, poX, poY, font); 00860 sumX += xPlus; 00861 *string++; 00862 poX += xPlus; /* Move cursor right */ 00863 } 00864 return sumX; 00865 } 00866 00867 /*************************************************************************************** 00868 ** Function name: drawCentreString 00869 ** Descriptions: draw string across centre 00870 ***************************************************************************************/ 00871 int ST7735::drawCentreString(char *string, int dX, int poY, int font) 00872 { 00873 int sumX = 0; 00874 int len = 0; 00875 char *pointer = string; 00876 char ascii; 00877 00878 while(*pointer) 00879 { 00880 ascii = *pointer; 00881 //if (font==0)len += 1+pgm_read_byte(widtbl_log+ascii); 00882 //if (font==1)len += 1+pgm_read_byte(widtbl_f8+ascii-32); 00883 #ifdef LOAD_FONT2 00884 if (font==2)len += 1+pgm_read_byte(widtbl_f16+ascii-32); 00885 #endif 00886 //if (font==3)len += 1+pgm_read_byte(widtbl_f48+ascii-32)/2; 00887 #ifdef LOAD_FONT4 00888 if (font==4)len += pgm_read_byte(widtbl_f32+ascii-32)-3; 00889 #endif 00890 //if (font==5) len += pgm_read_byte(widtbl_f48+ascii-32)-3; 00891 #ifdef LOAD_FONT6 00892 if (font==6) len += pgm_read_byte(widtbl_f64+ascii-32)-3; 00893 #endif 00894 #ifdef LOAD_FONT7 00895 if (font==7) len += pgm_read_byte(widtbl_f7s+ascii-32)+2; 00896 #endif 00897 #ifdef LOAD_FONT8 00898 if (font==8) len += pgm_read_byte(widtbl_f72+ascii-32)+2; 00899 #endif 00900 *pointer++; 00901 } 00902 len = len*textsize; 00903 int poX = dX - len/2; 00904 00905 if (poX < 0) poX = 0; 00906 00907 while(*string) 00908 { 00909 00910 int xPlus = drawChar(*string, poX, poY, font); 00911 sumX += xPlus; 00912 *string++; 00913 poX += xPlus; /* Move cursor right */ 00914 } 00915 00916 return sumX; 00917 } 00918 00919 /*************************************************************************************** 00920 ** Function name: drawRightString 00921 ** Descriptions: draw string right justified 00922 ***************************************************************************************/ 00923 int ST7735::drawRightString(char *string, int dX, int poY, int font) 00924 { 00925 int sumX = 0; 00926 int len = 0; 00927 char *pointer = string; 00928 char ascii; 00929 00930 while(*pointer) 00931 { 00932 ascii = *pointer; 00933 //if (font==0)len += 1+pgm_read_byte(widtbl_log+ascii); 00934 //if (font==1)len += 1+pgm_read_byte(widtbl_f8+ascii-32); 00935 #ifdef LOAD_FONT2 00936 if (font==2)len += 1+pgm_read_byte(widtbl_f16+ascii-32); 00937 #endif 00938 //if (font==3)len += 1+pgm_read_byte(widtbl_f48+ascii-32)/2; 00939 #ifdef LOAD_FONT4 00940 if (font==4)len += pgm_read_byte(widtbl_f32+ascii-32)-3; 00941 #endif 00942 //if (font==5) len += pgm_read_byte(widtbl_f48+ascii-32)-3; 00943 #ifdef LOAD_FONT6 00944 if (font==6) len += pgm_read_byte(widtbl_f64+ascii-32)-3; 00945 #endif 00946 #ifdef LOAD_FONT7 00947 if (font==7) len += pgm_read_byte(widtbl_f7s+ascii-32)+2; 00948 #endif 00949 #ifdef LOAD_FONT8 00950 if (font==8) len += pgm_read_byte(widtbl_f72+ascii-32)+2; 00951 #endif 00952 *pointer++; 00953 } 00954 00955 len = len*textsize; 00956 int poX = dX - len; 00957 00958 if (poX < 0) poX = 0; 00959 00960 while(*string) 00961 { 00962 00963 int xPlus = drawChar(*string, poX, poY, font); 00964 sumX += xPlus; 00965 *string++; 00966 poX += xPlus; /* Move cursor right */ 00967 } 00968 00969 return sumX; 00970 } 00971 00972 /*************************************************************************************** 00973 ** Function name: drawFloat 00974 ** Descriptions: drawFloat 00975 ***************************************************************************************/ 00976 int ST7735::drawFloat(float floatNumber, int decimal, int poX, int poY, int font) 00977 { 00978 unsigned long temp=0; 00979 float decy=0.0; 00980 float rounding = 0.5; 00981 00982 float eep = 0.000001; 00983 00984 int sumX = 0; 00985 int xPlus = 0; 00986 00987 if(floatNumber-0.0 < eep) // floatNumber < 0 00988 { 00989 xPlus = drawChar('-',poX, poY, font); 00990 floatNumber = -floatNumber; 00991 00992 poX += xPlus; 00993 sumX += xPlus; 00994 } 00995 00996 for (unsigned char i=0; i<decimal; ++i) 00997 { 00998 rounding /= 10.0; 00999 } 01000 01001 floatNumber += rounding; 01002 01003 temp = (long)floatNumber; 01004 01005 01006 xPlus = drawNumber(temp,poX, poY, font); 01007 01008 poX += xPlus; 01009 sumX += xPlus; 01010 01011 if(decimal>0) 01012 { 01013 xPlus = drawChar('.',poX, poY, font); 01014 poX += xPlus; /* Move cursor right */ 01015 sumX += xPlus; 01016 } 01017 else 01018 { 01019 return sumX; 01020 } 01021 01022 decy = floatNumber - temp; 01023 for(unsigned char i=0; i<decimal; i++) 01024 { 01025 decy *= 10; /* for the next decimal */ 01026 temp = decy; /* get the decimal */ 01027 xPlus = drawNumber(temp,poX, poY, font); 01028 01029 poX += xPlus; /* Move cursor right */ 01030 sumX += xPlus; 01031 decy -= temp; 01032 } 01033 return sumX; 01034 } 01035 01036 void ST7735::setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) { 01037 01038 writecommand(ST7735_CASET); // Column addr set 01039 writedata(0x00); 01040 writedata(x0+colstart); // XSTART 01041 writedata(0x00); 01042 writedata(x1+colstart); // XEND 01043 01044 writecommand(ST7735_RASET); // Row addr set 01045 writedata(0x00); 01046 writedata(y0+rowstart); // YSTART 01047 writedata(0x00); 01048 writedata(y1+rowstart); // YEND 01049 01050 writecommand(ST7735_RAMWR); // write to RAM 01051 } 01052 01053
Generated on Wed Jul 13 2022 21:17:58 by 1.7.2