Модули для текстового интерфейса пользователя (TUI) |
Автор ARV | |||||||
29.10.2009 г. | |||||||
Символьные ЖКИ широко применяются в любительских (и не только) разработках: они относительно недороги, удобны, экономичны, обладают высокой контрастностью, производятся многими иностранными и отечественными фирмами, например WinStar или МЭЛТ. Однако, разработчик непременно сталкивается с проблемой реализации на двух строках по 16 символов (наиболее "ходовая" конфигурация ЖКИ) удобного пользовательского интерфейса, который я условно называю TUI (Text User Interface) - по аналогии с GUI. Пользовательский интерфейс для портативных устройств, как правило, заключается в небольшом количестве кнопок для ввода информации пользователем и упомянутого ранее текстового ЖКИ для вывода информации. Разумеется, возможны варианты: энкодер, тачскрин и пр. Чаще всего ограничиваются 4-я кнопками и ЖКИ. Построению TUI именно для такой конфигурации и посвящен этот материал. Собственно говря, под интерфейсом следует понимать не только аппаратные средства, но так же и набор программных средств для программиста, которые позволяют реализовать неолбходимые функции взаимодействия программы с пользователем. Например, ввод и редактирование числовых параметров, изменение конфигурации, система меню и т.п. Не следует думать, что реализовать TUI несложно. Аппаратные ограничения в данном случае очень существенны: привычные для всех поля ввода не так-то просто сделать на микроконтроллере, да еще с ограниченным числом кнопок! Это вам не WinAPI, где на каждый чих пользователя уже имеется своя функция! Поэтому каждый программист в силу своих навыков и понятий об удобстве реализует TUI по-совему, причем зачастую заново для каждого очередного устройства. Я считаю, что это крайне неприятная ситуация - делать каждый раз одно и то же по-разному... И поэтому решил разместить кое-какие программные модули (частично завершенные, частично - заготовки), помогающие упростить разработку TUI. Эти и другие подобные вещи, так называемые библиотеки функций (хотя это и не совсем верное название), я буду помещать в специально созданный раздел файлового архива. В настоящее время там имеется 4 модуля для AVR-GCC:
Кроме модуля lcd (кстати, очень удобного - рекомендую!), автором которого является Я старался очень подробно комментировать все модули, поэтому, надеюсь, разобраться в них будет легко. Но тем не менее я кратко коснусь основных моментов по работе с ними.
Модуль buttons содержит средства опроса кнопок. Главная проблема в этом случае - борьба с дребезгом контактов - решена полностью. Так же модуль реализует функцию автоповтора, к которой мы все привыкли: если нажать и удерживать кнопку некоторое время, то возникнет эффект, как если бы кнопку стали нажимать часто-часто. Программисту требуется лишь реализовать по-своему функцию, возвращающую состояние кнопок get_key_code() (см. исходные тексты модуля) - все прочее реализовано внутри функции get_key(). То есть в основном цикле программы следует обращаться к функции get_key(), и она будет возвращать коды нажатых кнопок по нужному алгоритму (т.е. первое нажатие - немедленно, при удержании - через некоторую паузу). Модуль events - это пока лишь заготовка, а вообще он задуман как универсальный модуль обработки событий, чтобы работа с различными средствами ввода (кнопки, клавиатуры, энкодеры, тачскрины и т.п.) осуществлялась единообразно (отдаленная аналогия - сообщения в Windows). Наиболее функциональным на данный момент является модуль mmenu, при помощи которого можно реализовать многоуровненую систему меню на 2-строчном (и даже однострочном - если слегка модифицировать исходник) ЖКИ. При реализации этого модуля я стремился совместить функциональность с простотой и небольшим расходом памяти (как программной, так и ОЗУ). Без компромиссов не обошлось: наиболее красиво меню реализуются с применением объектно-ориентированного подхода на С++, но увы, как разобраться начинающему в этом языке, так и добиться минимальных издержек памяти в этом случае очень непросто. И поэтому все сделано при помощи традиционных массивов, хранящих структуры данных. Все типы данных определены в файле mmenu.h. Общий подход заключается в следующем. Меню представляет собой некоторое количество пунктов, т.е. тектовых строк, отображаемых на дисплее. Так как возможности ЖКИ ограничены, то в каждый момент времени в верхней строке ЖКИ отображается единственный пункт меню, а в нижней - краткая подсказка о назначении кнопок. Кнопок для работы с меню необходимо всего 4: две для перемещения между пунктами меню, одна - аналог кнопки ENTER (т.е. позволяет "выбрать" текущий пункт) и еще одна - аналог кнопки ESC (служит для "выхода" из меню без выбора какого-либо пункта). Каждый пункт меню может быть одного из трех типов:
При выбрре (т.е. при нажатии кнопки ENTER) простого пункта в программу пользователя возвращается определенный код, и остается лишь обработать его при помощи switch, выполнив необходимые действия. Если кнопка ENTER нажимается на пункте с подменю - происходит "погружение" внутрь этого самого подменю, по принципу обычного меню Windows (или, что более похоже, меню старых сотовых телефонов). Подменю, в свою очередь, так же может состоять из упомянутых трех вариантов пунктов. Вложенность этой системы меню теоретически может быть любой, но на практике увлекаться этим не стоит: во-первых, сложно ориентироваться в подобной системе, а во-вторых (и это более существенно), чем глубже погружаемся по меню, тем больше расходуется памяти, а она, как известно, у AVR очень невелика. Пункт-опция специально предназначен для управления какими-либо битовыми переключателями в программе, он реализует аналог "чекбокса" в Windows, т.е. выполняет функцию переключателя. В отличие от предыдущих типов пунктов меню, этот не имеет заранее предусмотренного текстового содержимого, а получает его непосредственно в динамике, т.е. текст пункта может меняться прямо во время работы с меню! Такой подход позволяет реализовать, например, индикацию состояния неких функций "Включено-Выключено". Другое отличие этого типа пункта от остальных в том, что нажатие кнопки ENTER не приводит к "выбору" этого пункта и возврата в основную программу. Вместо этого происходит вызов специальной функции (заранее предусмотренной программистом), которая изменяет состояние нужных переменных, т.е. изменение каких-либо параметров наступает немедленно (что может быть удобно для управления фоновыми асинхронными процессами, например, таймерами микроконтроллера). Чтобы было проще понять, о чем идет речь, я сделал в PROTEUS небольшую испытательную схемку и приложил к ней небольшой тестовый исходничек. Описывать его работу я не стану - там все просто, надеюсь, все желающие разберутся самостоятельно. В перспективе я планирую сделать модуль для редактирования числовых значений и текстовой информации, т.к. при помощи функции автоповтора нажатия кнопки "плюс" легко изменить число в пределах одного-двух десятков, но если требуется варьировать значение от 0 до нескольких тысяч (например) - этот метод совершенно непригоден из-за своей медлительности, тут необходимо поразрядное редактирование числа. Надеюсь, мои разработки кому-то пригодятся. Скачать их, как обычно, можно в файловом архиве. Обсудить материал на форуме. (32 сообщений) Добавить в любимые (2) | Просмотров: 29553
Только зарегистрированные пользователи могут оставлять коментарии. |
« Пред. | След. » |
---|