Графический дисплей 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. Скачать обновленный пример можно здесь.
Недавні записи
- U-FOC PC Monitor для Chrome browser
- Фільтрація Back-EMF. Безсенсорні BLDC мотори
- Text to speech. Українська мова
- LCD Display ST7567S (IIC)
- Розпізнавання мови (Speech recognition)
- Selenium
- Комп'ютерний зір (Computer Vision)
- Деякі думки про точність вимірювань в електроприводі
- Датчики Холла 120/60 градусів
- Модуль драйверів напівмосту IGBT транзисторів
Tags
eeprom gps mpu-9250 sensors lcd displays html tim meteo remap pwm avr rfid ethernet pmsm raspberry-pi mpx4115a piezo uart watchdog exti git i2c bme280 bmp280 barometer nodemcu st-link eb-500 led atmega esp8266 bkp servo stm32 wifi flask solar bluetooth brushless motor smd docker books encoder capture battery soldering hih-4000 ssd1331 ssd1306 mpu-6050 dc-dc ngnix programmator mongodb examples adc nvic dht11 rs-232 css websocket web python 3d-printer rtc usart gpio foc bldc usb flash dma sms max1674 java-script timer options
Архіви