Модули для текстового интерфейса пользователя (TUI)
Автор ARV   
29.10.2009 г.

Символьные ЖКИ широко применяются в любительских (и не только) разработках: они относительно недороги, удобны, экономичны, обладают высокой контрастностью, производятся многими иностранными и отечественными фирмами, например WinStar или МЭЛТ. Однако, разработчик непременно сталкивается с проблемой реализации на двух строках по 16 символов (наиболее "ходовая" конфигурация ЖКИ) удобного пользовательского интерфейса, который я условно называю TUI (Text User Interface) - по аналогии с GUI.

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

Чаще всего ограничиваются 4-я кнопками и ЖКИ. Построению TUI именно для такой конфигурации и посвящен этот материал.

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

Не следует думать, что реализовать TUI несложно. Аппаратные ограничения в данном случае очень существенны: привычные для всех поля ввода не так-то просто сделать на микроконтроллере, да еще с ограниченным числом кнопок! Это вам не WinAPI, где на каждый чих пользователя уже имеется своя функция! Поэтому каждый программист в силу своих навыков и понятий об удобстве реализует TUI по-совему, причем зачастую заново для каждого очередного устройства.

Я считаю, что это крайне неприятная ситуация - делать каждый раз одно и то же по-разному... И поэтому решил разместить кое-какие программные модули (частично завершенные, частично - заготовки), помогающие упростить разработку TUI. Эти и другие подобные вещи, так называемые библиотеки функций (хотя это и не совсем верное название), я буду помещать в специально созданный раздел файлового архива. В настоящее время там имеется 4 модуля для AVR-GCC:

  • lcd - для поддержки HD44780-совместимых ЖКИ
  • buttons - для поддержки кнопок
  • events - для поддержки системы событий
  • mmenu - для организации системы меню

Кроме модуля lcd (кстати, очень удобного - рекомендую!), автором которого является Peter Fleury, а лишь чуть-чуть его модифицировал, все прочие модули - моя разработка, прошу не судить строго.

Я старался очень подробно комментировать все модули, поэтому, надеюсь, разобраться в них будет легко. Но тем не менее я кратко коснусь основных моментов по работе с ними.

Модуль buttons содержит средства опроса кнопок. Главная проблема в этом случае - борьба с дребезгом контактов - решена полностью. Так же модуль реализует функцию автоповтора, к которой мы все привыкли: если нажать и удерживать кнопку некоторое время, то возникнет эффект, как если бы кнопку стали нажимать часто-часто. Программисту требуется лишь реализовать по-своему функцию, возвращающую состояние кнопок get_key_code() (см. исходные тексты модуля) - все прочее реализовано внутри функции get_key(). То есть в основном цикле программы следует обращаться к функции get_key(), и она будет возвращать коды нажатых кнопок по нужному алгоритму (т.е. первое нажатие - немедленно, при удержании - через некоторую паузу).

Модуль events - это пока лишь заготовка, а вообще он задуман как универсальный модуль обработки событий, чтобы работа с различными средствами ввода (кнопки, клавиатуры, энкодеры, тачскрины и т.п.) осуществлялась единообразно (отдаленная аналогия - сообщения в Windows).

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

При реализации этого модуля я стремился совместить функциональность с простотой и небольшим расходом памяти (как программной, так и ОЗУ). Без компромиссов не обошлось: наиболее красиво меню реализуются с применением объектно-ориентированного подхода на С++, но увы, как разобраться начинающему в этом языке, так и добиться минимальных издержек памяти в этом случае очень непросто. И поэтому все сделано при помощи традиционных массивов, хранящих структуры данных.

Все типы данных определены в файле mmenu.h. Общий подход заключается в следующем.

Меню представляет собой некоторое количество пунктов, т.е. тектовых строк, отображаемых на дисплее. Так как возможности ЖКИ ограничены, то в каждый момент времени в верхней строке  ЖКИ отображается единственный пункт меню, а в нижней - краткая подсказка о назначении кнопок. Кнопок для работы с меню необходимо всего 4: две для перемещения между пунктами меню, одна - аналог кнопки ENTER (т.е. позволяет "выбрать" текущий пункт) и еще одна - аналог кнопки ESC (служит для "выхода" из меню без выбора какого-либо пункта).

Каждый пункт меню может быть одного из трех типов:

  1. Простой пункт
  2. Пункт с подменю
  3. Пункт-опция

При выбрре (т.е. при нажатии кнопки ENTER) простого пункта в программу пользователя возвращается определенный код, и остается лишь обработать его при помощи switch, выполнив необходимые действия.

Если кнопка ENTER нажимается на пункте с подменю - происходит "погружение" внутрь этого самого подменю, по принципу обычного меню Windows (или, что более похоже, меню старых сотовых телефонов). Подменю, в свою очередь, так же может состоять из упомянутых трех вариантов пунктов. Вложенность этой системы меню теоретически может быть любой, но на практике увлекаться этим не стоит: во-первых, сложно ориентироваться в подобной системе, а во-вторых (и это более существенно), чем глубже погружаемся по меню, тем больше расходуется памяти, а она, как известно, у AVR очень невелика.

Пункт-опция специально предназначен для управления какими-либо битовыми переключателями в программе, он реализует аналог "чекбокса" в Windows, т.е. выполняет функцию переключателя. В отличие от предыдущих типов пунктов меню, этот не имеет заранее предусмотренного текстового содержимого, а получает его непосредственно в динамике, т.е. текст пункта может меняться прямо во время работы с меню! Такой подход позволяет реализовать, например, индикацию состояния неких функций "Включено-Выключено". Другое отличие этого типа пункта от остальных в том, что нажатие кнопки ENTER не приводит к "выбору" этого пункта и возврата в основную программу. Вместо этого происходит вызов специальной функции (заранее предусмотренной программистом), которая изменяет состояние нужных переменных, т.е. изменение каких-либо параметров наступает немедленно (что может быть удобно для управления фоновыми асинхронными процессами, например, таймерами микроконтроллера).

Чтобы было проще понять, о чем идет речь, я сделал в PROTEUS небольшую испытательную схемку и приложил к ней небольшой тестовый исходничек. Описывать его работу я не стану - там все просто, надеюсь, все желающие разберутся самостоятельно.

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

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

Обсудить материал на форуме. (32 сообщений)


Добавить в любимые (2) | Просмотров: 24578

  Коментарии (3)
 1 Написал(а) Настоящее имя, в 17:19 17.01.2012
перекопал весь архив, но архива с исходником так и не нашел...
 2 Написал(а) Настоящее имя, в 17:22 17.01.2012
обновите ссылку, из форума скачалось...спасибо
 3 Написал(а) ARV, в 13:30 19.01.2012
не знаю, как вы искали... http://arv.radioliga.com/component/option,com_remository/Itemid,27/func,select/id,30/ здесь оно и есть

Только зарегистрированные пользователи могут оставлять коментарии.
Пожалуйста зарегистрируйтесь или войдите в ваш аккаунт.