Обновление библиотеки вывода для дисплеев Nokia

Nokia 1100 - картинка 1

После того, как Валерий Гончаренко сделал приятный подарок в виде нескольких дисплеев Nokia, я немного переработал свою библиотеку вывода для дисплеев Nokia. Изменения коснулись обоих вариантов библиотеки, как графической (2.1), так и текстовой (1.1). В графический вариант внесено больше изменений, чем в текстовый, добавлены несколько новых функций.

Так как библиотеки разделены на два варианта, то имеет смысл рассказать об этом. Разделение на два варианта было сделано с целью экономии ресурсов там, где нам не нужны расширенные функции. В общем случае нумерация библиотек складывается следующим образом: номер варианта.номер версии.

Варианты и версии библиотеки

Текстовый вариант библиотеки имеет нумерацию 1.x и содержит только функции вывода на экран текстовой информации. Занимает в памяти программ минимум места и не создает никаких буферов в оперативной памяти. Содержит только функции вывода текста на экран. Рекомендуется для микроконтроллеров AVR с минимумом системных ресурсов (программной и оперативной памяти).

Второй вариант библиотеки — графический. Имеет нумерацию 2.x и содержит весь набор функций текстового варианта с добавлением функций для работы с графикой. В отличии от текстового варианта занимает намного больше памяти, как программной, так и оперативной. В оперативной памяти создается видеобуфер, содержащий копию того, что выведено на экран, так как дисплеи от Nokia позволяют только записывать данные в контроллер дисплея (хотя сам контроллер позволяет как записывать, так и читать данные). Буфер занимает в памяти 864 байта, плюс еще несколько переменных. Соответственно, применять этот вариант библиотеки можно на микроконтроллерах, которые имеют достаточное количество оперативной памяти.

Скорость работы

Основной претензией к работе библиотеки с экранами Nokia, в частности экраном Nokia 1100, было низкое быстродействие. Этот дисплей от Nokia 1100 можно было назвать супертормозным. Библиотека имеет параметр NLCD_MIN_DELAY (задается в файле nokia1100_lcd_lib.h). Это минимальная задержка при передаче байтов данных в контроллер дисплея. Так вот, в первой версии библиотеки (как 1.0, так и в 2.0) этот параметр имел значение 270 микросекунд для дисплея  Nokia 1100! Передача данных в контроллер дисплея была очень медленной. При меньшей задержке вывод на экран не работал. В отличии от 1100 в дисплеях Nokia 1202 можно было (да и сейчас это можно, и даже нужно) установить задержку в 0, после чего вывод на экран происходит мгновенно.

Во второй версии (именно версии, не варианте) библиотеки (1.1 и 2.1) ускорена работа с дисплеем, причем на порядок. Теперь минимальная задержка при передаче данных в контроллер 1100 — 34 микросекунды! Сравните: 270 было, 34 стало  (1202 работает при 0 — рекордсмен по скорости). Теперь вывод на экран стал намного более приемлемым. Реализовано это дополнительным командами инициализации.

Ошибка в видеобуфере

Так как изначально библиотека писалась под единственный имеемый в наличии дисплей Nokia 1100, то в расчетах при написании были допущены ошибки, которые устранены во второй версии библиотеки. Теперь размер буфера вычисляется автоматически по заданным параметрам. Сейчас можно задать параметр разрешения дисплея (файл nokia1100_lcd_lib.h) и использовать библиотеку с дисплеями с разным разрешением экрана, но со сходной системой команд.

Кодировка символов

Раньше вывод символов кириллицы был реализован частично в кодировке CP866. Теперь вывод символов реализован с кодировкой CP1251 (win1251), как более распространенной. Выводятся только символы кириллицы, псевдографика не выводится.Т.е. теперь не нужно подготавливать специальным образом строки для вывода кириллицы. Просто пишем nlcd_Print («Велик и могуч русский язык!»); и все работает корректно.

Про модификацию библиотеки под эту кодировку писал Maxim Grigorov в своем блоге. С точки зрения программиста изменения у него реализованы более грамотно, через функцию lcd_symbol_decode(c), но я сделал без функции, напрямую. Вызов функции занимает некоторое время (минимальное, но все же), а у меня пересчет идет прямо в процедуре вывода символа. Без всяких проверок на корректность данных, незачем тратить время на ерунду, мы не для настольных компьютеров быдлокодим программируем, нам каждый байт дорог :).

Вывод символов двойной ширины

В обоих вариантах библиотеки добавлена функция вывода символов двойной ширины. Функция может пригодится для вывода, например, каких-нибудь заголовков, названий и т.д. Сейчас думаю, нужна ли функция вывода символов двойной высоты. Место в памяти эта функция будет занимать, а необходимость ее использования сомнительна.

Прототип функции:

void nlcd_PrintWide(unsigned char * message);

Используется точно также как и nlcd_Print.

Тест широкого шрифта на экране Nokia 1100

Тест широкого шрифта на экране Nokia 1100

Тест широкого шрифта на экране Nokia 1202

Тест широкого шрифта на экране Nokia 1202

Разрешение экрана

потихоньку унивирсализируемся, ввел пару дефайнов, которые определяют разрешение экрана.

// Разрешение дисплея в пикселях
#define NLCD_X_RES    96        // разрешение по горизонтали
#define NLCD_Y_RES    68        // разрешение по вертикали

Работать с разрешением в функциях стало проще, теперь не надо править всю библиотеку под свой экран, если разрешение отличается от принятого в 1100 (96×65). Выше в примере заданы размеры экрана 1110i и 1202.

Вывод прямоугольника

Исправил ошибку в функции рисования прямоугольника. Проявлялась при рисовании с параметром наложения PIXEL_INV.

Вывод изображений

Ну и как же без вывода картинок. Написал первую версию этой процедуры. Куча ограничений. Практически никаких проверок на корректность данных. Зато работает очень быстро.

Долго сидел и думал, как ее написать. Можно написать при помощи функции nlcd_Pixel, т.е. выводить изображение попиксельно. Можно реализовать практически все проверки на корректность и т.д. Но работать будет очень долго. Это не наш путь.

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

Ограничения заключаются в том, что размер картинки по вертикали должен быть кратен 8. По горизонтали — без ограничений (в разумных пределах). Затем, координаты вывода левого верхнего угла картинки по вертикали опять же должны быть кратны 8. По горизонтали — без ограничений. Если функцию вызвать, например, с такими параметрами: nlcd_Pict (10,10,picture);, то картинка picture будет выведена по координатам: по горизонтали 10, во вертикали 8 (левый верхний угол картинки). Т.е. вертикальная координата приводится к значению, кратному 8.

Еще одно из ограничений в том, что картинка должна хранится в программной памяти, так как используется pgm_read_byte (). Думаю, что это логично, так как картинки занимают довольно много памяти, и хранить их в оперативке — не наш метод.

Картинки имеют следующий формат:

  • байт 0 — размер по горизонтали в пикселях (без ограничений, но в разумных пределах);
  • байт 1 — размер по горизонтали в пикселях (кратный 8);
  • далее массив данных побайтно (столбец из 8 бит) и построчно. Единица в значении бита говорит о том, что пиксел зажжен (светится).

Для подготовки данных, по подсказке Валерия Гончаренко (thanx), использую программу от Alex_EXE. После получения массива с данными картинки, добавьте в начало массива два байта с размером картинки по горизонтали и по вертикали (ну и размер массива нужно изменить на 2 байта).

Генератор картинок

Генератор картинок

В итоге должно получится что-то типа этого:

PROGMEM static const char nlcd_image[] =
{ 24,24,
0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0xE0, 0xE0, 0x60, 0x60, 0x60, 0x60,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
0x00, 0xE0, 0x78, 0x1F, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF,
0x01, 0xFF, 0xFE, 0xFF, 0xDB, 0xDB, 0xDB, 0x00, 0xFF, 0xC0, 0xC0, 0x00,
0x07, 0x07, 0x07, 0x06, 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x06, 0x07,
0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x07, 0x07, 0x02, 0x00};

Еще раз обращаю внимание, что картинки должны хранится в программной памяти. Не забываем!

Ну и вывод этой картинки выглядит так:

nlcd_Pict(40,8,nlcd_image);

Несколько примеров того, как выглядят изображения на экранах:

Nokia 1100 - картинка 1

Nokia 1100 — картинка 1

Nokia 1100 - картинка 2 - инверсная

Nokia 1100 — картинка 2 — инверсная

Nokia 1202 - картинка 1

Nokia 1202 — картинка 1

Nokia 1202 - картинка 2 - инверсная

Nokia 1202 — картинка 2 — инверсная

Ну и напоследок сравнение, как выглядит картинка на разных дисплеях.

Сравнение отображения экранов Nokia 1100 и 1202

Сравнение отображения экранов Nokia 1100 и 1202

На экране 1202 картинка чуть более контрастная, чем на 1100. Но сам экран чуть меньше, чем 1100. На фотке видно, что вертикальное разрешение у 1202 чуть больше, чем у 1100 (68 против 65).

Скачать вторую версию библиотеки можно на странице с описанием функций, но там надо откорректировать само описание. Сделаю это чуть позже. Наверно, если будет время.

 

Вливайтесь в обсуждение

  114 комментариев

Добавить комментарий

Отправляя комментарий, вы автоматически принимаете правила комментирования на сайте.

Правила комментирования на сайте:

  1. Не следует писать исключительно заглавными буквами. Это дурной тон.
  2. Запрещены комментарии не относящиеся к тематике сайта и самой статье.
  3. Запрещены реплики оскорбляющие других участников проекта. Давайте будем взаимовежливы.
  4. Запрещены нецензурные слова, идиоматические выражения, призывы к межнациональной и межконфессиональной розни.
  5. Запрещено обсуждение наркотических веществ и способов их применения.
  6. Запрещены комментарии с призывами к нарушению действующего законодательства РФ (Уголовного и Административного кодекса).
  7. Запрещены ссылки на сторонние ресурсы без согласования с владельцем сайта.
  8. Запрещается использовать в качестве имени комментатора слоганы/названия сайтов, рекламные фразы, ключевые и т.п. слова.

Следует учитывать следующее - все комментарии проверяются на предмет отсутствия спама. При обнаружении признаков спама, в оставленном Вами комментарии, сам комментарий будет незамедлительно удален, а Ваш IP-адрес будет добавлен в черный список без предупреждения!

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