Главная > AVR > Драйвер для WH0802A (ICST7066U)

Драйвер для WH0802A (ICST7066U)

Уже сто лет в моих закромах валялся знакосинтезирующий дисплейчик от WINSTAR — WH0802A-YGH-CT, когда-то купленный как самый дешевый с целью поиграться. И вот я наконец-то извлек его из темных далей. Собственно, по этому поводу и был написан драйвер для него.

Как явствует из даташита, сей модуль собран на базе контроллера ICST7066U, система команд которого приведена там же. Уж не знаю, в какой степени он аналогичен HD44780, но четырехбитный режим тоже присутствует. Тем не менее, я решил отойти от мейнстрима и включить его в восьмибитном режиме. Управляющие выходы подключаются напрямую к порту МК (для экспериментов я использовал свою бессменную плату с ATmega48), восьмибитная шина данных — через сдвиговый регистр типа 74HC595 (DB0 — Q0, DB1 — Q1, и т.д.). Все это задефайнено в wh0802a.h:

#define LCD_PORT           PORTD
#define LCD_DDR            DDRD

#define LCD_RS             (1<<PD4)
//Assumed to be always '0' - no read from module
//#define LCDCTL_RW
#define LCD_E              (1<<PD3)
//Shift register signals
#define LCD_SHCP           (1<<PD7)
#define LCD_STCP           (1<<PD6)
#define LCD_DSER           (1<<PD5)

Из сигналов управления используется только E (enable) и RS (register select, переключатель команда/данные). RW постоянно подключен к земле — только запись. Как по мне, чем заморачиваться с чтением из дисплея, проще завести внутренний буфер, благо сам дисплей-то всего 8х2 символа.

Принцип управления прост до невозможности: сигналом RS выбираем, что писать — команду или данные, ну и пишем. Дисплей читает байт со входа по спадающему фронту сигнала E.

Команды и инициализационная последовательность описаны в даташите. Есть только одна заметная неясность — команда «Display ON/OFF control». Согласно таблице, она имеет следующий формат:

В описании же инициализации видим:

Опытным путем было установлено, что для включения дисплея и выключения всяких курсоров команда должна иметь вид 0х0С, т.е. 0000 1100. Так что, похоже, правда в таблице.

Сам драйвер минималистичен и прост, ничего лишнего. Инициализация, вывод строки, вывод числа, очистка дисплея, выбор строки, в которую писать, все с говорящими названиями и префиксом LCD_… . Отдельного упоминания, пожалуй, заслуживают только интегрированные функции преобразования числа в строку. Их две:

//Simple conversion function
//converts selected number of decimal places to chars,
//including sign if needed.
//leading zeroes are not suppressed.
//
//buf    - char buffer to write resulting string to
//num    - number to convert
//places - number of decimal places to convert
void _num_to_str(char *buf,int16_t num,uint8_t places);

//Advanced conversion function
//converts selected number of decimal places to chars,
//including sign if needed.
//Supports suppression of leading zeroes.
//
//buf    - char buffer to write resulting string to
//num    - number to convert
//places - number of decimal places to convert

//Uncomment this to show unary '+' if value is positive
//#define SGN_SHOW_POSITIVE       1

void _num_to_str_a(char *buf,int16_t num,uint8_t places);

Первая — совсем простая функция. Складывает указанное количество цифр числа в переданный буфер. Если цифр меньше указанного количества — добавляются нули. По необходимости добавляется минус (буфер должен быть достаточного размера, чтобы в этом случае его вместить).

Вторая более продвинута. Нули не добавляются, оставшееся перед числовой записью место заполняется пробелами. Место под знак резервируется всегда, так что по факту запись будет занимать на экране places+1 символ. Если раскомментировать дефайн SGN_SHOW_POSITIVE, знак перед числом (‘+’) будет добавлен, даже если число положительное — может быть удобно для разных вольтметров; иначе в этом случае добавляется пробел.

Одна из вышеописанных функций используется в LCD_PutInt(), и может быть заменена по вкусу — в исходнике есть обе. Дефайн CHARS_PER_INT перед LCD_PutInt() как раз и обозначает количество знакомест, отводимых под число (без учета знака; место под него резервируется неявно).

Скачать драйвер можно тут.

Рубрики:AVR
  1. 12/04/2013 в 11:16

    Тоже както баловался с дисплейчиком, и даже уговорил его писать по русски… (хотя у него нет встроенной кириллицы).
    http://asis-kbr.ru/forum/viewtopic.php?f=13&t=139

    • YS
      12/04/2013 в 18:26

      По-русски эт не тру.🙂 Я стараюсь по максимуму использовать английский, ибо только он корректно отображается везде.

  2. 16/08/2012 в 10:02

    А делал с ним что то типа USB-LCD ?
    lcd smart что ли прога … или библиотека я сейчас на отдыхе подсмотреть негде ссылку

    • YS
      16/08/2012 в 18:17

      Не. Пока просто поковырял. Глянул USB-LCD… Я бы сделал на FT232 через D2XX.

  3. YS
    15/08/2012 в 18:57

    Vga :

    Отклик у них в районе сотни миллисекунд или выше. Не в этом дело, а в том, что программа тупит в цикле ожидания задержки. Тогда как с чтением статуса можно немедленно вернуться из функции и ждать, если потребуется, только при следущем вызове перед обменом с индикатором.
    1.53мс не предел, кстати – при инициализации в некоторых местах нужно десятки мс ждать – хотя там и BUSY-флаг еще не работает.

    Так и пусть себе тупит — отрисовка данных всегда выполняется самым низкоприоритетным процессом, который прерывается чем угодно.

    Ну, там только в начале >40msec. А дальше 1.53msec таки и есть предел.

  4. Vga
    14/08/2012 в 22:47

    Как по мне, чем заморачиваться с чтением из дисплея, проще завести внутренний буфер, благо сам дисплей-то всего 8х2 символа.
    Ну, вообще-то, фреймбуфер в контроллере больше — 2х40 байт. К тому же, оттуда можно читать позицию курсора. Ну и главное — режим чтения позволяет читать BUSY-бит, без которого приходится везде задержки с запасом лепить.

    • YS
      14/08/2012 в 23:05

      Но физически-то используется всего 8х2. Как по мне, переписать все скопом будет быстрее (а главное — проще), чем возюкаться с регистрами.

      Курсор я просто отключил — в грядущем проекте он мне не нужен.

      В чтении BUSY не вижу особого смысла. Сам дисплей очень инерционен, это не TFT. Самая долгая команда исполняется за 1.53 msec, что, как мне кажется, сильно меньше времени, необходимого собственно для переориентации ЖК. Так что задерка 5 msec, которую я поставил, самое оно. Кстати, даже у ранних TFT-матриц отклик пикселя был как раз в райное 5msec. Так что, по сравнению с временем реакции стекляшки, это все равно очень быстро. Да и при этом весь дисплей обновится за 5*16=80 msec. Для такого дисплейчика вполне нормально, 1000FPS там ни к чему.

      • Vga
        15/08/2012 в 00:23

        Отклик у них в районе сотни миллисекунд или выше. Не в этом дело, а в том, что программа тупит в цикле ожидания задержки. Тогда как с чтением статуса можно немедленно вернуться из функции и ждать, если потребуется, только при следущем вызове перед обменом с индикатором.
        1.53мс не предел, кстати — при инициализации в некоторых местах нужно десятки мс ждать — хотя там и BUSY-флаг еще не работает.

  1. No trackbacks yet.

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

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s