Графический дисплей WG12864A
Наступает момент, когда для решения поставленной задачи недостаточно возможностей символьных LCD, рано или поздно приходиться переходить к графическим LCD дисплеям.
Разнообразие их очень велико, и если символьные индикаторы в большинстве имеют сходный интерфейс, то интерфейс графических LCD очень сильно отличаются друг от друга.
Это обусловлено использованием различных контроллеров для различных LCD от разных производителей. В этой статье расскажу о WG12864A с управляющими контроллерами ks0108 фирмы Samsung. Сам дисплей разбит на две зоны размером 64x64 за каждую зону отвечает свой чип. Выбор чипа осуществляется подачей логического уровня на выводы CS1 и CS2. При этом, есть возможность писать в оба чипа одновременно. СКАЧАТЬ ПРИМЕР использования WG12864A для WinAVR (GCC) можно здесь. Читайте так же: Отличия WG12864A и WG12864B. Скачать обновленный пример можно здесь.
Документация и схема подключения дисплея WG12864A
Документацию по дисплею (очень скудную) можно скачать здесь.Назначение выводов индикатора:
1. Vss - общий 0В. 2. Vdd - +5В питание логики. 3. Vo - контрастность. 4. D/I - выбор данные/инструкции 1-данные 0-инструкции. 5. R/W - чтение/запись 1- чтение, 0-запись. 6. E - тактирующий сигнал при записи/чтении. 7-14. DB0-DB7 - шина данных/инструкций. 15. CS1 - выбор кристалла. 16. CS2 - выбор кристалла. 17. RST - сброс. 18. Vee - выход отрицательного напряжения. 19. A - анод подсветки 20. K - катод подсветки.Схема подключения WG12864A к микроконтроллеру ATMega16/ATMega32 приведена ниже.

Немного слов о том как работает графический дисплей WG12864A. На рисунке изображен принцип адресации дисплея.
Обратите внимание, дисплей условно разделен на две части, CS1 и CS2, за которые отвечают разные чипы дисплея. Мы можем управлять одной частью дисплея, устанавливая один из сигналов CS1 или CS2. Записываемый байт изображения отображает 8 точек расположенных по вертикали. Все изображение для одного кристалла, т.е. половины дисплея, можно отрисовать матрицей шириной 64 и высотой 8 байт.
Вывод простой графики на дисплей
Все приведенные ниже примеры основаны на использовании библиотеки WG12864A.c которую можно найти в архиве с примером.
WG_init_lcd();
WG_clear();
// Example 1 BEGIN
WG_WriteXY(6,2,LCD_CS1);
WG_WriteData(0×0,LCD_CS1);
WG_WriteData(0xC0,LCD_CS1);
WG_WriteData(0xE0,LCD_CS1);
WG_WriteData(0×10,LCD_CS1);
WG_WriteData(0×88,LCD_CS1);
WG_WriteData(0×88,LCD_CS1);
WG_WriteData(0×84,LCD_CS1);
WG_WriteData(0×84,LCD_CS1);
WG_WriteData(0×82,LCD_CS1);
WG_WriteData(0×2,LCD_CS1);
WG_WriteData(0×2,LCD_CS1);
WG_WriteData(0×2,LCD_CS1);
WG_WriteData(0×2,LCD_CS1);
WG_WriteData(0×2,LCD_CS1);
WG_WriteData(0×2,LCD_CS1);
WG_WriteData(0×4,LCD_CS1);
WG_WriteData(0×4,LCD_CS1);
WG_WriteData(0×8,LCD_CS1);
WG_WriteData(0×18,LCD_CS1);
WG_WriteData(0×30,LCD_CS1);
WG_WriteData(0xE0,LCD_CS1);
WG_WriteData(0×80,LCD_CS1);
WG_WriteData(0×0,LCD_CS1);
WG_WriteData(0×0,LCD_CS1);
WG_WriteXY(6,3,LCD_CS1);
WG_WriteData(0x7F,LCD_CS1);
WG_WriteData(0xFF,LCD_CS1);
WG_WriteData(0xFF,LCD_CS1);
WG_WriteData(0xFF,LCD_CS1);
WG_WriteData(0xFF,LCD_CS1);
WG_WriteData(0xE3,LCD_CS1);
WG_WriteData(0xE3,LCD_CS1);
WG_WriteData(0xE3,LCD_CS1);
WG_WriteData(0xFF,LCD_CS1);
WG_WriteData(0xFF,LCD_CS1);
WG_WriteData(0xFE,LCD_CS1);
WG_WriteData(0xC0,LCD_CS1);
WG_WriteData(0×80,LCD_CS1);
WG_WriteData(0×0,LCD_CS1);
WG_WriteData(0×0,LCD_CS1);
WG_WriteData(0x1C,LCD_CS1);
WG_WriteData(0x1C,LCD_CS1);
WG_WriteData(0x1C,LCD_CS1);
WG_WriteData(0×0,LCD_CS1);
WG_WriteData(0×0,LCD_CS1);
WG_WriteData(0×80,LCD_CS1);
WG_WriteData(0xFF,LCD_CS1);
WG_WriteData(0x7E,LCD_CS1);
WG_WriteData(0×0,LCD_CS1);
WG_WriteXY(6,4,LCD_CS1);
WG_WriteData(0×0,LCD_CS1);
WG_WriteData(0×1,LCD_CS1);
WG_WriteData(0×7,LCD_CS1);
WG_WriteData(0xF,LCD_CS1);
WG_WriteData(0x1F,LCD_CS1);
WG_WriteData(0x1F,LCD_CS1);
WG_WriteData(0x3F,LCD_CS1);
WG_WriteData(0x3F,LCD_CS1);
WG_WriteData(0x7F,LCD_CS1);
WG_WriteData(0x7F,LCD_CS1);
WG_WriteData(0x7F,LCD_CS1);
WG_WriteData(0x7F,LCD_CS1);
WG_WriteData(0x7F,LCD_CS1);
WG_WriteData(0x7F,LCD_CS1);
WG_WriteData(0x7E,LCD_CS1);
WG_WriteData(0x3C,LCD_CS1);
WG_WriteData(0x3C,LCD_CS1);
WG_WriteData(0x1C,LCD_CS1);
WG_WriteData(0x1E,LCD_CS1);
WG_WriteData(0xF,LCD_CS1);
WG_WriteData(0×7,LCD_CS1);
WG_WriteData(0×1,LCD_CS1);
WG_WriteData(0×0,LCD_CS1);
WG_WriteData(0×0,LCD_CS1);
// Example 1 END
При этом установка курсора по горизонтали от 0 до 63, а по вертикали от 0 до 8. При этом указываем, в какую часть дисплея пишем CS1 или CS2. Т.е. если нам надо что-то зарисовать с 72 точки по горизонтали, то это точка 8 (72-64), второй части дисплея. Для упрощения вывода изображения пользуйтесь функцией show_img(const char* img, uint8_t sx, uint8_t sy, uint8_t x, uint8_t y)
const char elefant[8][74] PROGMEM =
{
{0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×80,0xC0,0×60,0×70,0×30,0×38,0×38,0×38,0×38,0x3C,0x1C,0×38,0×19,0x3F,0xFC,0×78,0×78,0xF8,0xF8,0xC0,0×80,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0},
{0xC,0x1F,0×33,0×29,0xFF,0×6,0xC,0xF8,0xC0,0×0,0×0,0×6,0xEF,0×39,0x3C,0x3E,0×36,0xE7,0xC7,0x3F,0xFF,0xF2,0xFA,0xF4,0×0,0×0,0×0,0×0,0×0,0×80,0xC3,0×43,0xC7,0xBF,0xFF,0xF8,0xA0,0xC0,0xC0,0xE0,0×60,0×60,0×60,0×70,0×70,0×60,0×60,0×60,0×40,0xC0,0×80,0×80,0×0,0×0,0×0,0×0,0×0,0xE0,0xF8,0xD8,0×18,0×18,0×38,0×78,0xF8,0×70,0×70,0×20,0×0,0×0,0×0,0×0,0×0,0×0},
{0×0,0×0,0×0,0×0,0x1F,0x7F,0xC0,0×0,0×3,0x1E,0x1C,0x1C,0x1F,0×41,0x8C,0x8E,0x8B,0xE,0×0,0×0,0×0,0×0,0×7,0x1F,0×78,0×40,0xE0,0x3C,0x3F,0×79,0×79,0x1B,0x1B,0x1B,0×13,0×73,0×67,0x2D,0xB8,0xF0,0×60,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×1,0×1,0×42,0xC6,0xCC,0×78,0x1F,0xBF,0xFC,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0},
{0×0,0×0,0×0,0×0,0×0,0×0,0×1,0×3,0×2,0xE,0xC,0xC,0xC,0×16,0×13,0×31,0×21,0×23,0×60,0×40,0xC0,0×80,0×0,0×0,0×0,0×0,0xF,0×38,0×60,0xC0,0xC0,0×80,0×80,0×80,0xC0,0×60,0x3C,0×7,0×1,0×0,0×0,0×0,0×0,0×0,0xC0,0×60,0xC0,0×70,0×90,0xE0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0xC4,0×7,0×3,0×6,0×18,0xF0,0×80,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0},
{0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×80,0×81,0xC1,0×63,0x1E,0×6,0×4,0×8,0×18,0×30,0xA8,0xB8,0xFC,0xF8,0xE0,0xC0,0×80,0×80,0×80,0×80,0×0,0×2,0xC,0xF8,0xFF,0x2E,0×27,0×3,0×1,0×0,0×0,0×0,0×0,0×0,0×80,0xE0,0xF8,0xF8,0xFF,0×98,0xC0,0xC0,0xC0,0×1,0xF,0x3C,0xE0,0xC0,0×0,0×0,0×0,0×0,0×0,0×0},
{0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0x3E,0xFE,0xFF,0xEF,0xC2,0×6,0x3C,0xF8,0xBE,0xF,0xD,0×1,0×80,0xC0,0×40,0×20,0×30,0×10,0×18,0xD,0×7,0×3,0×1,0xD,0x7F,0xC3,0×3,0×7,0xF,0x1D,0xFF,0xFE,0x3E,0x3B,0×3,0×2,0xC0,0×60,0xE0,0×10,0×18,0xC,0×6,0×3,0×3,0×1,0×1,0×1,0×3,0×6,0xC,0×18,0×18,0xB0,0xF0,0xE0,0×80,0×81,0×3,0×6,0x8C,0xF0,0xE0,0xC0},
{0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×1,0×3,0×6,0×4,0×8,0×8,0×11,0×10,0xC,0×6,0×3,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×1,0×3,0×6,0xC,0×18,0×10,0x1F,0×98,0×78,0×66,0×63,0×60,0×60,0×61,0×7,0xC,0×30,0xE0,0×40,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0xC,0x1F,0×37,0x3C,0×31,0×11,0×18,0xE,0xF,0×7,0×6,0×3,0×0},
{0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×6,0xF,0xB,0xE,0xE,0xE,0xA,0xE,0xC,0×4,0×6,0×3,0×1,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0,0×0}
};
// Example 2 BEGIN
show_img(&elefant[0][0], sizeof(elefant[0]), sizeof(elefant)/sizeof(elefant[0]), 40,0);
// Example 2 END
Эта функция выводит изображение из указанного массива в указанную позицию в пикселях. При этом массив храниться во флеш памяти и не занимает оперативную. Параметры функции void show_img(const char* img, uint8_t sx, uint8_t sy, uint8_t x, uint8_t y) img - специально подготовленный массив sx - размер изображения по ширине sy - размер изображения по высоте x - положение изображения на дисплее в пикселях по горизонтали y - положение изображения на дисплее в пикселях по вертикали
Преобразование PNG файла в массив
Выписывать вручную массив точек для изображения занятие совершенно не благодарное. Чтобы избавить себя от этой рутины я написал небольшой скрипт на PHP. Скачать его можно здесь. Принцип работы прост: 1. В любом графическом редакторе рисуем черно-белое (не градации серого, а именно черно-белое) изображение размером не более 128x64 и сохраняем в формате PNG. 2. Идем по ссылке на wg12864a.php, загружаем изображение, получаем готовый код массива. Копируем, вставляем его в код программы. 3. Незабываем переименовать имя массива, если в коде используется несколько изображений.Вывод текста
WG12864A не имеет встроенного знакогенератора, поэтому отображать буквы будем самостоятельно. Для этого нам понадобиться массив с изображением всех символов. Он находиться в файле symbols.h В этом файле описано два массива symbol - буквы, цифры и big_number - цифры большого размера.Вывод одного символа выполняется командой WG_putc:
WG_SetTextXY(0,0);
WG_putc(‘a’,255);
Вывод строки из массива выполняется командой WG_puts:
WG_puts(0, 8, &mystring, 19, 0);
Вывод больших цифр WG_put_big_number:
WG_SetTextXY(3,5);
WG_put_big_number(9,0);
Пример:
// Example 3 BEGIN
WG_puts(0, 8, &mystring, 19, 0);
WG_SetTextXY(0,0);
WG_putc(‘a’,255);
WG_putc(‘g’,255);
WG_putc(‘a’,255);
WG_SetTextXY(3,5);
WG_put_big_number(9,0);
// Example 3 END
В функцииях вывода символов и строк есть есть параметр inv он отвечает за стиль вывода символа. Выводимый символ можно инвертировать. т.е. вывести светлым на темном. При этом используется 8 битное число, что позволяет инвертировать символ по маске, т.е. не целиком, а необходимые пиксели, например верхнюю или нижнюю часть. Пример:
WG_SetTextXY(0,0);
WG_putc(‘a’,255); // на темном фоне
WG_putc(‘g’,0); // на светлом фоне
WG_putc(‘a’,255); // на темном фоне
Вот пожалуй и все, для начала. Геометрические фигуры будем рисовать позже. Если заставить двигаться изображение по экрану, то заметим, что он немного инертен, изображение смазывается. Другими словами, для анимации он не предназначен.
Смотри так же:
7-и сегментный ЖК-индикатор. Пример использования.
Использование cимвольных жидкокристаллических LCD дисплеев. Пример на GCC (WinAVR) для Atmega 8
Отличия WG12864A и WG12864B. Скачать обновленный пример можно здесь.
Недавні записи
- CRSF to PWM
- U-FOC PC Monitor для Chrome browser
- Фільтрація Back-EMF. Безсенсорні BLDC мотори
- Text to speech. Українська мова
- LCD Display ST7567S (IIC)
- Розпізнавання мови (Speech recognition)
- Selenium
- Комп'ютерний зір (Computer Vision)
- Деякі думки про точність вимірювань в електроприводі
- Датчики Холла 120/60 градусів
Tags
bluetooth bldc nodemcu tim max1674 eeprom led avr hih-4000 brushless programmator mpu-6050 usart examples smd sensors piezo rs-232 motor html git meteo bme280 gps bkp encoder java-script raspberry-pi websocket esp8266 books solar eb-500 atmega mongodb gpio sms css pwm ethernet pmsm st-link capture dma stm32 watchdog lcd rfid python uart battery dc-dc soldering timer ssd1331 wifi nvic dht11 docker i2c 3d-printer adc bmp280 flash rtc servo barometer remap exti mpx4115a web flask ngnix usb displays foc ssd1306 mpu-9250 options
Архіви