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

OLED-дисплей на SSD1306: подключение и команды

SSD1306 — контроллер монохромных OLED-дисплеев 128 × 64 точки, на нём собрано большинство маленьких дисплеев с интерфейсом I²C и SPI. Разбираем по даташиту, как он питается, как устроены адрес и управляющий байт I²C, как картинка лежит в памяти и какими командами дисплей включается.

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

SSD1306 — микросхема фирмы Solomon Systech, которая одна управляет монохромной OLED-панелью размером до 128 × 64 точки: в ней есть драйверы 128 сегментов и 64 общих выводов, видеопамять на 128 × 64 бит, генератор и регулятор яркости на 256 ступеней. Микроконтроллер передаёт ей команды и изображение по одному из интерфейсов: параллельному 8-битному (6800 или 8080), SPI (3- или 4-проводному) или I²C. Большинство дешёвых OLED-модулей с диагональю около дюйма построены именно на нём.

Питание

ЦепьНапряжениеНазначение
VDD1,65–3,3 Влогика контроллера
VCC7–15 Впитание драйверов панели
VBAT3,3–4,2 Ввход встроенного умножителя напряжения, если VCC не подаётся снаружи

Напряжение 7–15 В для свечения OLED-панели можно подать снаружи, а можно получить внутри: встроенный умножитель на переключаемых конденсаторах с двумя внешними конденсаторами делает около 7,5 В из VBAT. Его включают командой 8Dh, 14h перед командой включения дисплея AFh — без этого панель модуля без внешнего источника VCC не загорится. Рабочая температура контроллера — от −40 до 85 °C.

Даташит задаёт порядок включения: сначала VDD, затем импульс сброса на выводе RES# длительностью не меньше 3 мкс, затем VCC и только после этого команда AFh; сегменты и общие выводы начинают работать через 100 мс. При выключении — команда AEh, затем снять VCC и примерно через 100 мс — VDD.

Интерфейс I²C

По I²C контроллер работает только на запись и отвечает на 7-битный адрес 011110 + SA0:

SA0Адрес (7 бит)С битом записи (8 бит)
00x3C0x78
10x3D0x7A

В режиме I²C роль SA0 выполняет вывод D/C#. Минимальный период тактового сигнала по даташиту — 2,5 мкс, то есть частота шины до 400 кГц. Подтягивающие резисторы на SDA и SCL нужны, как на любой шине I²C; их номиналы для своей длины линий можно подобрать в калькуляторе подтяжек I²C.

После адреса идёт управляющий байт — бит Co, бит D/C# и шесть нулей:

Управляющий байтCoD/C#Что идёт дальше
0x0000поток команд до конца передачи
0x4001поток данных в видеопамять до конца передачи
0x8010один байт команды, затем снова управляющий байт
0xC011один байт данных, затем снова управляющий байт

Поэтому типичная транзакция выглядит так: START, адрес 0x3C с битом записи, 0x00, несколько байтов команд, STOP. Для записи изображения — START, адрес, 0x40, байты картинки, STOP. Как такая транзакция выглядит по битам, можно посмотреть в конструкторе транзакции I²C.

Интерфейс SPI

В 4-проводном режиме, кроме SCLK, SDIN (MOSI) и CS#, используется отдельный вывод D/C#: низкий уровень — байт команды, высокий — байт данных в видеопамять. В 3-проводном режиме вывод D/C# не используется: перед каждым байтом передаётся девятый бит D/C#, первым. По SPI, как и по I²C, контроллер работает только на запись. Минимальный период такта SPI — 100 нс, то есть до 10 МГц. Интерфейс выбирается выводами BS0–BS2 контроллера; на готовом модуле это уже сделано, и он продаётся как «I²C» или «SPI».

Видеопамять: страницы по 8 строк

Видеопамять (GDDRAM) на 128 × 64 бит разделена на восемь страниц PAGE0–PAGE7 по 8 строк. Каждый байт данных — это вертикальный столбик из восьми точек одной страницы: бит D0 — верхняя точка, D7 — нижняя. Строка в 128 байт заполняет одну страницу во всю ширину, весь экран — 8 · 128 = 1024 байта.

После записи байта указатель столбца сдвигается сам. Как он ведёт себя дальше, задаёт команда 20h — режим адресации:

Режим20h +После последнего столбца
страничный (после сброса)02hуказатель возвращается в начало той же страницы
горизонтальный00hпереход на следующую страницу, удобно писать весь экран одним потоком
вертикальный01hпереход к следующему столбцу после каждой страницы

В горизонтальном и вертикальном режимах окно записи задают команды 21h (начальный и конечный столбец, 0–127) и 22h (начальная и конечная страница, 0–7). В страничном режиме страницу выбирают командами B0h–B7h, а столбец — двумя командами: 00h–0Fh (младшие 4 бита адреса) и 10h–1Fh (старшие).

Основные команды

КомандаБайтыЧто делаетПосле сброса
Дисплей выкл./вкл.AEh / AFhспящий режим или нормальная работавыключен
Контраст81h, 00–FFhяркость, 256 ступеней7Fh
Изображение из памяти / всё включеноA4h / A5hA5h зажигает все точки, игнорируя памятьA4h
Нормальное / инверсноеA6h / A7hинверсия цветовA6h
Коэффициент мультиплексированияA8h, 0Fh–3Fhчисло строк минус 1: 3Fh для 64 строк63
Смещение изображенияD3h, 00–3Fhвертикальный сдвиг по строкам00h
Начальная строка40h–7Fhс какой строки памяти начинается экран40h
Отражение по горизонталиA0h / A1hстолбец 0 на SEG0 или на SEG127A0h
Направление развёрткиC0h / C8hотражение по вертикалиC0h
Конфигурация выводов COMDAh, 02h или 12hпоследовательная или альтернативная разводка панели12h
Тактовый генераторD5h, 80hделитель и частота генератора80h
Умножитель напряжения8Dh, 14h / 10hвключить или выключить встроенный умножительвыключен

Поворот изображения на 180° делают парой команд A1h и C8h. Есть и команды прокрутки (26h, 27h, 29h, 2Ah, 2Eh, 2Fh, A3h): контроллер сдвигает изображение сам, без участия микроконтроллера.

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

Пример последовательности из application note Solomon Systech:

A8h 3Fh   коэффициент мультиплексирования: 64 строки
D3h 00h   без смещения
40h       начальная строка 0
A0h/A1h   отражение по горизонтали — по ориентации панели
C0h/C8h   направление развёртки
DAh 02h   конфигурация выводов COM (зависит от панели)
81h 7Fh   контраст
A4h       изображение из памяти
A6h       нормальное изображение
D5h 80h   тактовый генератор
8Dh 14h   включить умножитель напряжения
AFh       включить дисплей

Значение для DAh зависит от того, как выводы COM разведены в конкретной панели. Если изображение выводится через строку или растянуто по вертикали, попробуйте другое значение: 02h — последовательная конфигурация, 12h — альтернативная (значение после сброса).

Подключение к Arduino по I²C

Минимальный пример без библиотек: инициализация и заливка экрана узором. Команды отправляются с управляющим байтом 0x00, изображение — с 0x40 небольшими порциями.

#include <Wire.h>

const uint8_t OLED = 0x3C;  // 0x3D, если SA0 = 1

void commands(const uint8_t *list, uint8_t n) {
  Wire.beginTransmission(OLED);
  Wire.write(0x00);                 // дальше только команды
  for (uint8_t i = 0; i < n; i++) Wire.write(list[i]);
  Wire.endTransmission();
}

void setup() {
  Wire.begin();
  Wire.setClock(400000);            // до 400 кГц по даташиту
  const uint8_t init[] = {
    0xAE, 0xA8, 0x3F, 0xD3, 0x00, 0x40, 0xA1, 0xC8,
    0xDA, 0x12, 0x81, 0x7F, 0xA4, 0xA6, 0xD5, 0x80,
    0x8D, 0x14, 0x20, 0x00, 0xAF
  };
  commands(init, sizeof init);

  const uint8_t window[] = { 0x21, 0, 127, 0x22, 0, 7 };  // весь экран
  commands(window, sizeof window);
  for (uint16_t i = 0; i < 1024; i += 16) {
    Wire.beginTransmission(OLED);
    Wire.write(0x40);               // дальше данные видеопамяти
    for (uint8_t j = 0; j < 16; j++) Wire.write((i + j) & 1 ? 0x55 : 0xAA);
    Wire.endTransmission();
  }
}

void loop() {}

Для текста и графики удобнее готовые библиотеки, например Adafruit SSD1306 или U8g2: они держат копию экрана в памяти микроконтроллера (1024 байта) и отправляют её целиком или по страницам.

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

Какой адрес I²C у дисплея SSD1306?

0x3C или 0x3D. Семибитный адрес контроллера — 011110x, где младший бит задаёт вывод SA0: при низком уровне получается 0x3C, при высоком — 0x3D. На модулях этот вывод обычно уже подключён перемычкой или резистором. В некоторых программах адрес записывают вместе с битом записи как 8-битный — тогда это 0x78 и 0x7A.

С какой частотой работает I²C у SSD1306?

Минимальный период такта по даташиту — 2,5 мкс, то есть до 400 кГц (Fast-mode). По SPI контроллер принимает данные с периодом такта от 100 нс — до 10 МГц, поэтому SPI заметно быстрее при частом обновлении всего экрана: кадр 128 × 64 — это 1024 байта.

Можно ли подключить SSD1306 к Arduino на 5 В?

Сам контроллер питается от VDD 1,65–3,3 В, и его логические входы рассчитаны на этот уровень. Готовые модули часто питаются и от 5 В, но что именно стоит на плате модуля — стабилизатор, подтягивающие резисторы, согласование уровней, — зависит от производителя. Проверьте схему модуля; если стабилизатора и согласования нет, подключайте к 3,3 В.

Почему OLED-дисплей ничего не показывает после инициализации?

Частые причины: не тот адрес I²C (0x3C вместо 0x3D или наоборот), не включён встроенный умножитель напряжения (команда 8Dh с параметром 14h перед AFh — без него у модулей без внешнего VCC панель не светится), не отправлена команда включения AFh или память дисплея заполнена нулями. Если изображение есть, но через строку или растянуто, не подходит настройка выводов COM — команда DAh.

Источники

  1. Solomon Systech. SSD1306: 128 x 64 Dot Matrix OLED/PLED Segment/Common Driver with Controller, Rev 1.1, апрель 2008 (Advance Information; копия из библиотеки контроллеров Crystalfontz) — разд. 2 — питание VDD 1,65–3,3 В и VCC 7–15 В, интерфейсы, 256 ступеней контраста, −40…85 °C; разд. 8.1 — выбор интерфейса, 8.1.5 — I²C: адрес 0111100 или 0111101 по выводу SA0, управляющий байт Co и D/C#; 8.7 — GDDRAM, восемь страниц по 128 байт; 8.9 — порядок включения и выключения; табл. 9-1 — команды и значения после сброса; табл. 13-4 и 13-6 — время такта SPI 100 нс и I²C 2,5 мкс
  2. Solomon Systech. SSD1306 Application Note: Charge Pump Regulator, Rev 0.4, январь 2009 (в том же файле) — встроенный умножитель напряжения: VCC 7,5 В от VBAT 3,3–4,2 В с двумя внешними конденсаторами, команда 8Dh 14h, пример последовательности инициализации

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