Tiny TFT library for ATtiny microcontrollers

TFT library on ATtiny85 driving Adafruit 2.0″ 320×240 color display

This article is about a small graphics library designed specifically for ATtiny microcontrollers used with various miniature TFT displays, which can be purchased inexpensively from Adafruit, AliExpress or Banggood.

This is an updated version of my Tiny TFT Graphics Library that supports both classic ATtiny processors like the ATtiny85 and newer 0-series, 1-series and 2-series models like the ATtiny402. Like the original library, it allows you to draw points, lines, filled rectangles, as well as symbols and text in a 16-bit color palette with a configurable scaling factor.

The current version has the ability to draw outline rectangles, as well as outline and filled circles. In addition, I added demo programs for drawing curves and histograms that adapt to any display.


This library supports TFT displays that use the SPI interface and require four pins for control. As a result, on an 8-pin microcircuit like ATtiny85 or ATtiny402, one free contact remains. If you need more, get another IC like ATtiny84 or ATtiny404.

Unlike my Compact TFT Graphics Library, which uses standard Arduino SPI calls, this library interacts directly with I/O. This is about twice as fast as using SPI, and also allows you to use any pin assignment of the four I / O lines required by the display. I also expanded the range of supported TFT displays – now there are 16 of them.

How it all works

On classic ATtiny processors such as the ATtiny85, the library takes advantage of the ability to toggle one or more bits in a port by writing to a register.


for example, to enable/disable the chip-select signal:

PINB = 1<<cs;

So if all pins are set to disabled at startup, the display routines can simply toggle the pins they want, activating or deactivating them.

The new ATtiny 0-series and 1-series use the same case OUTTGL. For example:


Differences between each processor family are handled by constants defining pin assignments and a preprocessing macro defining bit manipulations. If you apply the diagrams below, you won’t need to change anything, just specify which display is being used.

I further optimized the procedure ClearDisplay()when I realized there was no need to go on and set the beat mosisince to clear the display it will always be zero, which means that the procedure only needs to switch the bit sck the right number of times. Thanks to Thomas Scherer for the idea.


The table below shows the performance difference when using a 240×240 TFT display with an ATtiny402 20MHz:

The entire library is less than 4KB, including the character set and demo programs, which means it will fit perfectly on microcontrollers with 4KB of flash memory, such as the ATtiny45 and ATtiny402.

Supported displays

This library will work with displays based on the ST7735 controller that supports a maximum screen size of 162×132, or ST7789 and ILI9340/1 that support 320×240. It contains parameters for the following TFT color displays:

* These Adafruit displays conveniently have the same side connector layout, allowing you to assemble a breadboard or PCB with the ability to connect any of them.

† These AliExpress models also have the same connector layout. Some of them include a 3.3V LDO, but no logic level conversion, so I recommend connecting them only to a 3.3V processor.

In turn, Adafruit displays all contain a 3.3V LDO regulator and a logic level converter, which means they can be connected to 5V or 3.3V processors.

For a red display 160×128 with AliExpress, to turn on the backlight, its contact must be connected to Vcc. This is not required for other displays.

My library allows you to customize the image orientation – so you can play with the display setup in different ways.

It is likely that it will support other models with the same ST7735, ST7789 or ILI9340/1 controllers, but you may need to adjust the settings to achieve proper image scaling and centering.

Display connection

To use the library, you need to properly connect the display and select the appropriate settings for it.

The display is connected to the microcontroller via four input/output lines: MOSI, SCK, CS and DC. To do this, you can use any contacts, but they must all be in the same port. The numbers of port pins to be used must be specified at the beginning of the library listing.

Keep in mind that on different display boards, the pins are designated differently:

Don’t be surprised by the SCL and SDA markings used on some displays – these are definitely SPI displays.


By default, the library sets the following pins for ATtiny85/84 in



int const dc = 0;
int const mosi = 1;
int const sck = 2;
int const cs = 3;

And here is the corresponding display connection diagram from AliExpress:

TFT color display wiring diagram using ATtiny85

A 33kΩ pull-up resistor is optional here. It is needed only on displays from AliExpress, where its task is to keep the chip select at a high level so that the screen does not flicker during programming of the microcontroller.

In the case of Adafruit displays, the 10kΩ resistor can be dispensed with, since they have a pull-up implemented on their own board.


By default, the library sets the following pins for ATtiny402/412 in



int const dc = 7;
int const mosi = 1;
int const sck = 3;
int const cs = 6;

And here is the corresponding display connection diagram from AliExpress:

TFT color display wiring diagram using ATtiny402

When using an Adafruit display, the 10kΩ resistor can be omitted, as they have a pull-up on the board itself.

An example implementation of this circuit with an Adafruit 320×240 2.2″ TFT display:

Tiny TFT library on ATtiny402 driving Adafruit 2.2″ 320×240 color TFT display

Display setting

Display options are defined by seven constants that set the size, offset from the area supported by the display driver, invert, screen rotation, and color order. For example:

// Adafruit 1.44" 128x128 display
int const xsize=128, ysize=128, xoff=2, yoff=1, invert=0, rotate=3, bgr=1;

Uncomment the options for the display being used.

By default, the options are set to the correct orientation, assuming you use the pins along the top of the display. The exception is large models, in which these contacts are located along the short side – in this case, they are assumed to be on the left.

However, changing the constant rotateyou can adjust the screen rotation in your own way:

Test pattern Test Chart

Keep in mind that on some displays, when you rotate an image, you may also need to change the value xoof or yoff.

You can use the program to check or adjust the values ​​for each display. TestChart()which draws a one-pixel-padded box around the perimeter and displays an “F”, allowing you to determine the orientation:

void TestChart () {
  DrawRect(xsize, ysize);
  scale = 8;
  fore = Colour(255, 0, 0);
  MoveTo((xsize-40)/2, (ysize-64)/2); PlotChar('F');
  scale = 1;


Test Chart on TFT color display 1.14″ 240×135 from AliExpress

If the “F” symbol is blue, you need to change the value bgr.

The library will certainly support other TFT displays using the same controllers, but in this case, you may need to adjust the parameters.

Graphics Commands

Here is a general list of graphic library commands:

The library uses a 16-bit color mode with 5 bits for red, 6 for green, and 5 for blue.

Colour() allows you to set a color value by specifying its red, green and blue components as numbers from 0 to 255:

unsigned int Colour (int r, int g, int b)

Foreground and background

The foreground and background color is determined by two global variables




. Initially they are set to white (


) and black (


) respectively.

int fore = White;
int back = Black;

Cleaning the display

clears the display to black:

void ClearDisplay ()

Drawing points and drawing lines

The library contains basic graphics routines for plotting points and drawing lines. They work in the traditional coordinate system, where the origin is in the lower left corner.

Here is an example for an 80×160 display:

The current draw position is stored in global variables xpos and ypos. You can change it with MoveTo():

void MoveTo (int x, int y)


draws a single dot that has the color of the current foreground:

void PlotPoint (int x, int y)


draws a line with the foreground color from the current position to


after which the current position is updated:

void DrawTo (int x, int y)

Drawing rectangles

draws an outline, and


filled rectangle, with width


and height


. In this case, the lower left corner is set to the current drawing position, and painting is performed in the current foreground color:

void DrawRect (int w, int h)
void FillRect (int w, int h)

After the drawing position does not change.

Drawing circles

DrawCircle() draws an outline, and FillCircle() filled circle with radius radiussetting the center to the current draw position:

void DrawCircle (int radius)
void FillCircle (int radius)

Upon completion, the draw position remains the same.

Symbols and text
The library contains a character set based on a 5×7 dot matrix.

PlotChar() draws the given character at the current position with the current foreground color:

void PlotChar (char c)

You can draw larger characters by changing the variable


whose initial value is


. After drawing the symbol


moves the current position to the start of the next one, allowing multiple characters to be output in a row without calling



PlotText() outputs text from a string held in program memory:

void PlotText (PGM_P p)

Examples can be viewed in the demo programs.

PlotInt() draws a number:

void PlotInt (int i)

Compiling the graphics library


Compile the program with

ATTinyCore by Spence Konde

. On the menu


under the heading


select an option

ATtiny25/45/85 (No bootloader)

. Then make sure the following options are set like this (ignore others):

Chip: "ATtiny85"
Clock Source: "8 MHz (internal)"

By default, ATtiny operates at 1MHz. Select

Burn Bootloader

to set the fuse bits to 8MHz mode, otherwise the graphics will run slowly. Then download the program using the ISP programmer, for example,

Tiny AVR Programmer Board by SparkFun



Compile the program with

megaTinyCore by Spence Konde

. On the menu


under the heading


select an option


. Check that the following options are set like this (ignore the rest):

Chip: "ATtiny420" (либо другой соответствующий)
Clock: "20 MHz internal"

Next, download the program through the UPDI programmer. It is recommended to use a USB to Serial board, such as

FTDI Basic by SparkFun

connected through a 4.7kΩ resistor:

Set option programmer on the “SerialUPDI with 4.7k resistor or diode (230400 baud)”.


Similar Posts

Leave a Reply