Многие экспериментирующие с *duino сталкиваются с графическими монохромными LCD экранчиками на контроллерах ks0107/ks0108. Благо для их поддержки имеются несколько версий только официальной библиотеки.
Библиотечку можно взять здесь:
http://code.google.com/p/glcd-arduino/downloads/list
Вопросы подключения экранчика к контроллеру я рассматривать не буду, примеры есть и на этом сайте и на просторах интернета желающий найдет без труда. Кроме того, достаточно подробно расписано в документации к библиотеке.
Засада кроется в том, что без телодвижений, напряжения серого вещества русский текст из скетча ардуино никакими судьбами не выведешь. Ну нет в составе библиотеки русских шрифтов и все! Правда прилагается на страничке скачивания программулина для изобретения своих шрифтов и конвертации виндовых.
Ну во-первых, написана она на JAVA, следовательно запустить ее тоже надо суметь, а во-вторых ну никак она у меня не захотела находить русские буквы в виндовых шрифтах, кракозябры и все!! 🙂
Лень, она конечно сильна, слов нет. Поэтому яндексу и гуглу были скормлены пара десятков запросов на различные вариации ключевых слов «русский шрифт GLCD». Ничего вразумительного, а тем более готового файла не нашлось. Может конечно не так искал….
Ну да ладно, делать нечего, пришлось напрягать пресловутое вещество.
Оговорюсь сразу: В данной заметке я рассмотрю создание (а точнее — модификацию) шрифта содержащего символы фиксированной ширины. Если тема кого заинтересует можно будет подобраться и к шрифту с символами переменной ширины.
Итак поехали!
Скачиваем и распаковываем библиотеку. Файлы с описанием шрифтов лежат в папочке «fonts». Открываем самый мелкий SystemFont5x7.h и пытаемся сделать ему трепанацию. Нас интересует какие параметры описывает этот файл, т.е. структура описания шрифта.
/* * * System5x7 * Ну информация в комментах читаем! * * File Name : System5x7.h - это понятно! * Date : 28 Oct 2008 - не интересно!!! * Font size in bytes : 470 - поменяется!! * Font width : 5 - вот первое важное - ширина символа * Font height : 7 - его высота * Font first char : 32 - хм.... это у нас код первого символа шрифта (ASCII - пробел) * Font last char : 127 - код последнего символа шрифта * Font used chars : 94 - количество запользованных символов * * The font data are defined as - опачки! описание структуры шрифта, разгребаем!!! * * struct _FONT_ { * uint16_t font_Size_in_Bytes_over_all_included_Size_it_self; - ни что иное как размер шрифта в байтах включая все размеры самого себя (вроде тафтология но выясняется что файл описания может содержать несколько размеров символов или я чегой-то не так понял) * uint8_t font_Width_in_Pixel_for_fixed_drawing; - ширина шрифта в пикселах для фиксированной отрисовки (не, но вот тут как-то не ясно, а как же шрифты с переменным размером?) * uint8_t font_Height_in_Pixel_for_all_characters; - высота шрифта для всех символов (я так понимаю наибольшая) * unit8_t font_First_Char; - код первого символа * uint8_t font_Char_Count; количество символов (где-то это мы уже видели) * * uint8_t font_Char_Widths[font_Last_Char - font_First_Char +1]; * // for each character the separate width in pixels, * // characters < 128 have an implicit virtual right empty row - если переводить буквально то диапазон ширины символов ширина_последнего - ширина_первого + 1 добавляем межсимвольный интервал - виртуальный правый пустой столбец. * * uint8_t font_data[]; * // bit field of all characters - описание символов в виде битовой маски. */ #include <inttypes.h> #include <avr/pgmspace.h> #ifndef SYSTEM5x7_H #define SYSTEM5x7_H #define SYSTEM5x7_WIDTH 5 #define SYSTEM5x7_HEIGHT 7 /* * added to allow fontname to match header file name. * as well as keep the old name for backward compability */ #define SystemFont5x7 System5x7 static uint8_t System5x7[] PROGMEM = { 0x0, 0x0, // size of zero indicates fixed width font, actual length is width * height - нули здесь говорят о том что мы имеем шрифт фиксированного размера!! 0x05, // width -5 на 0x07, // height -7 пикселей 0x20, // first char -HEX-код первого символа 0x60, // char count -количество буков в HEX! // Fixed width; char width table not used !!!! АГА!!!! здесь должна располагаться таблица ширин символов отличающихся от базового размера у нас в данном случае таких нет! // font data 0x00, 0x00, 0x00, 0x00, 0x00,// (space) - пошло описалово в HEX-формате.
Ну вроде все достаточно ясно для практического использования:
размер символов строго 5х7 точек, межсимвольный интервал добавляется автоматом, последний использованный код 0x20+0x60 — 1 = 0x7F. Начиня с 0x80 можно куролесить свои битовые маски.
Конечно, желающие могут взять тетрадку в клеточку, карандашик, разметить знакоместа 5 на 7 клеточек, закрасить соответствующие и перевести в начале в бинарный код а потом в HEX. Круто!!
🙂 Только для начала надо интерпретировать по клеточкам коды символа 0х41, чтобы разобраться как библиотека отрисовывает символ по вертикали или по горизонтали.
Я воспользовался для этой цели найденной на просторе интернета программой, могущей пригодиться не только при изобретении шрифтов но и для других работ с нашим экранчиком. (можно взять здесь: http://ikarab.narod.ru/KS0108.html ) В ней есть преобразование «код — картинка» можно проверить символ 0х41 и получить «A». Соответственно, закрашивая попиксельно знакоместа — получаем строчку HEX-кодов символов.
Ну что ж, рисуем:
0x7e, 0x11, 0x11, 0x11, 0x7e,//A 0x80 0x7f, 0x49, 0x49, 0x49, 0x33,//Б 0x81 0x7f, 0x49, 0x49, 0x49, 0x36,//В 0x82 0x7f, 0x01, 0x01, 0x01, 0x03,//Г 0x83 0xe0, 0x51, 0x4f, 0x41, 0xff,//Д 0x84 0x7f, 0x49, 0x49, 0x49, 0x41,//E 0x85 0x77, 0x08, 0x7f, 0x08, 0x77,//Ж 0x86 0x41, 0x49, 0x49, 0x49, 0x36,//З 0x87 0x7f, 0x10, 0x08, 0x04, 0x7f,//И 0x88 0x7c, 0x21, 0x12, 0x09, 0x7c,//Й 0x89 0x7f, 0x08, 0x14, 0x22, 0x41,//K 0x8A 0x20, 0x41, 0x3f, 0x01, 0x7f,//Л 0x8B 0x7f, 0x02, 0x0c, 0x02, 0x7f,//M 0x8C 0x7f, 0x08, 0x08, 0x08, 0x7f,//H 0x8D 0x3e, 0x41, 0x41, 0x41, 0x3e,//O 0x8E 0x7f, 0x01, 0x01, 0x01, 0x7f,//П 0x8F 0x7f, 0x09, 0x09, 0x09, 0x06,//P 0x90 0x3e, 0x41, 0x41, 0x41, 0x22,//C 0x91 0x01, 0x01, 0x7f, 0x01, 0x01,//T 0x92 0x47, 0x28, 0x10, 0x08, 0x07,//У 0x93 0x1c, 0x22, 0x7f, 0x22, 0x1c,//Ф 0x94 0x63, 0x14, 0x08, 0x14, 0x63,//X 0x95 0x7f, 0x40, 0x40, 0x40, 0xff,//Ц 0x96 0x07, 0x08, 0x08, 0x08, 0x7f,//Ч 0x97 0x7f, 0x40, 0x7f, 0x40, 0x7f,//Ш 0x98 0x7f, 0x40, 0x7f, 0x40, 0xff,//Щ 0x99 0x01, 0x7f, 0x48, 0x48, 0x30,//Ъ 0x9A 0x7f, 0x48, 0x30, 0x00, 0x7f,//Ы 0x9B 0x00, 0x7f, 0x48, 0x48, 0x30,//Э 0x9C 0x22, 0x41, 0x49, 0x49, 0x3e,//Ь 0x9D 0x7f, 0x08, 0x3e, 0x41, 0x3e,//Ю 0x9E 0x46, 0x29, 0x19, 0x09, 0x7f,//Я 0x9F // маленькие буквы 0x20, 0x54, 0x54, 0x54, 0x78,//a 0xA0 0x3c, 0x4a, 0x4a, 0x49, 0x31,//б 0xA1 0x7c, 0x54, 0x54, 0x28, 0x00,//в 0xA2 0x7c, 0x04, 0x04, 0x04, 0x0c,//г 0xA3 0xe0, 0x54, 0x4c, 0x44, 0xfc,//д 0xA4 0x38, 0x54, 0x54, 0x54, 0x18,//e 0xA5 0x6c, 0x10, 0x7c, 0x10, 0x6c,//ж 0xA6 0x44, 0x44, 0x54, 0x54, 0x28,//з 0xA7 0x7c, 0x20, 0x10, 0x08, 0x7c,//и 0xA8 0x7c, 0x41, 0x22, 0x11, 0x7c,//й 0xA9 0x7c, 0x10, 0x28, 0x44, 0x00,//к 0xAA 0x20, 0x44, 0x3c, 0x04, 0x7c,//л 0xAB 0x7c, 0x08, 0x10, 0x08, 0x7c,//м 0xAC 0x7c, 0x10, 0x10, 0x10, 0x7c,//н 0xAD 0x38, 0x44, 0x44, 0x44, 0x38,//o 0xAE 0x7c, 0x04, 0x04, 0x04, 0x7c,//п 0xAF 0x7C, 0x14, 0x14, 0x14, 0x08,//p 0xB0 0x38, 0x44, 0x44, 0x44, 0x20,//c 0xB1 0x04, 0x04, 0x7c, 0x04, 0x04,//т 0xB2 0x0C, 0x50, 0x50, 0x50, 0x3C,//у 0xB3 0x30, 0x48, 0xfc, 0x48, 0x30,//ф 0xB4 0x44, 0x28, 0x10, 0x28, 0x44,//x 0xB5 0x7c, 0x40, 0x40, 0x40, 0xfc,//ц 0xB6 0x0c, 0x10, 0x10, 0x10, 0x7c,//ч 0xB7 0x7c, 0x40, 0x7c, 0x40, 0x7c,//ш 0xB8 0x7c, 0x40, 0x7c, 0x40, 0xfc,//щ 0xB9 0x04, 0x7c, 0x50, 0x50, 0x20,//ъ 0xBA 0x7c, 0x50, 0x50, 0x20, 0x7c,//ы 0xBB 0x7c, 0x50, 0x50, 0x20, 0x00,//ь 0xBC 0x28, 0x44, 0x54, 0x54, 0x38,//э 0xBD 0x7c, 0x10, 0x38, 0x44, 0x38,//ю 0xBE 0x08, 0x54, 0x34, 0x14, 0x7c //я 0xBF
Ну вот, самая трудоемкая часть работы позади…. Не притомились?
Идем дальше…
Казалось бы, добавляем наш двоичный массив в хвост шрифта, корректируем заголовок и вот оно — счастье! Не тут-то было!
Меня осенила здравая идея — проверить в какой кодировке работает Arduino IDE. Для этого был спешно набросан кусочек кода:
#include <glcd.h> #include "fonts/SystemFont5x7.h" char myString[] = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя"; void setup () { GLCD.Init(); GLCD.SelectFont(System5x7,BLACK); } void loop() { byte i=0; while (i<120) { GLCD.print(myString[i]); GLCD.print(" == "); GLCD.print(myString[i],HEX); GLCD.println(); delay(100); i++; } GLCD.println(); GLCD.println(myString); delay(5000); }
Выяснилось — работаем в UTF-8. Берем таблицу кодировки и получается что:
диапазону 0x80 — 0x8F соответствуют маленькие буквы от «р» до «я»
с 0x90 и до 0xAF идут заглавные по порядку «А» — «Я» исключая «Ё»
и в хвосте с 0xB0 до 0xBF маленькие от «а» до «п». Корректируем наш сотворенный битовый массив согласно кодировке и добавляем в хвост h-файла. Не забываем поправить служебные поля в начале.
Вуаля!
Ну и бонусом для тех кто дочитал до сего места ссылка на готовый файл шрифта:
Брать здесь: http://narod.ru/disk/47094865001.37fe25fb0ce3344acb820deb206144db/SystemRus5x7.h.html
0 комментариев на «“Русифицируем LCD экранчик 128х64, точнее библиотеку GLCD”»
Вот только шрифт на проверку оказался 5×7, что всплывает при попытке использования букв с «хвостами» типа «Д».