Главная » Статьи » Проекты

Делаем меню для своего проекта на микроконтроллере
 Когда любой проект растет в функционале, и из простого показометра хочется сделать нечто большее, нужно придумать, как организовать удобную работу с устройством. Хорошо если в проекте задействован дисплей (графический, алфавитно-цифровой, да хоть семисегментный) тогда можно создать свое меню и рулить настройками оттуда.  Вот и попробуем организовать несложное древовидное меню из небольшого списка, с возможностью выбора любого пункта. Для начала необходимо определится с организацией и количеством пунктов меню и нарисовать структурную схему. Например, сделаем меню из 4-х пунктов, в каждом из которых по 3 подпункта, такую вот:
организация меню

 Для микроконтроллера каждый пункт это всего лишь переменная (А), которая меняется при нажатии кнопок и в зависимости от значения которой, на дисплей выводится информация или выполняется то или иное действие.  Кнопок, кстати всего 4: вверх (up), вниз (down), выбор (ok) и выход (esc). Сейчас подробно рассмотрим, что происходит с переменной при нажатии этих кнопок.

 При старте программы (или при входе в меню), переменной А присваивается значение 10, это соответствует первому пункту меню. При нажатии кнопки «Вниз», к  переменной прибавляется 10, и она становится равна 20, это соответствует второму пункту меню. Если еще раз нажать на эту кнопку, переменная станет равна 30, что будет соответствовать третьему пункту меню и так далее. Если нажать кнопку «Вверх» переменная будет уменьшаться на 10, до тех пор, пока не станет равна 10. Таким образом, организована навигация по главному списку меню.

 Для примера остановимся на первом пункте, и войдем в подменю первого пункта нажав кнопку "Вход". При этом к переменной прибавляется единичка и переменная становится равна 11. Это соответствует первому подпункту первого пункта меню %)
 Теперь если нажать на кнопку "Вниз" переменная будет увеличиваться на 1, пока не станет равна 13 (всего у нас 3 подпункта меню). Если нажимать на кнопку "Вверх" переменная будет уменьшаться на 1, пока не достигнет значения 11. Вот и организовали навигацию по пунктам подменю. Теперь, находясь в подменю, к примеру на пункте 1.1, если нажать кнопку "Ввод" переменная умножается на 10 и становится равна 110. 
При таком значении переменной вызывается подпрограмма 1.1, в которой совершаем какие нибудь действия. Выход организован проверкой значения переменной и присвоением переменной определенного значения. 
 Если все вышесказанное кажется бредом не совсем понятно, посмотри на рисунок ниже. Тут я на примере двух пунктов меню показал, как изменяется значение переменной и какие действия с ней происходят когда мы нажимаем на кнопки:

логика работы навигации по меню


Под каждую кнопку задействовано свое внешнее прерывание. Обработка нажатия кнопок у меня выглядит следующим образом:


Код обработчиков внешнийх прерываний
Ok:                                                         'обработка нажатия кнопки "OK"

If A = 11 Or A = 12 Or A = 13 Then
  A = A * 10
End If

If A = 21 Or A = 22 Or A = 23 Then
  A = A * 10
End If

If A = 31 Or A = 32 Or A = 33 Then
  A = A * 10
End If

If A = 41 Or A = 42 Or A = 43 Then
  A = A * 10
End If

If A = 10 Or A = 20 Or A = 30 Or A = 40 Then
  Incr A
End If

Return



Esc:                                                        'обработка нажатия кнопки "ESC"

If A = 11 Or A = 12 Or A = 13 Then
 A = 10
End If

If A = 21 Or A = 22 Or A = 23 Then
 A = 20
End If

If A = 31 Or A = 32 Or A = 33 Then
 A = 30
End If

If A = 41 Or A = 42 Or A = 43 Then
 A = 40
End If

If A > 100 Then
A = A / 10
End If

Return



Down:                                                       'обработка нажатия кнопки "DOWN"

If A = 10 Or A = 20 Or A = 30 Then
  A = A + 10
End If

If A = 11 Or A = 12 Then
  Incr A
End If

If A = 21 Or A = 22 Then
  Incr A
End If


If A = 31 Or A = 32 Then
  Incr A
End If

If A = 41 Or A = 42 Then
  Incr A
End If

Return



Up:                                                         'обработка нажатия кнопки "UP"

If A = 20 Or A = 30 Or A = 40 Then
 A = A - 10
End If

If A = 12 Or A = 13 Then
  Decr A
End If

If A = 22 Or A = 23 Then
  Decr A
End If

If A = 32 Or A = 33 Then
  Decr A
End If

If A = 42 Or A = 43 Then
  Decr A
End If
 
Return

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

  В главном цикле программы, в зависимости от значения переменной, будет происходить отрисовка меню и выполняемых операций. Тут все зависит от фантазии и применяемого дисплея.
В своем примере я применил алфавитно-цифровой 4-х строчный дисплей и микроконтроллер Atmega64. Почему такой жирный камень? Просто в нем есть необходимое количество внешних прерываний, и с ним нормально работает протеус. А вообще программа получилась размером чуть больше 4 кб, поэтому можно использовать контроллеры со значительно меньшей флэш памятью. А если сделать принудительный опрос кнопок, то не обязательно будет использовать микроконтроллер с большим числом внешних прерываний. В общем, на вкус и цвет... Схема подключения дисплея и кнопок ниже:



  Итак, при старте программы, переменная имеет значение 10. Это значение переменной соответствует первому пункту меню, нарисуем напротив этого пункта курсор. Например так:



 Код отрисовки выделения первого пункта меню у меня такой:

Подпрограмма вывода на дисплей выделения курсором первого пункта меню
10:                                   'подпрограмма отрисовки на дисплее выделения первого пункта

Lcd "label 1        <"                'в первой строке нарисовали курсор 
Lowerline                             'пишем на второй строке 
Lcd "label 2"
Thirdline                             'пишем на третьей строке
Lcd "label 3"
Fourthline                            'пишем на четвертой строке
Lcd "label 4"

Return                                'возвращаемся в основной цикл программы


 Теперь жмем на кнопку "Down", переменная увеличивается, и нужно нарисовать движение курсора вниз: остановимся например на третьем пункте, при этом значение переменной будет А=30:


Подпрограмма вывода на дисплей выделения курсором третьего пункта меню
30:                                   'подпрограмма при А=30

Lcd "label 1"                          
Lowerline                              
Lcd "label 2"
Thirdline                              
Lcd "label 3        <"                'курсор напротив третьего пункта
Fourthline                             
Lcd "label 4"

Return                                'возвращаемся в основной цикл программы
 

 Вот что будет на дисплее:


 При нажатии на кнопку "OK" переменная станет равна 31. На дисплее отобразится вход в подменю. В шапке отобразим родителя (пункт откуда пришли):

Подпрограмма вывода на дисплей выделения курсором третьего пункта меню
31:                                   'подпрограмма при А=31

Lcd "    label 3"                          
Lowerline                              
Lcd "label 3.1      <"
Thirdline                              
Lcd "label 3.2"               
Fourthline                             
Lcd "label 3.3"

Return                                'возвращаемся в основной цикл программы
 


 При повторном нажатии кнопки "OK" переменная станет равна 310, и произойдет выполнение подпрограммы, какой угодно, например просто выведем надпись "Run program 3.1" на дисплей: 


310:                                  'подпрограмма при А=310

Lcd "RUN PROGRAM  3.1"                'выводим надпись       

Return                                'возвращаемся в основной цикл программы
 


 При нажатии на кнопку "ESC" переменная изменится и произойдет выход из этой подпрограммы. Ну а дальше принцип думаю ясен. Как видишь, организовать свое меню, не такая уж непосильная задача как может показаться. Удачи!

Ниже можно скачать архив с моделью в Proteus, исходник и откомпилированный файл:

СКАЧАТЬ

UPD:  если нет протеуса, то для просмотра работы меню сгодится симулятор самого bascom-avr, как его заюзать писалось ранее





Категория: Проекты | Добавлено: 25.06.2011
Просмотров: 51390 | Комментарии: 35 | Теги: atmega64, дисплей, Алгоритм, меню | Рейтинг: 4.6/19
Всего комментариев: 331 2 »
33 rustr   (15.12.2013 11:40)
Нее, алгоритм понятен, даже для меня :-)
Я не могу придумать, как при A=, допустим 0 (при старте) вызывать меню нажатием кнопки "Ok" и далее по алгоритму и при выходе снова присваивать А=0

32 exersizze   (12.12.2013 13:39)
А в чем проблема? с алгоритмом или с обработкой кнопки при нажатии. Если проблема с алгоритмом посмотри вот этот проект http://avrproject.ru/publ/logger_temperatury_2_0/1-1-0-134 там как раз меню у меня организовано для настроек разных. Суть там вся в следующем: есть переменная Z,  и стоит проверка этой переменной в главном цикле. Если она равна нулю тогда на дисплей выводятся показания датчиков и прочая рабочая информация. При нажатии на кнопку "ОК" переменная Z становится равна 1 и при следующей проверки этой переменной на дисплей выводится первое окно менюшки  (см файл Menu.bas) Ну и так далее нажимая кнопки, эта переменная меняется и на дисплей выводится соответствующая информация.

31 rustr   (11.12.2013 22:13)
Пытаюсь, опыта не хватает.
Например, никак не могу придумать, как вызывать меню при нажатии на кнопку Ok

30 exersizze   (09.12.2013 08:34)
Дело в том что влево/вправо да и любая комбинация добавляется аналогично тому что приведено в примере, нужно просто немного подумать и вникнуть в идею.

29 rustr   (06.12.2013 11:53)
Здравствуйте.
Пытаюсь приспособить Вашу идею под свои нужды, возник вопрос - а как можно добавить в Ваш код обработку кнопок "Влево" и "Вправо"?

28 exersizze   (31.10.2013 19:50)
Обычно сначала вникают в алгоритм чтобы переписать на другой язык, могу посоветовать сделать также.

27 shansov   (31.10.2013 14:49)
Подскажите как перевести на СИ?

26 exersizze   (19.09.2013 18:48)
В железе не должно ничего мигать, текст выводится на дисплей быстро. Проверьте правильность выставленных фьюз, может частота работы стоит на самом деле ниже 16МГц
И попробуйте убрать команду Cls  в коде перед строками вывода строк на дисплей.

25 rus9892   (19.09.2013 13:53)
на 16Мгц

24 exersizze   (19.09.2013 10:50)
на какой частоте работает микроконтроллер?