Перейти к содержанию

TFT-дисплей на ILI9341: подключение по SPI и команды

ILI9341 — контроллер цветных TFT-дисплеев 240 × 320 точек, на нём собраны популярные модули с диагональю 2,4–3,2 дюйма. Разбираем по даташиту, как он подключается по SPI, как устроены форматы цвета и окно записи и какими командами дисплей запускается.

Обновлено Редакция GAW

ILI9341 — однокристальный контроллер и драйвер цветной TFT-панели 240 × 320 точек фирмы Ilitek. В нём есть 720 выходов на столбцы (по три субпикселя на 240 точек), 320 выходов на строки, видеопамять (GRAM) на 172 800 байт — ровно 240 · 320 точек по 18 бит, — генератор, преобразователи напряжения для панели и гамма-коррекция. Изображение до 262 144 цветов принимается по параллельной шине 8, 9, 16 или 18 бит, по RGB-интерфейсу или по SPI. Модули с этим контроллером и диагональю около 2,4–3,2 дюйма — самый распространённый цветной дисплей для Arduino, ESP32 и STM32.

Питание и интерфейсы

ЦепьНапряжениеНазначение
VDDI1,65–3,3 Влогика и уровни интерфейса
VCI2,5–3,3 Ваналоговая часть, из неё встроенные преобразователи делают напряжения панели

Логические входы рассчитаны на уровни VDDI, то есть на 3,3 В и ниже. Рабочая температура — от −40 до 85 °C. Подсветка панели питается отдельно: это светодиоды модуля, а не часть контроллера.

Интерфейс выбирают выводы IM[3:0]; на готовом модуле это сделано при сборке, и чаще всего выбран 4-проводной SPI:

IM[3:0]ИнтерфейсВыводы
01104-проводной SPI, данные по одному выводу в обе стороныSCL, SDA, D/CX, CSX
11104-проводной SPI, отдельные вход и выходSCL, SDI, SDO, D/CX, CSX
0101, 11013-проводной SPI, 9 бит на байтSCL, SDA (SDI, SDO), CSX
0000–0011, 1000–1011параллельная шина 8080: 8, 9, 16 или 18 битD[17:0], WRX, RDX, D/CX, CSX

SPI и вывод D/CX

В 4-проводном режиме контроллер принимает обычные 8-битные байты старшим битом вперёд, а что это за байт, говорит вывод D/CX: низкий уровень — команда, высокий — параметр команды или данные изображения. Данные читаются по нарастающему фронту SCL, а ведущий выставляет следующий бит по спаду — это режим SPI 0.

Минимальный период такта по даташиту — 100 нс при записи и 150 нс при чтении, то есть до 10 МГц на запись и примерно 6,7 МГц на чтение. Передача начинается с низкого уровня на CSX; несколько байтов можно передать в одной посылке, не поднимая CSX. Как выглядит такой обмен по тактам, показывает калькулятор кадра SPI.

Цвет: 16 или 18 бит на точку

Формат точки задаёт команда 3Ah (COLMOD). Младшие три бита параметра выбирают формат для MCU-интерфейса и SPI:

Параметр 3AhБит на точкуЦветовБайт на точку по SPI
55h16 (R5 G6 B5)65 5362
66h (после сброса)18 (R6 G6 B6)262 1443

Почти всегда выбирают 16 бит: точка занимает два байта, а кадр — 240 · 320 · 2 = 153 600 байт вместо 230 400. Цвет в формате RGB565 упаковывается в 16-битное число (R >> 3) << 11 | (G >> 2) << 5 | (B >> 3) и передаётся старшим байтом вперёд.

Окно записи

Изображение пишется в прямоугольное окно видеопамяти тремя командами:

  1. 2Ah (Column Address Set) — начальный и конечный столбец, по два байта каждый: SC[15:8] SC[7:0] EC[15:8] EC[7:0]. После сброса окно на всю ширину: 0–239 (00EFh).
  2. 2Bh (Page Address Set) — начальная и конечная строка, тоже по два байта. После сброса — 0–319 (013Fh).
  3. 2Ch (Memory Write) — после неё идут данные точек подряд; контроллер сам переходит на следующую точку окна и следующую строку.

Залить прямоугольник одним цветом — значит задать окно и передать нужное число одинаковых точек. Перерисовывать только изменившиеся области намного быстрее, чем весь экран: полный кадр на 10 МГц идёт около 0,12 с.

Поворот и порядок цветов: команда 36h

Параметр команды 36h (MADCTL) задаёт, в каком порядке точки из интерфейса ложатся в видеопамять:

БитИмяЧто делает
D7MYобратный порядок строк — отражение по вертикали
D6MXобратный порядок столбцов — отражение по горизонтали
D5MVстроки и столбцы меняются местами — альбомная ориентация 320 × 240
D4MLнаправление обновления панели по вертикали
D3BGRпорядок субпикселей RGB или BGR, по светофильтру панели
D2MHнаправление обновления панели по горизонтали

Сочетания MV, MX и MY дают четыре поворота экрана; при MV = 1 границы окна в 2Ah и 2Bh меняются местами — по столбцам до 319, по строкам до 239. Если красный и синий на экране перепутаны, нужен противоположный бит BGR.

Инициализация

Минимальная последовательность по ограничениям из описаний команд:

  1. Аппаратный сброс: низкий уровень на RESX не короче 10 мкс, затем подождать 5 мс.
  2. 01h — программный сброс, подождать 5 мс.
  3. 11h — выход из спящего режима: следующую команду можно посылать через 5 мс, а полностью контроллер выходит из сна за 120 мс.
  4. 3Ah, 55h — 16 бит на точку.
  5. 36h, параметр — ориентация и порядок RGB/BGR.
  6. 29h — включить изображение.

Производители модулей добавляют к этому настройки питания, гаммы и частоты кадров (команды C0h–C7h, E0h, E1h и другие) под свою панель; их значения берут из документации модуля или из готовой библиотеки.

Пример для Arduino по SPI

Без библиотек: инициализация и заливка экрана красным. D/CX, CS и RESET — на свободных выводах, SCL и SDA — на выводах аппаратного SPI. Модуль должен работать с уровнями платы: у Arduino Uno это 5 В, поэтому нужен модуль с согласованием уровней или преобразователь. Библиотека SPI ядра Arduino AVR выбирает самую быструю частоту не выше заданной, и на Uno с 16 МГц вместо 10 МГц получится 8 МГц — половина тактовой частоты.

#include <SPI.h>

const uint8_t PIN_CS = 10, PIN_DC = 9, PIN_RST = 8;
const SPISettings TFT(10000000, MSBFIRST, SPI_MODE0);  // до 10 МГц по даташиту

void command(uint8_t c) {
  digitalWrite(PIN_DC, LOW);
  SPI.transfer(c);
  digitalWrite(PIN_DC, HIGH);  // дальше параметры и данные
}

void setup() {
  pinMode(PIN_CS, OUTPUT);
  pinMode(PIN_DC, OUTPUT);
  pinMode(PIN_RST, OUTPUT);
  SPI.begin();

  digitalWrite(PIN_RST, LOW);  delayMicroseconds(20);   // сброс не короче 10 мкс
  digitalWrite(PIN_RST, HIGH); delay(5);

  SPI.beginTransaction(TFT);
  digitalWrite(PIN_CS, LOW);
  command(0x01); delay(5);     // программный сброс
  command(0x11); delay(120);   // выход из сна
  command(0x3A); SPI.transfer(0x55);  // 16 бит на точку
  command(0x36); SPI.transfer(0x08);  // BGR; ориентация по умолчанию
  command(0x29);               // включить изображение

  command(0x2A); SPI.transfer16(0); SPI.transfer16(239);  // столбцы 0–239
  command(0x2B); SPI.transfer16(0); SPI.transfer16(319);  // строки 0–319
  command(0x2C);
  for (uint32_t i = 0; i < 240UL * 320; i++) SPI.transfer16(0xF800);  // красный в RGB565
  digitalWrite(PIN_CS, HIGH);
  SPI.endTransaction();
}

void loop() {}

Для текста, шрифтов и графики используют библиотеки — например, Adafruit ILI9341 или TFT_eSPI для ESP32 и STM32: они берут на себя инициализацию модуля и рисуют через окно записи.

Частые вопросы

С какой частотой SPI работает ILI9341?

По даташиту минимальный период такта 4-проводного SPI при записи — 100 нс, то есть до 10 МГц, при чтении — 150 нс, около 6,7 МГц. Полный кадр 240 × 320 в 16-битном цвете — 153 600 байт, на 10 МГц он передаётся примерно за 0,12 с. Поэтому быстрые программы перерисовывают не весь экран, а только изменившиеся области через окно записи.

Зачем ILI9341 вывод D/CX?

В 4-проводном SPI он говорит контроллеру, что передаётся: низкий уровень — байт команды, высокий — параметр или данные. Без него, в 3-проводном режиме, к каждому байту спереди добавляется девятый бит D/CX, что неудобно для аппаратного SPI микроконтроллеров, поэтому модули почти всегда работают в 4-проводном режиме.

Как повернуть изображение на ILI9341?

Командой 36h (MADCTL): бит MV меняет местами строки и столбцы, то есть даёт альбомную ориентацию 320 × 240, а биты MX и MY отражают изображение по горизонтали и вертикали. Сочетания этих трёх битов дают все четыре поворота. Бит BGR в той же команде переставляет красный и синий — его включают, если цвета на экране перепутаны.

Как проверить, что на модуле действительно ILI9341?

Прочитать идентификатор командой D3h (Read ID4): после фиктивного байта контроллер возвращает версию и номер модели 93h, 41h. Для чтения нужен вывод SDO (MISO) на модуле и, по даташиту, высокий уровень на выводе EXTC контроллера. Если ответ другой, на модуле может стоять совместимый, но иной контроллер с другой инициализацией.

Источники

  1. Ilitek. ILI9341 a-Si TFT LCD Single Chip Driver 240RGBx320 Resolution and 262K color, Specification V1.10 (ILI9341_DS_V1.10) — разд. 1–2 — разрешение, GRAM 172 800 байт, интерфейсы, питание VDDI 1,65–3,3 В и VCI 2,5–3,3 В, −40…85 °C; табл. выбора интерфейса по IM[3:0]; разд. 7.6.2 — форматы данных 4-проводного SPI (2 байта на точку в 16-битном режиме, 3 байта в 18-битном); описания команд 01h, 11h, 29h, 2Ah, 2Bh, 2Ch, 36h, 3Ah, D3h с ограничениями по времени; разд. 15.4 — импульс сброса не короче 10 мкс; разд. 18.3.4 — такт SPI при записи от 100 нс, при чтении от 150 нс
  2. Arduino. ArduinoCore-avr, libraries/SPI/src/SPI.h (коммит 11b9130) — SPISettings выбирает самую быструю частоту не выше заданной из F_CPU/2 … F_CPU/128; transfer16 при MSBFIRST передаёт старший байт первым

Нашли ошибку?