Реализация меню на switch конструкции. Практический пример

Аппаратная часть

   Макет с микроконтроллером ATmega8535 со всей обвязкой, с присоединенным экранчиком, четырьмя кнопками (Up, Down, Enter, Cancel) и двумя светодиодами. Схему можно посмотреть здесь.

Кнопки имеют следующие функции:
Up – переместиться вверх по меню
Down – переместиться вниз по меню
Enter -  войти в пункт меню/ выполнить действие
Cancel – выйти из пункта меню

Структура меню

Структура меню имеет следующий вид.

структура меню

 

   В первом уровне осуществляется выбор светодиода, во втором выбор действия над ним. Каждый пункт меню имеет свой номер. Я сначала пронумеровал пункты первого уровня, затем второго – это не принципиально, но так удобнее расписывать дальнейший алгоритм.
 

Кнопки

 
   В таблице ниже расписаны переходы и действия, выполняемые при нажатии кнопок в конкретных пунктах меню.
таблица переходов для каждого состояния

 

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

Структура проекта

Проект состоит из следующий файлов.
menu1.asm – главный файл программы, к нему подключаются все остальные.
lcd.asm – содержит библиотеку подпрограмм для вывода на жки
lcd_user.asm – содержит подпрограммы вывода строк меню на жки
menu.asm – содержит макрос case и обработчики всех четырех кнопок
buttons.asm – инициализация и опрос кнопок
timers.asm – содержит подпрограмму инициализации и обработчик прерывания
led.asm – содержит подпрограммы управления светодиодами

Логика работы

   Логика работы программы проста как три копейки. В начале программы располагается таблица векторов прерываний, а за ней, после метки Reset, секция инициализации. Здесь мы инициализируем все, что нам потребуется для работы - стек, порты ввода/вывода, переменные в ОЗУ, жк экран, таймер Т0.
   Далее идет цикл Main в котором микроконтроллер без конца опрашивает кнопочный буфер. По сигналу прерывания таймера Т0 запускается подпрограмма DebriefButtons, которая осуществляет опрос кнопок. Внутри подпрограммы организована защита от дребезга. Если какая-то из кнопок будет нажата в течение 10-ти прерываний – ее номер помещается в буфер.
   В цикле Main расположен код диспетчера – он запускается, только если кнопочный буфер содержит номер одной из 4-ех кнопок. Диспетчер вызывает для каждой кнопки соответствующую подпрограмму-обработчик. Обработчики кнопок описаны в файле menu.asm и логику их работы мы подробно рассматривали в предыдущей статье.

   Вот собственно и все. По тексту программы расставлены дополнительные комментарии, надеюсь, разберетесь.

Заключение

Преимущества данного метода:

  • простота реализации
  • наглядность
  • возможность расширения


Недостатки:

  • большой объем кода
  • медленная скорость выполнения
   Скорость выполнения ограничена тем, что поиск нужной ветви обработчика осуществляется последовательным перебором. Можно прикинуть, сколько времени будет занимать обход всего обработчика, если в меню будет 100 пунктов.  

    cpi        - 1 такт
    brne     - 1 такт без перехода и 2 такта с переходом

   Итого – 300 тактов. При частоте микроконтроллера 16МГц – 300 тактов это – 18,75 мкс. Много это или мало? Смотря, для какого приложения. Как мне кажется -  программа меню быстрой реакции не требует, потому что ввод данных пользователем и вывод на экран осуществляется довольно медленно.

И напоследок

  • Пунктам меню лучше давать символические имена. Это более наглядно.
  • Вместо одной подпрограммы в ветви switch`а я бы рекомендовал использовать две. Одна для работы с экраном, а вторая для каких-нибудь дополнительных действий.

Схему можно посмотреть здесь. Файлы проекта здесь.