[Перевод] Крошечная библиотека TFT для микроконтроллеров ATtiny

vtfbugk2rqfp0931ccwckh6ei1o.png

Библиотека TFT на ATtiny85, управляющая цветным дисплеем Adafruit 2.0» 320×240

В статье речь пойдёт о маленькой графической библиотеке, предназначенной специально для микроконтроллеров 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<


Так что, если при запуске все контакты установлены на состояние «отключён», то процедуры дисплея смогут просто переключать нужные из них, активируя или отключая.

На новых ATtiny 0- и 1-серии используется равнозначный регистр OUTTGL. Например:

PORTA.OUTTGL = 1<


Отличия между каждым семейством процессоров обрабатываются константами, определяющими назначения контактов, и макросом препроцессинга, определяющим манипуляции с битами. Если вы примените приведённые ниже схемы, то вам не потребуется что-либо менять, только указать, какой используется дисплей.

Я дополнительно оптимизировал процедуру ClearDisplay(), когда осознал, что нет нужды продолжать и устанавливать бит mosi, так как для очистки дисплея он всегда будет нулевым, а значит, процедуре нужно только переключать бит sck нужное число раз. Благодарю Томаса Шерера за поданную идею.

Быстродействие


В таблице ниже отражено отличие в быстродействии при использовании TFT-дисплея 240×240 с ATtiny402 20МГц:
Вся библиотека занимает менее 4КБ, включая набор символов и демо-программы, а значит, вполне уместится на микроконтроллерах с 4КБ флэш-памяти, таких как ATtiny45 и ATtiny402.

Поддерживаемые дисплеи


Эта библиотека будет работать с дисплеями на базе контроллера ST7735, поддерживающего максимальный размер экрана 162×132, либо ST7789 и ILI9340/1, поддерживающих размер 320×240. Она содержит параметры для следующих цветных TFT-дисплеев:
* Эти дисплеи 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. Для этого можно задействовать любые контакты, но они все должны находиться в одном порту. Номера используемых контактов порта необходимо указать в начале листинга библиотеки.

Имейте ввиду, что на разных платах дисплеев контакты обозначаются по-разному:

Не удивляйтесь используемой на некоторых дисплеях маркировке 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:

7b24yq972vhytonvx8sxub44ock.png

Схема подключения цветного 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:

pe9dlcgae20zrxddrx9brhlscxq.png

Схема подключения цветного TFT-дисплея с использованием ATtiny402

При использовании дисплея Adafruit резистор 10кОм можно опустить, так как у них подтягивание происходит на самой плате.

Пример реализации этой схемы с дисплеем Adafruit 320×240 2.2» TFT:

i-g1p0ab9v3rzu_3ztqwr9yvzts.png

Крошечная библиотека TFT на ATtiny402, управляющая цветным TFT-дисплеем Adafruit 2.2» 320×240

Настройка дисплея


Параметры дисплеев определяются семью константами, которые устанавливают размер, смещение относительно области, поддерживаемой драйвером дисплея, инвертирование, степень поворота экрана, а также порядок цветов. Например:

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


Раскомментируйте параметры для используемого дисплея.

По умолчанию параметры задают верную ориентацию — исходя из предположения, что вы используете контакты вдоль верхней части дисплея. Исключением становятся крупные модели, у которых эти контакты расположены вдоль короткой стороны — в этом случае предполагается, что они находятся слева.

Тем не менее изменяя константу rotate, можно настроить поворот экрана по-своему:

ntxtdocfnjn3tevfdpwvjw2as3c.png

Тестовый паттерн 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;
}


Пример:

huvpjcfgpio9jogqns7f9pvg-ky.png

Test Chart на цветном TFT-дисплее 1.14» 240×135 с 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:

_wvhhaga0yn64gcs8rxyxtwdgke.png

Текущая позиция отрисовки хранится в глобальных переменных 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кОм:

_57q_zizjxk9ok9araa4t2jme4o.png

Установите опцию Programmer на «SerialUPDI with 4.7k resistor or diode (230400 baud)».

Ресурсы


xbo4gmrlicdllfwrmtuypqrlcgg.jpeg

© Habrahabr.ru