Схема включения oled display bl12864g

Обновлено: 07.07.2024

Добрый день, друзья!
Эта статья открывает цикл, посвящённый средствам визуального отображения информации.
Нами будут рассмотрены модули, в состав которых входят следующие дисплеи и управляющие контроллеры:
1. OLED дисплей на 0.96 дюйма (128×64 пикселей), контроллер SSD1306.
2. TFT дисплей на 1.8 дюйма (128×160 пикселей), контроллер ST7735.
3. TFT дисплей на 2.8 дюйма (240×320 пикселей), контроллер ILI9341.
4. TFT дисплей на 3.5 дюйма (320×480 пикселей), контроллер ILI9481.

Весь материал разбит на пять частей, в четырёх из которых изложена информация по модулям (технические параметры, подключение и инициализация, вывод на дисплей базового графического элемента — точки), а пятая содержит единую графическую библиотеку для описанных дисплеев.

Сама идея единой библиотеки и большинство приёмов её реализации позаимствованы из библиотеки Adafruit_GFX, а также отдельных работ её авторов — Лимор Фрид (Limor Fried) и Кевина Таунсенда (Kevin Townsend).
Моя скромная заслуга заключается в переносе кода с С++ на С, написании отдельных функций и выборочном переводе даташитов с целью более детального освещения особенностей работы модулей.

OLED дисплей на 0.96 дюйма (128×64 пикселей), контроллер SSD1306

Содержание / Contents

↑ Основные характеристики OLED-модуля

• Размеры: 27мм х 27мм х 4.1 мм.
• Разрешение: 128х64 пикселя.
• Угол обзора: >160°.
• Цветность: чёрно-белый. В реальности «белый» пиксель может светиться голубым или, как на рисунке выше, жёлтым цветом, но это, как вы понимаете, не делает дисплей цветным.
• Энергопотребление: 0.08Вт при включённом дисплее.
• Рабочая температура: от – 30 до 70 градусов по Цельсию.
• Напряжение питания: 3В – 5В.
• Протокол обмена данными: I2c или SPI.

↑ Назначение выводов

Для модуля с протоколом I2c:
• SCL, SDA – линии протокола. Подтягивающие резисторы уже встроены в модуль, поэтому соединение с микроконтроллером (МК) – напрямую.
• VCC, GND – линии питания.

Для модуля с протоколом SPI:
• SCK, MOSI – линии протокола. Тут каждый производитель старался, как мог, поэтому эти выводы могут иметь и другие названия – DO/DI, CLK/DIN и даже, как ни странно, SCL/SDA. Вывод MISO отсутствует по причине, о которой будет сказано ниже.
• CS – выбор чипа, аналог SS. Активный уровень – низкий.
• DC – выбор типа записываемого в SSD1306 слова – данные или команда.
• RES – аппаратный сброс. В прилагаемой библиотеке прописана функция программного сброса, так что, если вы ограничены в выводах микроконтроллера, можно соединить этот вывод с аналогичным пином МК либо подтянуть его к питанию.
• VCC, GND – линии питания.

↑ Особенности протоколов обмена данными

Протокол SPI – стандартный, за исключением двух нюансов:
1. Чтение из модуля невозможно по причине отсутствия вывода MISO. Причина, по которой производители пошли на это, заключается, как мне кажется, в следующем. Единственная информация, которую можно извлечь из SSD1306 – включен дисплей или нет. Данные, согласитесь, не настолько бесценные, чтобы тратиться на организацию целой линии обмена.
2. В зависимости от состояния вывода DC записываемый в модуль байт будет интерпретироваться как команда (состояние «0») или данные (состояние «1»).

Функция записи команды, с учётом макроопределений, будет выглядеть так:

А байт данных записывается следующим образом:

Для выяснения особенностей протокола I2c обратимся к следующему рисунку из прилагаемого даташита SSD1306:


Как видите, запись в модуль происходит как минимум тремя байтами.
Первый байт – сдвинутый на один бит влево адрес (0х3С) с добавленным битом выбора типа операции (чтение или запись). В интернете упоминается, что адрес SSD1306 может быть и 0x3D, поэтому, если ваш модуль не запускается, возможно, стоит попробовать поменять в программе его адрес.
Следующим идёт контрольный байт, шестой бит которого (D/C) определяет тип записываемого слова: команда или данные. По сути, этот бит – программный аналог вывода DC в модулях с протоколом SPI.
Третий байт – непосредственно команда или данные.
Таким образом, функции обмена обретают следующий вид:

Функция чтения для протокола I2c в библиотеке не прописана по соображениям, приведённым выше для объяснения отсутствия вывода MISO.

↑ Система команд

Полный перевод таблиц команд выложен в архиве. Все команды условно разделены на шесть групп:
1. Базовые команды.
2. Команды прокрутки.
3. Команды адресации.
4. Команды аппаратной настройки.
5. Команды тайминга и схемы управления.
6. Команды ёмкостного умножителя.

Команды могут быть как однобайтными так и многобайтными, причем второй и последующие байты записываются как отдельные команды:

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

0хAE/0хAF – выключение/включение дисплея. Как только модуль подключается к питанию, SSD1306 готов принимать и исполнять команды, в том числе выводить изображение на дисплей. Однако само изображение вы не увидите, поскольку по сбросу/подаче питания выполняется команда 0хAE, т.е. дисплей выключен. Поэтому в функции инициализации модуля необходимо, среди прочего, прописать команду 0хAF.

0х81 – двухбайтная команда установки контрастности, значение которой определяется вторым байтом в диапазоне от 1 до 256.

0х20 – установка режима адресации. Эта команда определяет порядок вывода данных на дисплей: горизонтальный, вертикальный или постраничный. Более подробно об этом - чуть позже, а пока лишь скажу, что мы будем использовать режим горизонтальной адресации.

0х21/0х22 – установка адресов столбца/страницы. В более понятном выражении эти команды позволяют задать координаты пикселя, который вы хотите активировать.

А0/А1 - с точки зрения изображения на дисплее эти команды ответственны за отражение по горизонтали.



C0/C8 – определение порядка сканирования COM-выводов дисплея. Если проще – отражение по вертикали.



Сочетание двух последних пар команд позволяет регулировать ориентацию изображения.


0x8D - включение/выключение ёмкостного умножителя. При включении дисплея без использования этой команды, изображение будет едва видимо, даже, если командой 0х81 выставить максимальное значение контрастности. Дело в том, что рабочее напряжение дисплея – от 7В до 15В. Поскольку подаваемого на выводы модуля напряжения (3В – 5В) не достаточно, в его состав включён емкостной умножитель, повышающий уровень напряжения до необходимого. По сбросу/подаче питания этот узел отключен, поэтому второй обязательной командой в функции инициализации модуля должна быть, помимо 0хAF, команда включения ёмкостного умножителя.

↑ Вывод изображения на дисплей

Собственно, как только вывод DC (протокол SPI) или бит D/C контрольного байта (протокол I2c) выставлены в 1, записываемый в модуль байт будет выводиться на дисплей. Если быть более точным, мы с помощью функции ssd1306_data() отправляем байт в ОЗУ (GDDRAM), входящего в состав SSD1306, а далее данные автоматически выводятся на дисплей.

Давайте разберёмся, как именно происходит этот процесс.
В соответствии с количеством пикселей на дисплее ОЗУ содержит 128х64 бит, разделенных на восемь страниц по 128х8 бит или 128 байт в каждой. В случае настроек по сбросу/подаче питания данные из ОЗУ выводятся на дисплей в следующем порядке:

Визуализация для микроконтроллера. Часть 1. OLED дисплей 0.96" (128х64) на SSD1306


А комбинация команд 0хА1 и 0хС8 меняет порядок вывода таким образом:



Каждому из 128 байтов в странице ОЗУ соответствует вертикальная черта шириной 1 и высотой 8 пикселей в области дисплея, ограниченной на рисунке прямоугольником с соответствующей надписью. Отсчёт адреса столбцов ведётся слева-направо, а порядок расположения битов байта – сверху-вниз. Более наглядно сказанное поясняет рисунок из даташита:


Здесь выполнены следующие действия: соответствующими командами заданы столбец 4 (SEG4) и страница 2 (PAGE2), а затем с записано число 01000001 (65 – в десятичном исчислении). Часть кода, обеспечивающая этот процесс, выглядит для режимов горизонтальной или вертикальной адресации так:

По исполнению вы получите два светящихся пикселя в заданном месте дисплея:


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

В состав SSD1306 входят счётчики адресов столбцов и страниц, текущее значение которых и определяет адрес в ОЗУ (читай – координаты на дисплее), по которому будет записан байт данных. Каждое обращение к GDDRAM приводит к автоматическому инкременту того или иного счётчика, а заданные нами начальный и конечный адреса определяют, начиная с какого и до какого значения будет происходить счёт.

Выбирая же режим адресации, мы определяем порядок работы и взаимодействия счётчиков.
• Для режима горизонтальной адресации при каждом исполнении функции ssd1306_data() увеличивается на единицу значение счётчика адреса столбца. По достижении заданного конечного значения счётчик адреса столбца сбрасывается в начальное значение, а счётчик адреса страницы увеличивается на единицу. После достижения счётчиком адреса страницы заданного конечного значения оба счётчика сбросятся в начальные значения и процесс пойдёт по второму кругу.

• Для режима вертикальной адресации, наоборот, увеличивается на 1 значение счётчика адреса страницы. После его заполнения следует сброс в начальное значение, инкремент счётчика адреса столбца и так далее.

• Для режима постраничной адресации предусмотрен только счётчик адреса столбца, то есть все действия происходят в пределах одной выбранной страницы. Кроме того, в этом режиме не предусмотрен конечный адрес столбца, так что рост значения счётчика продолжается до значения 127 (конец страницы), а затем, в отличие от двух других режимов, не сбрасывается в начальное значение, а обнуляется.

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




Перейдём к прорисовке базового элемента – точки. Как вы поняли, конструктивные особенности SSD1306 не дают нам возможность задавать отдельную строку на дисплее, а лишь страницу. Во-первых, из-за этого мы не можем объединить единой библиотекой этот модуль с другими, которые оперируют координатами пикселя - столбец/строка (или – х/у). Во-вторых, это – просто неудобно и непривычно.
Используем следующие конструкции для определения из координаты «у» номера страницы:

Тогда вывести точку в нужное место дисплея можно так:

На этом статью можно было бы считать завершённой, если бы не одно «но» - мы не можем поменять состояние одного пикселя, не затронув остальные семь, связанные с ним. Используя функцию draw_pixel() в приведённом виде мы будем гасить на дисплее 7 ни в чём не повинных точек.

Чтобы этого не происходило, необходимо не только каким-то образом изменить функцию, но и, до вхождения в неё, знать состояние пикселей – 0 или 1. В масштабе всего дисплея мы должны в любой момент знать текущее состояние всех 128х64 пикселей или 128х8 байт памяти. Поскольку извлечь эту информацию из SSD1306, как вы помните, невозможно, придётся создать массив соответствующей размерности.

В итоге прорисовку точки будут обеспечивать две функции:

↑ Структура и содержание библиотеки SSD1306

Библиотека состоит из 8 файлов. Приведу их краткое содержание:
1. main.c – подключает необходимые для работы библиотеки, инициализирует модуль и выводит на дисплей изображение. Какое именно, вы узнаете, запустив программу.
2. main.h – выбор протокола обмена (SPI или I2c) и типа сброса (программный или аппаратный). Библиотека пригодна к использованию для модулей с обоими вариантами протокола и сброса, поэтому для выбора подходящих вам параметров раскомментируйте соответствующие строки в этом файле.
3. i2c.c – содержит функции программного протокола I2c. Обычно я пользуюсь аппаратным вариантом. Но, хотелось, чтобы библиотека была полезна как можно большему кругу людей, поэтому я воспользовался кодом из этой статьи Avinash Gupta . Вы можете заменить содержимое этого файла тем кодом, которому больше доверяете и обычно используете, обеспечив лишь соответствие названий функций.
4. i2c.h – назначение выводов МК, участвующих в протоколе I2c.
5. spi.c – функции программного SPI. Так же, как и в случае с I2c, можете заменить их на свои.
6. spi.h – назначение выводом МК, к которым подключается модуль с одноимённым протоколом обмена.
7. ssd1306.с – функции, непосредственно обеспечивающие работу модуля. Кроме тех, что уже упомянуты в статье, здесь вы найдёте функции инициализации, аппаратного и программного сброса, полной очистки дисплея, выбора ориентации изображения на экране, а также, для желающих организовать бегущую строку, функции прокрутки.
8. ssd1306.h – определение параметров дисплея (цвета, размеры), макроопределения всех используемых команд контроллера. Здесь же объявлен массив buffer[], который развёрнут по причине, указанной в п.1.

↑ Файлы

Пожалуй, на этом всё, конец первой части.
Продолжение следует!

Обычно для вывода информации сигнального дисплея на HD44780 более чем достаточно. Но иногда нужно нарисовать картинку, график или хочется сделать красиво, с модными менюшками. Тут на помощь приходят графические дисплеи. Одним из самых простых и доступных является дисплей на контроллере KS0107 или аналоге. Например, WG12864A от Winstar. Сам дисплей вполне свободно достается, имеет довольно большой размер (диагональ около 80мм) и разрешение 128х64 пикселя. Монохромный. Цена вопроса 400-500р.


Итак, если взять тот, что у меня WG12864A-TGH-VNW то у него следующая распиновка:



К контроллеру (ATMega16 на Pinboard) я подключил все следующим образом.

Данные полностью легли на PORTA, а управление на PORTB. В качестве резистора подстройки контраста я взял многооборотный переменник, что так кстати стоит рядом для подобных случаев. Питание подсветки взял с колодки от дисплеяя. Благо там все уже готово, даже управление от транзистора есть :) Правда я ее просто включил.


Двое из ларца, одинаковых с лица. Адресация
Контроллер CS0107 он может организовать матрицу только 64х64. А у нас в дисплее вдвое большая 128х64. Значит стоят два контроллера. Один отвечает за правую половину экрана, другой за левую.
Он представляет собой этакую микросхему памяти, где все введенные данные отображаются на дисплее. Каждый бит это точка. Кстати, для отладки удобно юзать, выгружая туда разные данные, а потом разглядывая этот дамп). Карта дисплея выглядит так:

Байты укладываются в два контроллера страницами по 64 байта. Всего 8 страниц на контроллер.

Протокол обмена
Тут все просто, без каких либо изысков. Выставляем на линиях RW, DI что мы хотим сделать, линиями CS1 и CS2 выставляем к кому обращаемся. На шину данных выдаем нужное число и поднимаем-опускаем линию строба. Опа! Впрочем, есть одна тонкость. Для чтения данных строб нужно дернуть дважды, т.к. предварительно данные должны попасть в регистр-защелку. Для чтения же флага состояния такой изврат не нужен. Вот примеры временных диаграм для разных режимов.

И запись. Причем запись, в отличии от чтения, можно делать сразу в оба контроллера. Конечно одновременно писать данные в контроллер смысла имеет мало, разве что захочишь двойную картику получить :) А вот команды обычно пишут срзау в оба.

Временные диаграммы, т.е. сдвиг фронтов между собой по времени может быть разным у разных контроллеров. Где то быстрей, где то медленней. Но в целом 1мкс обычно хватает. В реале обычно меньше. Лучше поглядеть в даташите на конкретный контроллер (не дисплей, в ДШ на дисплей обычно редко есть описание самого контроллера). Там обычно есть таблица вида:


Система команд.
Она тут простейшая.

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

Надо после сброса задать начальные координаты (адрес точки и страница), значение скролинга (обычно 0) и включить отображение. При включении на дисплее может быть мусор. Поэтому отображение обычно включают после очистки видеопамяти.

У меня ициализация, по командам, выглядит так:

Ну и потом еще заливка сразу в оба контроллера.

Код
Итак, приступим к коду. Чтобы было наглядней я все операции с ногами расписал в виде макросов. Заодно будет гораздо проще все перенести на другую архитектуру. Просто написав другие макросы, не правя сам код :)
Весь код можно поглядеть в нашей кодосвалке:
lcd_wg128.h
lcd_wg128.c

Покажу тут лишь характерные моменты работы с дисплеем.

Записью команд и данных занимаются следующие функции:

Чтение слова состояния делать не стал. Т.к. дисплей работает весьма шустро, что на круг ожидания можно не уходить, а просто подождать несколько тактов. Собственно этих трех функций уже достаточно для работы :) Остальное все свистоперделки и удобства.

Вроде заливки экрана:

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

// Процедура установки пикселя. Т.к. пиксель часть байта, то надо сначала вычислить // Контроллер, потом страницу и нужный байт. Считать этот байт. Изменить в нем только один, // нужный, бит и вернуть его на место. // На входе координаты и режим обработки пикселя (вкл, выкл, переключение) void PIXEL(u08 x,u08 y,u08 mode) < u08 CSS, row, col, byte; u08 res,read; if(y>63) // Проверяем в каком контроллере искомый пиксель < CSS = 1<<CS2; // Если У больше 63 значит во втором. Выставляем 2й col = y-64; // И отнимаем смещение, чтобы не мешалось. >else < CSS = 1<<CS1; // Иначе контроллер у нас первый. col = y; // А смещения нет. >row = x>>3; // Делим Х на 8, чтобы получить номер страницы. byte = 1<<x%8; // А остаток от деления даст нам искомый бит, который мы задвигаем // и получаем нужную нам битмаску для модификации байта. SET_ADDR(row,col,CSS); // выставляем адрес read = LCD_RD_DATA(CSS); // Читаем данные (адрес при этом ++ аппаратно). switch(mode) // В зависимости от режима < case 0: // Clear < res = read &

byte; // Накладываем сбрасывающую (NOT) маску break; > case 1: // Invert < res = read ^ byte; // Накладываем инвертирующую (ХОR) маску break; >default: // Set < res = read | byte; // Накладываем устанавливающую (OR) маску break; >> SET_ADDR(row,col,CSS); // Повторно выставляем адрес. Т.к. чтение его исказило. LCD_WR_DATA(res,CSS); // Вгоняем туда результат нашей модификации. >


Но работа с пикселями медленная штука. Это же каждый надо считать, изменить, закинуть обратно. Куча мороки. На обновление всего экрана в попиксельном режиме уйдет прорва времени. Я подсчитывал, при полной загрузке проца только на это, на заливку попиксельно всего экрана уходит чуть ли не треть секунды.

Куда эффективней работать с дисплеем блоками. Т.е. берем и последовательно записываем сразу куски страниц, на глубину в несколько байт. Например, таким образом удобно рисовать текст. Правда при попиксельном выводе, когда текст попадает между страницами получается неудобно, приходится делать вдвое больше работы. Но все равно намного быстрей чем попиксельно. На порядок!

// Запись сразу блока. Удобно для вывода строк или картинок, постранично. // На входе страница Х и колонка У. А также длина блока и адрес откуда брать данные. u08 BLOCK(u08 x,u08 y, u08 len, u16 addr) < u08 CSS,i,col; if(y>63) // Сначала вычисляем нужные нам сегмент (чип) < CSS = 1<<CS2; col = y-64; >else < CSS = 1<<CS1; col = y; >SET_ADDR(x,col,CSS); // Ставим адрес // А дальше в цикле гоним байты. Не забывая увеличивать адрес, чтобы была выборка из // памяти. Счетчик, чтобы не сбиться со счета. И номер колонки, чтобы не вылезти за границы // И вообще понимать где мы находимся. for(i=0;i!=len;i++,addr++,col++) < if(64==col) // Попутно проверяем за границы выхода из сегмента < if(CSS == (1<<CS2)) // Если случилось, и у нас второй сегмент, т.е. конец < // страницы (уже второй в этой строке) return 128; // выходим с кодом ошибки (код больше разрешения экрана) >col=0; // Иначе же обнуляем счетчик колонок. И переключаем банку CSS = 1<<CS2; // Выбрав второй сегмент экрана SET_ADDR(x,col,CSS); // И выставив новый текущий адрес > LCD_WR_DATA(pgm_read_byte(addr),CSS); // Пишем туда данные прям из флеша (таблица символов). > return y+len; // Возвращаем координату увеличиную на размер блока. >

Блочный вывод легко превращается в текстовый вывод. Надо лишь совместить таблицу символов с печаталкой блоков. И гнать данные из флеша напрямую.

// Процедура вывода строки. На входе строка, и координаты. Х в страницах, а У в точках. void LCD_putc(u08 x,u08 y,u08 *string) < u08 sym; while (*string!='\0') // Пока первый байт строки не 0 (конец ASCIIZ строки) < if(127<y) // Проверяем за границу выхода за экран. Если вылезаем < // Вот тут, кстати, можно поиграть с числом, чтобы не рубило последний символ. y=0; // То обнуляем координату точки. x++; // Выставляем следующую строку if(x>7) break; // Если экран и вниз кончился - выход. >sym = *string-0x20; // Вычисляем из ASCII кода смещение в таблице символов. // Для русского языка и цифр надо условия добавить. Т.к. // таблица там не полная, не 255 байт. y = BLOCK(x,y+1,5,(u16)symboltable+sym*5); // Закатываем этот блок. string++; // Не забывая увеличивать указатель, > >

Для еще большего ускорения можно немного оптимизировать функции ввода вывода. Убрав из хвостов возврат сигналов в первоначальное положение. У меня они больше для красоты. Да чтобы на экране анализатора было лучше видно :)

Ну и чтение-модификацию-запись делать тоже большими блоками. Загоняя, скажем, страницу в буфер, правя его там и быстро выгружая обратно.

Ну и, традиционно, архив с примером. Сделано все на ATmega16 под WinAVR GCC на Pinboard

Спасибо. Вы потрясающие! Всего за месяц мы собрали нужную сумму в 500000 на хоккейную коробку для детского дома Аистенок. Из которых 125000+ было от вас, читателей EasyElectronics. Были даже переводы на 25000+ и просто поток платежей на 251 рубль. Это невероятно круто. Сейчас идет заключение договора и подготовка к строительству!

А я встрял на три года, как минимум, ежемесячной пахоты над статьями :)))))))))))) Спасибо вам за такой мощный пинок.

115 thoughts on “Работа с графическим дисплеем WG12864 на базе контроллера KS0107”

TFT так просто не обработаешь, под него нужен мощный контроллер, а лучше ПЛИС и видеопамять. Так что не все так просто.

Можно да, но его надо гдето в памяти держать. Тут получается килобайт только фреймбуфер.

Мощный то и не нужен, lpc2478 или lh79520 отлично справятся, только если хранить картинки нужно, то лучше прикрутить внешний nand мега на 4

Ди, нескромный вопросик, а с чем у тебя связана работа? :)

Я уже три года как безработный О_о

А последняя работа была какая?
Ди. Раз ты тут. Скажи своей жене чтобы она занялась моим заказом :) 701 вроде.

Последний раз я был наладчиком лабораторного оборудования. До этого наладчиком станков ЧПУ, а до этого я был студентом :)

Вывод информации из микроконтроллера зачастую создаёт больше сложностей, чем непосредственно работа основной программы – ведь необходимо и “отдать” несколько пинов для подключения, и некоторое количество памяти для библиотеки обработки графики.

Новички часто допускают ошибку, либо пытаясь запихнуть большое количество данных на маленький экран (вроде Nokia 3310), либо наоборот – в любой, даже самый маленький проект добавляют гигантский дисплей, требующий большой производительности.

Мы рассмотрим компромиссное решение – небольшой по размеру (0.96”), но с достаточным разрешением (128×64) экран с подключением всего по 3 проводам!

Обзор модуля

OLED 128x64px SPI - схема подключения к Arduino

SSD1306 – контроллер, на котором построено несколько вариаций дисплейных модулей. Часто встречаются также подключающиеся по интерфейсу I²C, но наш сегодняшний вариант подключается по более скоростному SPI.

Сам дисплей, установленный на модуле, выполнен по технологии OLED, что гарантирует низкое потребление, высокую скорость переключения (как следствие, большая возможная частота обновления экрана). Экран двухцветный, что не позволяет выводить точные картинки, зато помогает снизить размер буфера для видеопамяти всего до 1 Кб, так как 8 точек кодируются сразу одним байтом.

Подключение по SPI обеспечивает скорость соединения до 20 Мбит/с, с чем интерфейс I²C с его запросами и сложной структурой конкурировать неспособен. Доступно также подключение по параллельным интерфейсам, но модули с таким подключением мало распространены.

Питание модуля – 3.3 В, но на плате установлен стабилизатор с низким падением напряжения, что позволяет питать дисплей как от 5 В, так и от 3.3 В напрямую. Лучше использовать 5 В питание – этим вы разгружаете и без того не сильно мощный 3.3 В стабилизатор, установленный на Arduino.

Максимальное потребление (когда включены все пиксели дисплея) порядка 20 мА, поэтому при необходимости его можно питать прямо от пина микроконтроллера.

Схема подключения к Arduino

OLED 128x64px SPI - схема подключения к Arduino

  • CS – любой пин Arduino
  • SCK – 13 пин (Arduino UNO)
  • MOSI – 11 пин
  • Vcc – 3.3…5В
  • GND – GND

Распиновку интерфейса для других плат можно найти на официальном сайте.

Подключение в Arduino IDE

Для дисплея существует множество библиотек, причём никто не запрещает вам написать свою – протокол описан в даташите. Но для упрощения задачи мы возьмём готовую библиотеку U8gLib. Она поддерживает большое количество контроллеров экрана, в числе которых и SSD1306.

Откройте любой пример. В начале скетча будет большое количество закомментированных строк инициализации для разных контроллеров. Найдите среди них SSD1306, подключающийся по SPI и имеющий разрешение 128×64, после чего раскомментируйте эту строчку и можете загружать скетч!

Привет! Будучи любителем - энтузиастом электроники, я уверен, что всё что мы делаем – радиоэлектронные игрушки – самоделки, или большие проекты, все это от любопытства и лени. Любопытство стремится понять и постичь необъятное, не познанное, разобраться, как оно там работает, чего делает, как двигается. А лень изобретает, чтобы такого придумать, чтобы не вставать, не подходить, не поднимать, не запачкаться или еще чего ни будь важное.

Для тех, у кого тоже возникло подобное желание, - вот краткое руководство по подключению и проверке маленьких и не дорогих дисплеев OLED.
Далее речь пойдет об одной из широко доступных для радиолюбителей моделях OLED дисплеев, управляемых чипом SSD1306, с размером экрана 0,96-дюймов и разрешением 128*64 или 128*32 точки. Эти дисплеи идеально подходят для не больших радиолюбительских конструкций и самоделок.

Шаг 1: Основные понятия

  • OLED это Organic Light-Emitting Diode, т.е., полупроводниковый прибор из органических соединений, который начинает излучать свет при прохождении через него электрического тока.
  • ARDUINO - это платформа для обучения и построения систем автоматики и робототехники.
  • ArduinoIDE - среда разработки. Это бесплатная программа для программирования Arduino.
  • I2C – Inter-Integrated Circuits, межмикросхемная линия связи.
  • Скетч, он же, код, он же программа - терминология Arduino.

Шаг 2: Комплектующие

  • 1. Сам OLED дисплей 0,96” (можно купить на Aliexpress или Ebay, - долго, но дешево!).
  • 2. Arduino UNO / Nano (там же где дисплей).
  • 3. Соединительные провода (там же).
  • 4. Компьютер или ноутбук с установленной ArduinoIDE.

Вообще покупка деталей для различных проектов на Aliexpress и Ebay очень прикольная штука, пока занимаешься одним проектом, детали к другому уже на подходе. Главное не забыть сделать заказ.

Шаг 3: Подключение дисплея


Управление дисплеем осуществляет чип SSD1306, который поддерживает пять протоколов связи и один из которых I2C. Данные по этому протоколу передаются всего по двум проводам, а чем меньше проводов в корпусе, тем лучше, так что нам он вполне подходит. Но! Встречаются модули с протоколом SPI и даже с переключением протоколов, так что будьте внимательны при покупке данного модуля.

Используемые выводы:
OLED дисплей - SCL/SCK (clock) и SDA (data), «Плюс» питания (VCC) и «Минус» питания (GND).
  • Vcc - 5V
  • GND - GND
  • SDA - A4
  • SCL - A5

Шаг 4: Сканер I2C

Каждое устройство на шине I2C имеет шестнадцатеричный адрес, поменять нельзя, он вшит намертво, каждый ответственный производитель должен где-то на корпусе или в инструкции указать его. Бывают модули с переключателями и перемычками, которыми можно изменить адрес, но… если устройства дешевые, до безобразия, то производитель может и не удосужиться заниматься такой мелочью, поэтому его придется определять самостоятельно.

Всего на шине может использоваться до 127 адресов - 119 для устройств и 8 адресов служебных. Общение ведется по этим адресам. Есть главный, он же Master, а есть ведомый, он же Slave, - Мастера запрашивают, ведомые отвечают, все просто.
Поскольку на нашем OLED-дисплей используется протокол связи I2C, а адрес может быть и не указан, мы сами попробуем узнать этот самый адрес.

Это можно сделать, загрузив коротенький скетч на свою плату Arduino с подключенным OLED. НО!
Не торопитесь сразу заливать скетч в Arduino! Давайте для начала загрузим «драйвера», т.е. подключим библиотеки, а для этого сразу перейдем к «Шагу №5», а затем вернемся и продолжим.

Шаг 4: Продолжение:

Шаг 5: Загрузка и подключение библиотек

  • 1. В ArduinoIDE идем в меню Скетч / Sketch.
  • 2. Выбираем «Включить библиотеки» / Include Libraries.
  • 3.Выбираем «Управление библиотеками» / Managed Libraries.
  • 4. Находим ADAFRUIT GFX и устанавливаем их.
  • 5. Находим ADAFRUIT SSD1306 и устанавливаем их.

Шаг 6: Тестирование дисплея


Чтобы проверить, работает ли все так, как ожидалось, запустите пример для проверки из ArduinoIDE.
Для этого:
Перейти ФАЙЛ> ПРИМЕРЫ> SSD 1306> Выбрать 128x64 i2c
Если вы получите «Ошибку», попробуйте выбрать SSD 1306> 128x32 i2c.
Если снова «Ошибка» попробуйте изменит адрес I2C в строке 61, демонстрационного кода, и замените его адресом вашего дисплея, который вы определили на шаге №4.
Если снова ошибка, можно попробовать отредактировать файл Adafruit_SSD1306.h, он находится в папке с библиотеками Arduino.

Откройте файл Adafruit_SSD1306.h в текстовом редакторе и найдите строки:

Должно получиться так:

Если снова ошибка – необходимо проверить правильность соединений.
После окончания загрузки вы увидите тестовую анимацию на экране, это означает, что вы успешно настроили свой OLED дисплей.

Когда вы вдоволь насладитесь сей анимацией, можете переходить к следующему шагу.

Затем пишем протокол сброса:

В VOID SETUP указываем шестнадцатеричный адрес нашего дисплея 0x3C, который мы узнали на «Шаге №4».
Затем, инициализируем дисплей и очищаем его:

Читайте также: