В статье речь пойдёт о маленькой графической библиотеке, предназначенной специально для микроконтроллеров ATtiny, используемых с различными миниатюрными TFT-дисплеями, которые можно недорого приобрести на сайтах Adafruit, AliExpress или Banggood.
Это обновлённая версия моей Tiny TFT Graphics Library, которая поддерживает и классические процессоры ATtiny, такие как ATtiny85, и новые модели 0-, 1- и 2-серий, например, ATtiny402. Как и оригинальная библиотека, она позволяет отрисовывать точки, линии, закрашенные прямоугольники, а также символы и текст в 16-битной цветовой палитре с настраиваемым фактором масштабирования.
В текущей версии появилась возможность рисовать контурные прямоугольники, а также контурные и закрашенные круги. Помимо этого, я добавил подстраивающиеся под любой дисплей демо-программы для рисования кривых и гистограмм.
Введение
Эта библиотека поддерживает TFT-дисплеи, использующие интерфейс SPI и требующие четыре контакта для управления. В итоге на 8-контактной микросхеме вроде ATtiny85 или ATtiny402 остаётся один свободный контакт. Если вам нужно больше, берите другую микросхему, например, ATtiny84 или ATtiny404.
В отличие от моей Compact TFT Graphics Library, которая использует стандартные вызовы Arduino SPI, эта библиотека напрямую взаимодействует с вводом/выводом. Это примерно вдвое ускоряет работу в сравнении с использованием SPI, а также позволяет использовать любое назначение контактов четырёх необходимых дисплею линий ввода/вывода. Ещё я расширил спектр поддерживаемых TFT-дисплеев – теперь их 16.
Как всё это работает
На классических процессорах ATtiny, таких как ATtiny85, библиотека использует возможность переключения одного или более бит в порту с помощью записи в регистр PINB
, например, для активации/отключения сигнала chip-select (выбора микросхемы):
PINB = 1<<cs;
Так что, если при запуске все контакты установлены на состояние «отключён», то процедуры дисплея смогут просто переключать нужные из них, активируя или отключая.
На новых ATtiny 0- и 1-серии используется равнозначный регистр OUTTGL
. Например:
PORTA.OUTTGL = 1<<cs;
Отличия между каждым семейством процессоров обрабатываются константами, определяющими назначения контактов, и макросом препроцессинга, определяющим манипуляции с битами. Если вы примените приведённые ниже схемы, то вам не потребуется что-либо менять, только указать, какой используется дисплей.
Я дополнительно оптимизировал процедуру ClearDisplay()
, когда осознал, что нет нужды продолжать и устанавливать бит mosi
, так как для очистки дисплея он всегда будет нулевым, а значит, процедуре нужно только переключать бит sck
нужное число раз. Благодарю Томаса Шерера за поданную идею.
Быстродействие
В таблице ниже отражено отличие в быстродействии при использовании TFT-дисплея 240х240 с ATtiny402 20МГц:
Компактная библиотека TFT | Крошечная библиотека TFT | |
ClearDisplay() | 856 мс | 279 мс |
FillRect(240, 240) | 1142 мс | 737 мс |
TestChart() | 210 мс | 61 мс |
BarChart() | 1306 мс | 728 мс |
Вся библиотека занимает менее 4КБ, включая набор символов и демо-программы, а значит, вполне уместится на микроконтроллерах с 4КБ флэш-памяти, таких как ATtiny45 и ATtiny402.
Поддерживаемые дисплеи
Эта библиотека будет работать с дисплеями на базе контроллера ST7735, поддерживающего максимальный размер экрана 162х132, либо ST7789 и ILI9340/1, поддерживающих размер 320х240. Она содержит параметры для следующих цветных TFT-дисплеев:
Поставщик | Размер | Ширина | Высота | Напряжение | Контроллер | Ссылка |
Adafruit | 1.44" | 128 | 128 | 3.3 — 5V | ST7735R | Adafruit 1.44" Color TFT LCD Display * |
AliExpress | 1.44" | 128 | 128 | 3.3 — 5V | ST7735R | 1.44" 128x128 SPI TFT display † |
Adafruit | 0.96" | 160 | 80 | 3.3 — 5V | ST7735 | Adafruit 0.96" 160x80 Color TFT Display * |
AliExpress | 0.96" | 160 | 80 | 3.3V | ST7735 | TFT Display 0.96 inch 80x160 † |
Adafruit | 1.8" | 160 | 128 | 3.3 — 5V | ST7735R | Adafruit 1.8" Color TFT LCD display |
AliExpress | 1.8" | 160 | 128 | 3.3V | ST7735R | 1.8 inch TFT LCD Module 128x160 |
AliExpress | 1.8" | 160 | 128 | 3.3V | ST7735R | 1.8" 128x160 SPI TFT display † |
Adafruit | 1.14" | 240 | 135 | 3.3 — 5V | ST7789 | Adafruit 1.14" 240x135 Color TFT Display * |
AliExpress | 1.14" | 240 | 135 | 3.3V | ST7789 | 1.14in SPI 240x135 RGB TFT display † |
Adafruit | 1.3" | 240 | 240 | 3.3 — 5V | ST7789 | Adafruit 1.3" 240x240 Wide Angle TFT LCD Display * |
Adafruit | 1.54" | 240 | 240 | 3.3 — 5V | ST7789 | Adafruit 1.54" 240x240 TFT LCD Display * |
AliExpress | 1.54" | 240 | 240 | 3.3V | ST7789 | 1.54" TFT 240x240 LCD Display † |
Adafruit | 1.9" | 320 | 170 | 3.3 — 5V | ST7789 | Adafruit 1.9" 320x170 Color IPS TFT Display * |
Adafruit | 2.0" | 320 | 240 | 3.3 — 5V | ST7789 | Adafruit 2.0" 320x240 Color TFT Display * |
Adafruit | 2.2" | 320 | 240 | 3.3 — 5V | ILI9340C | Adafruit 2.2" 320x240 Color TFT Display |
AliExpress | 2.4" | 320 | 240 | 3.3V | ILI9341 | 2.4" 320x240 TFT Display Module † |
* Эти дисплеи Adafruit к удобству имеют одинаковое расположение боковых разъёмов, что позволяет собрать макетную или печатную плату с возможностью подключения любого из них.
† Эти модели с AliExpress тоже имеют одинаковое расположение разъёмов. Некоторые из них включают LDO-регулятор 3.3В, но без преобразования логического уровня, так что я советую подключать их только к процессору, работающему от 3.3В.
В свою очередь, дисплеи Adafruit все содержат LDO-регулятор 3.3В и преобразователь логического уровня, а значит, могут подключаться к процессорам 5В или 3.3В.
У красного дисплея 160х128 с AliExpress для включения подсветки её контакт нужно подключить к Vcc. В случае других дисплеев этого не требуется.
Моя библиотека позволяет настраивать ориентацию изображения — чтобы можно было по-разному обыграть установку дисплея.
Есть вероятность, что она будет поддерживать и другие модели с теми же контроллерами ST7735, ST7789 или ILI9340/1, но при этом вам может потребоваться подобрать параметры, чтобы добиться правильного масштабирования и центровки изображения.
Подключение дисплея
Для использования библиотеки нужно правильно подключить дисплей и выбрать для него подходящие параметры.
Дисплей подключается к микроконтроллеру по четырём линиям ввода/вывода: MOSI, SCK, CS и DC. Для этого можно задействовать любые контакты, но они все должны находиться в одном порту. Номера используемых контактов порта необходимо указать в начале листинга библиотеки.
Имейте ввиду, что на разных платах дисплеев контакты обозначаются по-разному:
Контакт | Маркировка |
Vcc | Vin |
Ground | GND |
Clock | SCK, SCL |
Data In | MOSI, SI, SDA |
Chip Select | CS, TCS |
Data/Command | DC, D/C, A0 |
Backlight | LITE, LIT, BLK |
Не удивляйтесь используемой на некоторых дисплеях маркировке SCL и SDA — это определённо дисплеи SPI.
ATtiny85/45
По умолчанию библиотека устанавливает для ATtiny85/84 следующие контакты в PORT B
:
int const dc = 0;
int const mosi = 1;
int const sck = 2;
int const cs = 3;
А вот соответствующая схема подключения дисплея с AliExpress:
Схема подключения цветного TFT-дисплея с использованием ATtiny85
Подтягивающий резистор 33кОм здесь необязателен. Он необходим только на дисплеях с AliExpress, где его задача удерживать chip select на высоком уровне, чтобы во время программирования микроконтроллера экран не мерцал.
В случае дисплеев Adafruit можно обойтись без резистора 10кОм, поскольку у них подтягивание реализовано на собственной плате.
ATtiny402/412
По умолчанию библиотека устанавливает для ATtiny402/412 следующие контакты в PORT A
:
int const dc = 7;
int const mosi = 1;
int const sck = 3;
int const cs = 6;
А вот соответствующая схема подключения дисплея с AliExpress:
Схема подключения цветного TFT-дисплея с использованием ATtiny402
При использовании дисплея Adafruit резистор 10кОм можно опустить, так как у них подтягивание происходит на самой плате.
Пример реализации этой схемы с дисплеем Adafruit 320x240 2.2" TFT:
Крошечная библиотека TFT на ATtiny402, управляющая цветным TFT-дисплеем Adafruit 2.2" 320x240
Настройка дисплея
Параметры дисплеев определяются семью константами, которые устанавливают размер, смещение относительно области, поддерживаемой драйвером дисплея, инвертирование, степень поворота экрана, а также порядок цветов. Например:
// Adafruit 1.44" 128x128 display
int const xsize=128, ysize=128, xoff=2, yoff=1, invert=0, rotate=3, bgr=1;
Раскомментируйте параметры для используемого дисплея.
По умолчанию параметры задают верную ориентацию — исходя из предположения, что вы используете контакты вдоль верхней части дисплея. Исключением становятся крупные модели, у которых эти контакты расположены вдоль короткой стороны – в этом случае предполагается, что они находятся слева.
Тем не менее изменяя константу rotate
, можно настроить поворот экрана по-своему:
Тестовый паттерн Test Chart
Имейте в виду, что на некоторых дисплеях при повороте изображения вам также может потребоваться изменить значение xoof
или yoff
.
Для проверки или подстройки значений под каждый дисплей можно использовать программу TestChart()
, которая рисует по периметру рамку с отступом в один пиксель и отображает “F”, позволяя определить ориентацию:
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 на цветном TFT-дисплее 1.14" 240x135 с AliExpress
Если символ “F” окажется синим, необходимо изменить значение bgr
.
Библиотека наверняка будет поддерживать и другие TFT-дисплеи, использующие те же контроллеры, но в этом случае может потребоваться подстройка параметров.
Графические команды
Вот общий список графических команд библиотеки:
Colour
Библиотека использует 16-битный режим цвета, в котором 5 бит отводится красному, 6 зелёному и 5 синему.
Colour()
позволяет задавать значение цвета путём указания его красной, зелёной и синей компонент в виде чисел от 0 до 255:
unsigned int Colour (int r, int g, int b)
Передний и задний план
Цвет переднего и заднего плана определяется двумя глобальными переменными fore
и back
. Изначально они установлены на белый (0xFFFF
) и чёрный (0
) соответственно.
int fore = White;
int back = Black;
Очистка дисплея
ClearDisplay()
очищает дисплей в чёрный цвет:
void ClearDisplay ()
Нанесение точек и отрисовка линий
Библиотека содержит базовые графические процедуры для нанесения точек и отрисовки линий. Работают они в традиционной системе координат, где исходная точка находится в нижнем левом углу.
Вот пример для дисплея 80х160:
Текущая позиция отрисовки хранится в глобальных переменных xpos
и ypos
. Изменить её можно с помощью MoveTo()
:
void MoveTo (int x, int y)
PlotPoint()
наносит одну точку, имеющую цвет текущего переднего плана:
void PlotPoint (int x, int y)
DrawTo()
отрисовывает линию с цветом переднего плана из текущей позиции до x,y
, после чего текущая позиция обновляется:
void DrawTo (int x, int y)
Отрисовка прямоугольников
DrawRect()
рисует контурный, а FillRect()
закрашенный прямоугольник, с шириной w
и высотой h
. При этом нижний левый угол устанавливается в текущую позицию отрисовки, а закрашивание производится в текущий цвет переднего плана:
void DrawRect (int w, int h)
void FillRect (int w, int h)
После позиция отрисовки не меняется.
Отрисовка кругов
DrawCircle()
рисует контурный, а FillCircle()
закрашенный круг с радиусом radius
, устанавливая центр в текущую позицию отрисовки:
void DrawCircle (int radius)
void FillCircle (int radius)
По завершению позиция отрисовки остаётся прежней.
Символы и текст
Библиотека содержит набор символов, основанный на точечной матрице 5х7.
PlotChar()
отрисовывает заданный символ в текущей позиции с текущим цветом переднего плана:
void PlotChar (char c)
Можно отрисовывать более крупные символы, изменяя переменную scale
, чьё изначальное значение равно 1
. После отрисовки символа PlotChar()
перемещает текущую позицию к началу следующего, позволяя выводить несколько символов подряд без вызова MoveTo()
.
PlotText()
выводит текст из строки, содержащейся в программной памяти:
void PlotText (PGM_P p)
Примеры можно посмотреть в демо-программах.
PlotInt()
рисует число:
void PlotInt (int i)
Компиляция графической библиотеки
ATtiny85/45
Скомпилируйте программу с помощью ATTinyCore от Spence Konde. В меню Board под заголовком ATTinyCore выберите опцию ATtiny25/45/85 (No bootloader). Затем убедитесь, чтобы последующие опции были установлены так (прочие игнорируйте):
Chip: "ATtiny85"
Clock Source: "8 MHz (internal)"
По умолчанию ATtiny работает на 1МГц. Выберите Burn Bootloader, чтобы установить фьюз-биты в режим 8МГц, иначе графика будет работать медленно. Затем загрузите программу с помощью программатора ISP, например, Tiny AVR Programmer Board от SparkFun.
ATtiny402/412
Скомпилируйте программу с помощью megaTinyCore от Spence Konde. В меню Board под заголовком megaTinyCore выберите опцию ATtiny412/402/212/202. Проверьте, чтобы последующие опции были установлены так (остальные игнорируйте):
Chip: "ATtiny420" (либо другой соответствующий)
Clock: "20 MHz internal"
Далее загрузите программу через программатор UPDI. Рекомендуется использовать плату USB to Serial, например, FTDI Basic от SparkFun, подключённую через резистор 4.7кОм:
Установите опцию Programmer на «SerialUPDI with 4.7k resistor or diode (230400 baud)».
Ресурсы
- Крохотная библиотека TFT с демо-программой лежит здесь: Tiny TFT Graphics Library 2 Program.
- Либо можете взять её отсюда.
Автор: Дмитрий Брайт