All tutorials

4 · Displays & buses

Colour TFT screen over SPI

Expert30 min

Goal

Drive a 240×240 ST7789 with the hardware SPI port.

Why it matters

SPI is far faster than I²C: essential for video.

Steps

  1. 01Drag the TFT 240×240 (SPI) component onto the canvas.
  2. 02Keep DC on D8 — SCK is D13 and MOSI is D11 on the UNO.
  3. 03Load the starter sketch: it initialises the panel and draws colour bars.
  4. 04Edit the colour array to draw your own interface.

Starter sketch

// ST7789 240x240 SPI display driven directly — DC on D8, RST on D9, CS on D10.
#include <SPI.h>

#define TFT_DC 8
#define TFT_RST 9
#define TFT_CS 10

void cmd(uint8_t c) {
  digitalWrite(TFT_DC, LOW);
  digitalWrite(TFT_CS, LOW);
  SPI.transfer(c);
  digitalWrite(TFT_CS, HIGH);
}

void dat(uint8_t d) {
  digitalWrite(TFT_DC, HIGH);
  digitalWrite(TFT_CS, LOW);
  SPI.transfer(d);
  digitalWrite(TFT_CS, HIGH);
}

void window(int x0, int y0, int x1, int y1) {
  cmd(0x2A); dat(x0 >> 8); dat(x0); dat(x1 >> 8); dat(x1);
  cmd(0x2B); dat(y0 >> 8); dat(y0); dat(y1 >> 8); dat(y1);
  cmd(0x2C);
}

void fill(int x, int y, int w, int h, uint16_t color) {
  window(x, y, x + w - 1, y + h - 1);
  digitalWrite(TFT_DC, HIGH);
  digitalWrite(TFT_CS, LOW);
  for (long i = 0; i < (long)w * h; i++) {
    SPI.transfer(color >> 8);
    SPI.transfer(color & 0xFF);
  }
  digitalWrite(TFT_CS, HIGH);
}

void setup() {
  pinMode(TFT_DC, OUTPUT);
  pinMode(TFT_RST, OUTPUT);
  pinMode(TFT_CS, OUTPUT);
  digitalWrite(TFT_CS, HIGH);
  SPI.begin();

  digitalWrite(TFT_RST, LOW); delay(20);
  digitalWrite(TFT_RST, HIGH); delay(50);

  cmd(0x01); delay(50);   // software reset
  cmd(0x11); delay(50);   // sleep out
  cmd(0x3A); dat(0x55);   // 16-bit color
  cmd(0x36); dat(0x00);   // memory access
  cmd(0x21);              // inversion on (typical for 240x240 panels)
  cmd(0x29);              // display on

  fill(0, 0, 240, 240, 0x0000);
}

uint16_t bar = 0;

void loop() {
  const uint16_t colors[4] = { 0xF800, 0x07E0, 0x001F, 0xFFE0 };
  fill(0, (bar % 4) * 60, 240, 60, colors[bar % 4]);
  bar++;
  delay(400);
}

This tutorial runs inside the Circuitly simulator: your wiring and your code are checked automatically at every step.

Next tutorials