воскресенье, 6 декабря 2009 г.

Библиотека для ЖК-дисплея WH1602b

После долгой кропотливой работы изучения документации и написания кода, родилась полезная и нужная для меня библиотека для работы с этим дисплеем. Возможно она окажется полезной кому-нибудь ещё :)
О дисплее
Дисплей этот я приобрёл на молотке около года тому назад, за почти астрономическую сумму в 450рэ. Ну тем не менее он устраивает меня во всём, и в быту неприхотлив=)
Особенности этой библиотеки
Код написан на ассемблере, и очень компактен. Занимает от 298 до 466 байт в памяти программ МК. В файле конфигурации wh1602b/conf.h можно дополнительно установить поддержку следующих функций:
  • Поддержка знакогенератора (298+52 байт)
  • Поддержка функции вывода десятичных чисел (298+66 байт)
  • Поддержка функции вывода шестнадцатеричных чисел (298+72 байт)
Основные функциональные возможности
  • Вывод строк, символов
  • Вывод чисел
  • Очистка дисплея
  • Управление курсором
  • Поддержка знакогенератора (до 8-ми знаков, согласно спецификации)
  • Настройка различных параметров работы
Не поддерживается:
  • Чтение памяти дисплея
  • Текущее положение курсора нельзя определить

Библиотека использует 4-битную шину для передачи данных.

Примеры использования

Простой пример:
#include "wh1602b/wh1602b.h"

int main(void)
{
  wh1602b_init(); // инициализировать модуль, порты
  // настроить параметры управления дисплеем
  wh1602b_displayctl(DC_DISPLAY_ON); // дисплей включён
  // задать число строк
  wh1602b_funcset(FS_LINES_2); // 2 строки
  // очистить область
  wh1602b_clear();
  // вывести строку на дисплей
  wh1602b_puts("Hello, World!");

  for (;;)
    ;
}
Результат:

Следующий пример демонстрирует возможность загрузки собственного знака:
#include "wh1602b/wh1602b.h"

// собственно массив представляющий собой
//  знак который надо загрузить
static const uint8_t window_char[8] = {
  0x1f, // 1 1 1 1 1
  0x11, // 1 0 0 0 1
  0x0e, // 0 1 1 1 0
  0x04, // 0 0 1 0 0
  0x0e, // 0 1 1 1 0
  0x15, // 1 0 1 0 1
  0x15, // 1 0 1 0 1
  0x00  // 0 0 0 0 0
};

int main(void)
{
  wh1602b_init(); // инициализировать модуль, порты
  // настроить параметры управления дисплеем
  wh1602b_displayctl(DC_DISPLAY_ON); // дисплей включён
  // задать число строк
  wh1602b_funcset(FS_LINES_2); // 2 строки
  // очистить область
  wh1602b_clear();
  // записать символ ассоциировав его с кодом 5
  wh1602b_genc(5, window_char);
  // вернуться в начало (команда аналогичная move).
  //   этот вызов является обязательным после вызова genc()
  wh1602b_home();
  // вывести строку на дисплей вместе с новым знаком :)
  wh1602b_puts("Крякозябла \5");

  for (;;)
    ;
}
Результат:

В качестве аргументов для wh1602b_puts и wh1602b_genc выступает указатель на строку расположенную в области RAM. Для того чтобы иметь возможность выводить строки из памяти программ, необходимо соответственно использовать wh1602b_putsP или wh1602b_gencP. Например:
#include "wh1602b/wh1602b.h"
#include <avr/pgmspace.h>

int main(void)
{
  <...>
  // вывести строку1 из памяти программ
  wh1602b_putsP(PSTR("Здравствуй"));
  // переместить курсор на заданную позицию (нумерация с нуля)
  wh1602b_move(1,4); // 2 строка, 5 столбец
  // вывести строку2 из памяти программ
  wh1602b_putsP(PSTR("Мир!"));
  <...>
}
Результат:


Как настроить библиотеку под себя
Для начала необходимо задать порты к которым подключён дисплей. Для этого необходимо отредактировать файл wh1602b/conf.h:
#define F_CPU 16000000 /* частота мк, Гц */

#define USE_PUTN /* включить поддержку wh1602b_putn() */
#define USE_PUTH /* включить поддержку wh1602b_puth() */
#define USE_GENC /* включить поддержку wh1602b_genc() */

/* ножки к которым подключены выводы RS, RW, EN */
#define NPIN_RS PB4
#define NPIN_RW PB3
#define NPIN_EN PB2

/* порты к которым подключены выводы RS, RW, EN */
#define PORT_RS _SFR_IO_ADDR(PORTB)
#define PORT_RW _SFR_IO_ADDR(PORTB)
#define PORT_EN _SFR_IO_ADDR(PORTB)
#define DDR_RS  _SFR_IO_ADDR(DDRB)
#define DDR_RW  _SFR_IO_ADDR(DDRB)
#define DDR_EN  _SFR_IO_ADDR(DDRB)

/* ножки к которым подключены выводы DB4-DB7 */
#define NPIN_DB7  PD7
#define NPIN_DB6  PD6
#define NPIN_DB5  PD5
#define NPIN_DB4  PD4

/* порты к которым подключены выводы DB4-DB7 */
#define PORT_DB7  _SFR_IO_ADDR(PORTD)
#define PORT_DB6  _SFR_IO_ADDR(PORTD)
#define PORT_DB5  _SFR_IO_ADDR(PORTD)
#define PORT_DB4  _SFR_IO_ADDR(PORTD)
#define DDR_DB7   _SFR_IO_ADDR(DDRD)
#define DDR_DB6   _SFR_IO_ADDR(DDRD)
#define DDR_DB5   _SFR_IO_ADDR(DDRD)
#define DDR_DB4   _SFR_IO_ADDR(DDRD)

Соответствующие ножки дисплея показаны на следующем рисунке:

Как компилировать программы написанные с использованием этой библиотеки
Существует ряд особенностей при компиляции программ использующих данную библиотеку. Дело в том что ЖК-дисплей понимает только строки написанные в своём собственном варианте кодировки. Поэтому компилировать надо с ключом -fexec-charset=wh1602b. При этом, в системе должен быть установлен специальный модуль для iconv - wh1602b. Готовые скомпилированный модуль можно скачать здесь (x86_64 и i686), или собрать его самостоятельно. Для установки необходимо скопировать файл WH1602B.so в папку с модулями gconv (у меня это /usr/lib/gconv), а также отредактировать файл /usr/lib/gconv/gconv-modules, добавив строчки:
# from      to      module    cost
alias WH-1602B//     WH1602B//
alias 1602B//       WH1602B//
module  WH1602B//    INTERNAL    WH1602B    1
module  INTERNAL    WH1602B//    WH1602B    1
Самостоятельная сборка такого модуля довольно кропотливая процедура, и будет описана в следующий раз.

Полный перечень поддерживаемых функций
  • void wh1602b_init()
    Выполняет инициализацию модуля дисплея.
  • void wh1602b_funcset(uint8_t t)
    Устанавливает число строк и размера шрифта. В качестве аргументов может служить комбинация одного или нескольких параметров:
    FS_LINES_2 - использовать две строки дисплея (по умолчанию одна строка, FS_LINES_1)
    FS_FONT_5x11 - использовать шрифт размером 5х11 (по умолчанию 5х8)
  • void wh1602b_entrymode(uint8_t t)
    Настраивает режима ввода. В качестве аргументов может служит комбинация одного или нескольких параметров:
    EM_CURSOR_DIR - использовать автоматическое перемещение курсора слева-направо
    EM_DISPLAY_SHIFT - разрешить смещение дисплея
  • void wh1602b_displayctl(uint8_t t)
    Устанавливает параметры управления дисплеем. В качестве аргументов может служит комбинация одного или нескольких параметров:
    DC_DISPLAY_ON - дисплей включён (по умолчанию выключен, DC_DISPLAY_OFF)
    DC_CURSOR_BLINK - использовать мигающий курсор
    DC_CURSOR_ON - использовать курсор
  • void wh1602b_puts(const char* s)
    Выводит строку s из RAM на дисплей.
  • void wh1602b_putsP(const char* s)
    Выводит строку s из памяти программ на дисплей.
  • void wh1602b_putn(uint16_t n)
    Выводит десятичное число n на дисплей.
  • void wh1602b_puth(uint8_t w, uint16_t h)
    Выводит шестнадцатеричное число h на дисплей. Ширина поля определяется параметром w
  • void wh1602b_genc(uint8_t n, const uint8_t* p)
    Записывает знак на который указывает p в знакогенератор. Если это последний записываемый знак, и при этом ожидается вывод на дисплей, то необходимо после выполнения genc вызвать wh1602b_home() или wh1602b_move().
  • void wh1602b_home()
    Возвращает курсор в начальное положение. Если дисплей при этом смещён то функция восстанавливает его.
  • void wh1602b_move(uint8_t r, uint8_t c)
    Перемещает курсор на заданную позицию (r - строка, c - столбец). Нумерация начинается с нуля.
  • void wh1602b_putc(uint8_t c)
    Выводит символ c на экран дисплея.
  • void wh1602b_clear()
    Очищает экран дисплея.
Скачать
Исходный код библиотеки вместе с примером можно скачать здесь.

13 комментариев:

Deus комментирует...

отличная библиотека!
спасибо!

anterior комментирует...

Рад что кому-то оказалась полезной!

DeusExMachina комментирует...

к сожалению, не могу воспользоваться
-fexec-charset=wh1602b
компилятор ругается

avr-gcc -fexec-charset=wh1602b -Wall -Os -fpack-struct -fshort-enums -funsigned-char -funsigned-bitfields -mmcu=atmega2560 -DF_CPU=16000000UL -MMD -MP -MF"main.d" -MT"main.d" -c -o"main.o" "../main.c"

cc1: error: conversion from UTF-8 to wh1602b not supported by iconv
пытался сохранять в других кодировках, то же самое. Ubuntu 9.10 AMD64

anterior комментирует...

> cc1: error: conversion from UTF-8 to wh1602b not supported by iconv
а если заменить "-fexec-charset=wh1602b" на любую последовательность, вроде "-fexec-charset=blablabla"... Та же ошибка? Значит вероятно в файле /usr/lib/gconv/gconv-modules не добавлены соответствующие строчки. Кстати, помоему в убунту этот файл где-то в другом месте распологается.

Предлагаю поискать файл gconv-modules в папке /usr/..

DeusExMachina комментирует...

в Ubuntu все также
/usr/lib/gconv/gconv-modules
даже есть версия 32 бита
/usr/lib32/gconv/gconv-modules
строки добавил даже в оба конфигурационных файла, но проблема осталась :(

DeusExMachina комментирует...

решил проблему запустив iconvconfig

anterior комментирует...

> решил проблему запустив iconvconfig
странно, но на моей системе этого не требовалось.

спасибо за комментарий, возможно кому-то эта информация может пригодиться.

Анонимный комментирует...

Уважаемый Антериор!

Не могли бы Вы перезалить свою библиотеку? Заранее спасибо.

IronCaterpillar комментирует...

Присоединяюсь к просьбе перезалить.

anterior комментирует...

все ссылки обновил

IronCaterpillar комментирует...

Гран мерси :)

Анонимный комментирует...

Спасибо!

IronCaterpillar комментирует...

А никто не пробовал iconv мучать под виндой? Под MinGW, например? А то грустно без родного языка. А в ручную таблички делать не хочется, когда уже есть готовые :)