Используйте графический дисплей 128×64 / I²C для вывода текста, отрисовки графиков и отображения простых картинок. Монохромный экран выполнен по технологии LCD c разрешением 128×64 пикселей.
Графические дисплеи применяются в домашних охранных системах, робототехнике, МФУ-устройствах, вендинговых автоматах и турникетах общественного транспорта.
Дисплей похвастается интерфейсом I²C, а это значит можно забыть про вермишель из проводов. Для общения с микроконтроллером понадобится всего два сигнальных провода.
Мозгом для проекта выступит платформа Arduino Uno.
Для начала необходимо собрать железо и выполнить программную настройку.
Выведем на экран дисплея монохромное изображение. Для этого воспользуйтесь графическим редактором GIMP и преобразуйте исходную картинку в текстовый массив чисел .
Основные правила при конвертации изображения:
// Библиотека для работы с модулям по I²C #include <Wire.h> // Адрес младшего кристалла #define RW1065I_ADDR_I2C_LOW 0x3C // Адрес старшего кристалла #define RW1065I_ADDR_I2C_HIGH 0x3D // Адрес кристалла управления #define NF8475A_ADDR_I2C 0x3B // Определение управляющих байт // control byte C0=0, DC=1, последний упр.байт, дальше только данные #define CTRL_0_DATA 0x40 // control byte C0=1, DC=1, после байт данных, потом снова упр. байт #define CTRL_1_DATA 0xC0 // control byte C0=0, DC=0, последний упр.байт, дальше только команды #define CTRL_0_CMD 0x00 // control byte C0=1, DC=0, после байт команды, потом снова упр. байт #define CTRL_1_CMD 0x80 // Массив картинки логотипа амперки // Каждые 8 вертикальных точек собраны в байт const byte amperkaLogo[8][128] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x1F, 0x3F, 0x7F, 0x79, 0x70, 0x70, 0x79, 0x7F, 0x3F, 0x1F, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFE, 0xFF, 0x1F, 0x07, 0xF1, 0xF8, 0xFC, 0x1E, 0x0E, 0x0F, 0x07, 0x07, 0x0F, 0x0E, 0x1E, 0xFC, 0xF8, 0xF1, 0x07, 0x1F, 0xFF, 0xFE, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x3F, 0x7F, 0xFC, 0xF0, 0xE7, 0xCF, 0x9F, 0xBC, 0x38, 0x78, 0x70, 0x70, 0x78, 0x38, 0xBC, 0x9F, 0xCF, 0xE7, 0xF0, 0xFC, 0x7F, 0x3F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xE0, 0x60, 0x60, 0x60, 0xE0, 0xC0, 0xE0, 0xE0, 0x00, 0x00, 0xE0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xE0, 0x00, 0x00, 0xE0, 0xE0, 0x60, 0x60, 0x60, 0x60, 0x60, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xE0, 0x60, 0x60, 0xE0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0xE0, 0xE0, 0xC0, 0x60, 0x60, 0x60, 0x60, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x60, 0x60, 0x60, 0xE0, 0xC0, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x3F, 0x7F, 0xF1, 0xE0, 0xC0, 0xC0, 0xC0, 0xE0, 0x71, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x0F, 0x1E, 0x1E, 0x0F, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1E, 0x7F, 0x7F, 0xE6, 0xC6, 0xC6, 0xC6, 0xC6, 0xE6, 0xE7, 0x67, 0x00, 0x00, 0xFF, 0xFF, 0x60, 0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0x71, 0x3F, 0x1F, 0x00, 0x00, 0xFF, 0xFF, 0x0C, 0x0C, 0x1F, 0x3F, 0xF3, 0xE0, 0xC0, 0x00, 0x00, 0x3F, 0x7F, 0xF1, 0xE0, 0xC0, 0xC0, 0xC0, 0xE0, 0x71, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; void drawImage() { // Текущая страница byte pp = 0; // цикл по 8-ми страницам for (pp = 0; pp < 8; pp++) { // поз. по горизонтали выводимого байта byte c = 0; // Вывод строки массива, первая половина в мл. кристалл Wire.beginTransmission(RW1065I_ADDR_I2C_LOW); Wire.write("\x80\x3F\x80\xC0\x80\x40\x80"); for (byte j = 0; j < 4; j++){ Wire.endTransmission(false); Wire.beginTransmission(RW1065I_ADDR_I2C_LOW); Wire.write(0x80); Wire.write(0xB8|pp); Wire.write(0x40); for (byte i = 0; i < 16; i++) { byte send_data; send_data = amperkaLogo[pp][c]; Wire.write(send_data); c++; } } Wire.endTransmission(false); // Вывод строки массива, вторая половина в ст. кристалл Wire.beginTransmission(RW1065I_ADDR_I2C_HIGH); Wire.write("\x80\x3F\x80\xC0\x80\x40\x80"); for (byte j = 0; j < 4; j++) { Wire.endTransmission(false); Wire.beginTransmission(RW1065I_ADDR_I2C_HIGH); Wire.write(0x80); Wire.write(0xB8|pp); Wire.write(0x40); for (byte i = 0; i < 16; i++) { byte send_data; send_data = amperkaLogo[pp][c]; Wire.write(send_data); c++; } } Wire.endTransmission(true); } } // Одиночная команда в обычном режиме void normComand1 (byte cmd) { // Команда, мл. крист. Wire.beginTransmission(RW1065I_ADDR_I2C_LOW); Wire.write(0x00); Wire.write(cmd); Wire.endTransmission(false); // Команда, ст. крист. Wire.beginTransmission(RW1065I_ADDR_I2C_HIGH); Wire.write(0x00); Wire.write(cmd); Wire.endTransmission(true); } // Инициализация дисплея void initLCD() { // вкл. дисплея, Addr=0, нач.стр.=0, Page=0, мл.кристалл Wire.beginTransmission(RW1065I_ADDR_I2C_LOW); Wire.write(0x80); Wire.write(0x3F); Wire.write(0x80); Wire.write(0x40); Wire.write(0x80); Wire.write(0xC0); Wire.write(0x00); Wire.write(0xB8); Wire.endTransmission(false); // вкл. дисплея, Addr=0. ст.кристалл Wire.beginTransmission(RW1065I_ADDR_I2C_HIGH); Wire.write(0x80); Wire.write(0x3F); Wire.write(0x00); Wire.write(0x40); Wire.endTransmission(true); } // Очистка дисплея void clearLCD(byte f, byte m) { Wire.beginTransmission(RW1065I_ADDR_I2C_LOW); Wire.write("\x80\x3F\x80\xC0\x80\x40\x80"); for (byte p = 0; p < 8; p++) { Wire.endTransmission(false); Wire.beginTransmission(RW1065I_ADDR_I2C_LOW); Wire.write(0x80); Wire.write(0xB8|p); Wire.write(0x40); for (byte i = 0; i < 16; i++) { Wire.write(f); f ^= m; } for (byte j=0; j < 3; j++) { Wire.endTransmission(false); Wire.beginTransmission(RW1065I_ADDR_I2C_LOW); Wire.write(0x40); for (byte i = 0; i < 16; i++) { Wire.write(f); f ^= m; } } } Wire.endTransmission(true); Wire.beginTransmission(RW1065I_ADDR_I2C_HIGH); Wire.write("\x80\x3F\x80\xC0\x80\x40\x80"); for (byte p = 0; p < 8; p++) { Wire.endTransmission(false); Wire.beginTransmission(RW1065I_ADDR_I2C_HIGH); Wire.write(0x80); Wire.write(0xB8|p); Wire.write(0x40); for (byte i = 0; i < 16; i++) { Wire.write(f); f ^= m; } for (byte j=0; j < 3; j++) { Wire.endTransmission(false); Wire.beginTransmission(RW1065I_ADDR_I2C_HIGH); Wire.write(0x40); for (byte i=0; i<16; i++) { Wire.write(f); f ^= m; } } } Wire.endTransmission(true); } void setup() { // Настройка I²C Wire.begin(); Wire.setClock(400000); delay(200); // Установка регистра управления в исходное состояние - FF // Нормальный режим, P_ON Wire.beginTransmission(NF8475A_ADDR_I2C); Wire.write(0xFF); Wire.endTransmission(true); delay (500); // power normal, команда расширенного режима Wire.beginTransmission(RW1065I_ADDR_I2C_LOW); Wire.write(0x80); Wire.write(0x0D); Wire.write(0x80); Wire.write(0x02); Wire.write(0x00); Wire.write(0x0C); Wire.endTransmission(false); Wire.beginTransmission(RW1065I_ADDR_I2C_HIGH); Wire.write(0x80); Wire.write(0x0D); Wire.write(0x80); Wire.write(0x02); Wire.write(0x00); Wire.write(0x0C); Wire.endTransmission(true); clearLCD(0, 0); initLCD(); // Включение полной яркости подсветки // Полная яркость подсветки BL_ON2 - "низкий" Wire.beginTransmission(NF8475A_ADDR_I2C); Wire.write(0xFB); Wire.endTransmission(true); delay(100); // Вывод изображения на дисплей drawImage(); } void loop() { }
Дисплей MT-12864K выполнен на монохромной жидкокристаллической матрице с разрешением 128×64 пикселей. Каждый пиксель поддерживает только два состояния: включён или выключен, 1 или 0, true или false.
Матрица экрана подключена к драйверу дисплея, который выполняет роль посредника между экраном и управляющим микроконтроллером.
RW1065I LCD Segment Common Driver — это контроллер сегментов с драйвером общих линий для управления матрицей дисплея с разрешением 64×32 пикселя. Для управления графическим дисплеем разрешением 128×64 пикселей, требуется два таких чипа. Первый RW1065I для управления левой половиной сегментов SEG1–SEG64 с общими линиями COM1–COM32, а второй RW1065I для управления правой половиной сегментов SEG65–SEG128 с общими линиями COM33–COM64.
Доступ к каждому контроллеру осуществляется по интерфейсу I²C с заданными I²C-адресами. На плате дисплея есть возможность сменить адреса контроллеров RW1065I. Это даёт возможность подключить к управляющей плате два дисплея одновременно и выводить на каждый экран различные данные, при этом количество занятых пинов останется прежним.
Для смены адресов контроллеров RW1065I на обратной стороне дисплея установлен переключатель
с контактными площадками и .Капнув припоем на соответствующие контактные площадки, можно получать две разных группы I²C-адресов:
Addr1 | |||
---|---|---|---|
R5 | R6 | Адрес RW1065I #1 | Адрес RW1065I #2 |
L | H | 0x3C (по умолчанию) | 0x3D (по умолчанию) |
H | L | 0x3E | 0x3F |
Для управления контрастности и яркости на двух дисплей отдельно, необходимо также сменить адрес вспомогательного контроллера INF8475A.
INF8475A Driver — это вспомогательный контроллер для программной регулировки контрастности дисплея, яркость подсветки и других вспомогательных функций.
Доступ к вспомогательному контроллеру осуществляется по интерфейсу I²C с заданными I²C-адресом. На плате дисплея есть возможность сменить адрес регистра RW1065I. Это даёт возможность подключить к управляющей плате два дисплея одновременно и управлять контрастностью/яркостью каждого экрана отдельно, при этом количество занятых пинов останется прежним.
Для смены адреса вспомогательного контроллера INF8475A на обратной стороне дисплея установлен переключатель
с контактными площадками и .Капнув припоем на соответствующие контактные площадки, можно получать два разных I²C-адреса:
Addr2 | ||
---|---|---|
R17 | R18 | Адрес INF8475A |
L | H | 0x3B (по умолчанию) |
H | L | 0x3A |
Для вывода на каждый экран различных данных, необходимо также сменить адреса контроллеров RW1065I.
На плате дисплея выведено 4 контакта для подключения питания и взаимодействия с управляющей электроникой.
Вывод | Обозначение | Описание | Подключение |
---|---|---|---|
1 | VIN | Питание дисплея | Подключите к питанию 2,9–5,5 В. |
2 | GND | Общая земля | Подключите к земле. |
3 | SCL | Тактирование шины I²C | Подключите к пину SCL микроконтроллера. |
4 | SDA | Данные шины I²C | Подключите к пину SDA микроконтроллера. |