Ten post chciałbym poświęcić na opisanie sposobu sterowania wyświetlaczem TFT 1.8 cala za pomocą interfejsu SPI.
[Źródło: https://nettigo.pl/products/wyswietlacz-lcd-tft-1-8-spi-ili9163]
Podłączenie:
Poniżej przedstawię w jaki sposób podłączyć układ do płytki Arduino:
- LED - 3.3V
- SCK - Arduino pin 13
- SDA - Arduino pin 11
- A0 - definiowany w programie
- RESET - definiowany w programie
- CS - definiowany w programie
- GND - GND
- VCC - 5V
Biblioteki:
W projekcie będą wykorzystywane dwie wbudowane biblioteki. Jedna z nich SPI.h odpowiada za komunikację z wyświetlaczem poprzez interfejs SPI. Druga czyli TFT.h jest odpowiedzialna za rysowanie oraz wypisywanie tekstu na ekranie.
Biblioteka dla wyświetlacza korzysta z plików przygotowanych przez Adafruit, które zawierają funkcje graficzne takie jak rysowanie bitmap, figur geometrycznych czy obsługi tekstu.
Sam plik TFT zawiera inicjalizację obiektu który przekazuje wielkość wyświetlacza oraz piny sterujące dla biblioteki z Adafruit.
Jedyna funkcja jaka znajduje się w pliku TFT odpowiada za uruchomienie sterownika wyświetlacza (ILI9163C) oraz ustawienia orientacji ekranu:
- void TFT::begin() {
- initG();
- setRotation(1);
- }
Funkcja uruchamiająca sterownik wyświetlacza oraz ustawiająca SPI:
- // Initialization for ST7735B screens
- void Adafruit_ST7735::initG(void) {
- commonInit(Gcmd);
- }
- // Initialization code common to both 'B' and 'R' type displays
- void Adafruit_ST7735::commonInit(const uint8_t *cmdList)
- {
- colstart = rowstart = 0; // May be overridden in init func
- pinMode(_rs, OUTPUT);
- pinMode(_cs, OUTPUT);
- csport = portOutputRegister(digitalPinToPort(_cs));
- cspinmask = digitalPinToBitMask(_cs);
- rsport = portOutputRegister(digitalPinToPort(_rs));
- rspinmask = digitalPinToBitMask(_rs);
- if(hwSPI) { // Using hardware SPI
- SPI.begin();
- #ifdef SPI_HAS_TRANSACTION
- spisettings = SPISettings(4000000L, MSBFIRST, SPI_MODE0);
- #else
- #if defined(ARDUINO_ARCH_SAM)
- SPI.setClockDivider(24); // 4 MHz (half speed)
- #else
- SPI.setClockDivider(SPI_CLOCK_DIV4); // 4 MHz (half speed)
- #endif
- SPI.setBitOrder(MSBFIRST);
- SPI.setDataMode(SPI_MODE0);
- #endif // SPI_HAS_TRANSACTION
- } else {
- pinMode(_sclk, OUTPUT);
- pinMode(_sid , OUTPUT);
- clkport = portOutputRegister(digitalPinToPort(_sclk));
- clkpinmask = digitalPinToBitMask(_sclk);
- dataport = portOutputRegister(digitalPinToPort(_sid));
- datapinmask = digitalPinToBitMask(_sid);
- *clkport &= ~clkpinmask;
- *dataport &= ~datapinmask;
- }
- // toggle RST low to reset; CS low so it'll listen to us
- *csport &= ~cspinmask;
- if (_rst) {
- pinMode(_rst, OUTPUT);
- digitalWrite(_rst, HIGH);
- delay(500);
- digitalWrite(_rst, LOW);
- delay(500);
- digitalWrite(_rst, HIGH);
- delay(500);
- }
- if(cmdList) commandList(cmdList);
- }
Z funkcji korzysta się poprzez wywołanie zdefiniowanego typu z biblioteki TFT i podanie funkcji z jakiej chce się dla wyświetlacza korzystać. Lista dostępnych publicznych funkcji wygląda następująco:
- Adafruit_ST7735(uint8_t CS, uint8_t RS, uint8_t SID, uint8_t SCLK,
- uint8_t RST);
- Adafruit_ST7735(uint8_t CS, uint8_t RS, uint8_t RST);
- void initB(void), // for ST7735B displays
- initG(void), // for ILI9163C displays
- initR(uint8_t options = INITR_GREENTAB), // for ST7735R
- setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1),
- pushColor(uint16_t color),
- fillScreen(uint16_t color),
- drawPixel(int16_t x, int16_t y, uint16_t color),
- drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color),
- drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color),
- fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
- uint16_t color),
- setRotation(uint8_t r),
- invertDisplay(boolean i);
- uint16_t Color565(uint8_t r, uint8_t g, uint8_t b) { return newColor(r, g, b);}
Dodatkowo dostępne są funkcje:
- public:
- Adafruit_GFX(int16_t w, int16_t h); // Constructor
- // This MUST be defined by the subclass
- virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
- // These MAY be overridden by the subclass to provide device-specific
- // optimized code. Otherwise 'generic' versions are used.
- virtual void
- drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
- uint16_t color),
- drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color),
- drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color),
- drawRect(int16_t x, int16_t y, int16_t w, int16_t h,
- uint16_t color),
- fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
- uint16_t color),
- fillScreen(uint16_t color),
- invertDisplay(boolean i);
- // These exist only with Adafruit_GFX (no subclass overrides)
- void
- drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color),
- drawCircleHelper(int16_t x0, int16_t y0,
- int16_t r, uint8_t cornername, uint16_t color),
- fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color),
- fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
- uint8_t cornername, int16_t delta, uint16_t color),
- drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
- int16_t x2, int16_t y2, uint16_t color),
- fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
- int16_t x2, int16_t y2, uint16_t color),
- drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h,
- int16_t radius, uint16_t color),
- fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h,
- int16_t radius, uint16_t color),
- drawBitmap(int16_t x, int16_t y,
- const uint8_t *bitmap, int16_t w, int16_t h,
- uint16_t color),
- drawChar(int16_t x, int16_t y, unsigned char c,
- uint16_t color, uint16_t bg, uint8_t size),
- setCursor(int16_t x, int16_t y),
- setTextColor(uint16_t c),
- setTextColor(uint16_t c, uint16_t bg),
- setTextSize(uint8_t s),
- setTextWrap(boolean w),
- setRotation(uint8_t r);
- #if ARDUINO >= 100
- virtual size_t write(uint8_t);
- #else
- virtual void write(uint8_t);
- #endif
- int16_t
- height(void),
- width(void);
- uint8_t getRotation(void);
- /*
- * Processing-like graphics primitives
- */
- /// transforms a color in 16-bit form given the RGB components.
- /// The default implementation makes a 5-bit red, a 6-bit
- /// green and a 5-bit blue (MSB to LSB). Devices that use
- /// different scheme should override this.
- virtual uint16_t newColor(uint8_t red, uint8_t green, uint8_t blue);
- void
- // http://processing.org/reference/background_.html
- background(uint8_t red, uint8_t green, uint8_t blue),
- background(color c),
- // http://processing.org/reference/fill_.html
- fill(uint8_t red, uint8_t green, uint8_t blue),
- fill(color c),
- // http://processing.org/reference/noFill_.html
- noFill(),
- // http://processing.org/reference/stroke_.html
- stroke(uint8_t red, uint8_t green, uint8_t blue),
- stroke(color c),
- // http://processing.org/reference/noStroke_.html
- noStroke(),
- text(const char * text, int16_t x, int16_t y),
- textWrap(const char * text, int16_t x, int16_t y),
- textSize(uint8_t size),
- // similar to ellipse() in Processing, but with
- // a single radius.
- // http://processing.org/reference/ellipse_.html
- circle(int16_t x, int16_t y, int16_t r),
- point(int16_t x, int16_t y),
- line(int16_t x1, int16_t y1, int16_t x2, int16_t y2),
- quad(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t x3, int16_t y3, int16_t x4, int16_t y4),
- rect(int16_t x, int16_t y, int16_t width, int16_t height),
- rect(int16_t x, int16_t y, int16_t width, int16_t height, int16_t radius),
- triangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t x3, int16_t y3);
Programowanie:
Poniżej przedstawię prostą aplikacje wypisującą tekst na ekranie oraz zmieniającą jego kolor:
- #include <TFT.h>
- #include <SPI.h>
- /* Pin definitions*/
- #define CS_Pin 10
- #define A0_Pin 9
- #define RST_Pin 8
- /* Create library instance, pass pin numbers */
- TFT TFTDisplay = TFT(CS_Pin, A0_Pin, RST_Pin);
- void setup() {
- /* Initialize library */
- TFTDisplay.begin();
- /* Clear screen, set background color */
- TFTDisplay.background(0, 0, 0);
- /* set the font color to white */
- TFTDisplay.stroke(255, 255, 255);
- /* Set text size */
- TFTDisplay.setTextSize(4);
- TFTDisplay.text("Napis :\n ", 0, 0);
- /* Select font color */
- TFTDisplay.stroke(50, 100, 100);
- }
- void loop()
- {
- int redColor = 0;
- int greenColor = 0;
- int blueColor = 0;
- TFTDisplay.stroke(redColor, greenColor, blueColor);
- /* Print text */
- TFTDisplay.text("Hello, World!", 20, 24);
- if(redColor == 255)
- {
- redColor=0;
- greenColor=0;
- blueColor=0;
- }
- redColor++;
- greenColor++;
- blueColor++;
- /* Small delay */
- delay(100);
- }