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

Делаем меню для своего проекта на микроконтроллере
 Когда любой проект растет в функционале, и из простого показометра хочется сделать нечто большее, нужно придумать, как организовать удобную работу с устройством. Хорошо если в проекте задействован дисплей (графический, алфавитно-цифровой, да хоть семисегментный) тогда можно создать свое меню и рулить настройками оттуда.  Вот и попробуем организовать несложное древовидное меню из небольшого списка, с возможностью выбора любого пункта. Для начала необходимо определится с организацией и количеством пунктов меню и нарисовать структурную схему. Например, сделаем меню из 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
Просмотров: 42275 | Комментарии: 35 | Теги: atmega64, дисплей, Алгоритм, меню | Рейтинг: 4.8/18
Всего комментариев: 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)
на какой частоте работает микроконтроллер?

23 rus9892   (19.09.2013 10:18)
почем у меня пункты меню медленно вырисовываются на жк не подскажите ребята?

22 Zheckiss   (09.07.2013 17:26)
Гениально! Вы решили мою проблему! Спасибо!!!

21 max   (06.04.2013 17:17)
Антошин, вот это то, что тебе нужно:
http://avrproject.ru/publ....1-0-138

20 Антошин   (06.04.2013 16:25)
Хотелось бы тоже самое для камней по проще у которых Int0 и Int1,т.е еще две кнопки
повесить на обычные пины...Возможно ли?

19 exersizze   (02.01.2013 16:57)
Данные с часов принимаются в двоично-десятичном формате, возможно проблема в этом. Посмотри вот этот проект http://avrproject.ru/publ....1-0-110 там меню сделано по такому же принципу и добавлена работа с часами ds1307

18 shinkaruk-ivan   (02.01.2013 16:21)
Помогите у меня не получается добавить в этот проект часы реального времени,
или на дисплее какая то ерунда (часы искаженные, или на дисплее вообще ничего не показывает

17 DM   (25.12.2012 12:08)
ГЕНИАЛЬНО !!! С легкостью перевел это на СИ в CVAVR и работаю.

16 exersizze   (15.04.2012 10:55)
я не имел дело с такими дисплеями, поэтому подсказать не смогу.

15 sashashemelev1   (15.04.2012 08:56)
С построением меню разобрался. Только не получается на графическом LCD 128х64 не могу сделать меню с выделением символов инверсией. Подскажите...

14 sashashemelev1   (26.03.2012 18:12)
Спасибо! Теперь надеюсь разберусь.

13 exersizze   (26.03.2012 09:53)
код практически аналогичен переходу из главного меню в пункты подменю:
вход в подменю
Code
OK:
if A=13 then  
A=130
end if
return


курсор вниз

Code
DOWN:
if A=130 then
incr A
....
return

и так далее

12 sashashemelev1   (24.03.2012 17:15)
А можно кусочек кода увидеть, а то не догоню никак... BASCOM недавно стал использовать, не всё быстро доходит. Ещё написал кусок кода меню для GLCD128х64, но не знаю как в графическом виде это всё сообразить,в смысле хотелось бы символы на экране сделать инверсными.

11 exersizze   (24.03.2012 16:44)
можно сначала умножить переменную на 10, а затем ее инкрементировать. И тогда можно в этом пункте организовать еще 10 подпунктов (со значением переменной с 130 по 139)

10 sashashemelev1   (24.03.2012 14:45)
Как поступить, если мне нужно например из пункта 1.3 сделать ещё меню на 8 пунктов. Всю голову сломал - не получается никак....

9 exersizze   (23.10.2011 15:40)
Если понятен принцип того, как организовать меню, то уже дело вкуса как организован переход по пунктам. Способов на самом деле куча.

8 pchela5   (23.10.2011 14:52)
С меню очень доступно написано, но много лишних условий.
Можно ли сделать проще?
Например, так:
'Код обработчиков внешнийх прерываний
Ok: 'обработка нажатия кнопки "OK"

If(a Mod 10) = 0 Then
Incr A
Else
A = A * 10
End If

Return

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

If A > 100 Then
A = A / 10
Else
A = A / 10
A = Abs A ' если переменная integer то действие может быть лишним
A = A * 10
End If

Return

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

If(a Mod 10) = 0 Then

A = A + 10
Else
Incr A
End If

Return

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

If(a Mod 10) = 0 Then
A = A - 10
Else
Decr A
End If

Return

7 exersizze   (06.07.2011 23:21)
А это все зависит от того, что в этом цикле будет выполняться. Если простенький код и без больших задержек, то и для опроса кнопок можно выделить место в главном цикле. А если в цикле задержка в секунду или более, то до момента опроса кнопок может пройти немало времени. Ну их нафиг такие кнопки, которые не реагируют на нажатия. Или еще момент, есть например в нашем цикле проверка условия, по которому будет выход из этого цикла. И тогда все, до опроса кнопок дело так может и не дойти никогда, в общем жуть))
Решением может быть применение таймера: настраиваешь любой свободный таймер на прерывание по переполнению, и в обработчике прерывания производишь опрос кнопок. В независимости от того какой код будет выполняться, будет происходить прерывание по переполнению, а значит и опрос кнопок.

6 kestrel   (06.07.2011 20:07)
интересно, если кнопки не сажать на прерывания, а опрашивать их в основном цикле насколько это будет првильно (в плане правильности построения программы?) хотелось бы узнать ваше мнение, но это я так для себя. Да и еще если команду очистки дисплея поместить не в начале основного цикла, а в начале кода обработки нажатий кнопок Ok и Esc можно избежать неприятного моргания дисплея

5 AlekS   (06.07.2011 19:32)
Мы за тобой следим :-)

4 exersizze   (03.07.2011 19:03)
В планах было собрать регуль для двигателя использующий шим. Так что этот момент будет обязательно освещен в ближайшее время.

1-30 31-33
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]






   EasyEDA:  бесплатный редактор схем

   ✓ Создание схем
   ✓ Возможность симуляции
   ✓ Быстрое создание печатных плат
   ✓ Интуитивно понятный интерфейс

   Нарисуй свою схему прямо сейчас!
   Изготовление печатных плат   https://easyeda.com/order
авторизация
Логин:
Пароль:
Комментарии
Когда не хватает ног. Часть 2. Сдвиговый регистр 74HC595
08.12.2016 - exersizze:
yorx выдалось немного свободного времени, проверил в симуляторе. Проблема...
Логгер температуры 2.0
05.12.2016 - Evgeny6873:
Хотел повторить схему и долго ждал дисплей, два раза заказывал с Китая, пришел. ...
Когда не хватает ног. Часть 2. Сдвиговый регистр 74HC595
01.12.2016 - yorx:
Доброго времени суток, exersizze попробовал Ваш код все равно не работает как на...
Помни об усадке!
30.11.2016 - pchela5:
Автомобильные никакие не лезут?
Помни об усадке!
29.11.2016 - AlekS:
Виктор, спасибо.
С заменой транса в зиму, перестройка не комельфо) Валяет...
Управляем микроконтроллером с ПК по UART
29.11.2016 - exersizze:
Михаил, для работы с инфракрасными датчиками и диодами есть команды RC5SE...
Управляем микроконтроллером с ПК по UART
29.11.2016 - Михаил:
Всем привет.
Подскажите как переменную S передать по инфракрасному каналу...
Помни об усадке!
29.11.2016 - pchela5:
> Если ленту светодиодную порезать и соединить последовательно
Только ...
Когда не хватает ног. Часть 2. Сдвиговый регистр 74HC595
29.11.2016 - exersizze:
yorx, вывод Q7 ' первой микросхемы соединен с DS второй микросхемы? С...


Лучшие цены на 3D принтеры
успей сделать себе подарок к Новому Году! ;)


Prusa i3

Prusa i3 от 12500 р.



Rostoсk

Rostock от 15000 р.