Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Система меню
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
haker_fox
Здравствуйте! Ни кто не ткнет ссылкой на исходники меню для встраиваемых систем? Разработал для своего девайса подсистему меню и вот теперь хочу поглюдеть на чужие творенья, т.к. считаю, что мой код не оптимальный. Устройства ввода-вывода у меня чрезывачайно "приметивные": пять кнопок и десятиразрядный семисегментный ЖКД с микроконтроллером. Управляющий МК ATmega8-16PI.

Искал в нете, но ничего путнего не нашел: все для компьютера. Плохо искал значит biggrin.gif
BVU
Цитата(haker_fox @ Oct 25 2005, 11:38)
Здравствуйте! Ни кто не ткнет ссылкой на исходники меню для встраиваемых систем? Разработал для своего девайса подсистему меню и вот теперь хочу поглюдеть на чужие творенья, т.к. считаю, что мой код не оптимальный. Устройства ввода-вывода у меня чрезывачайно "приметивные": пять кнопок и десятиразрядный семисегментный ЖКД с микроконтроллером. Управляющий МК ATmega8-16PI.

Искал в нете, но ничего путнего не нашел: все для компьютера. Плохо искал значит  biggrin.gif
*

Что Вы конкретно хотели бы узнать (концепции построения, структура, код, дизайн)?
Как правило это все назавается GUI или UI в зависимости от реализации применения. К тому же является одной из стратегий и фирменным отличием для производителя ПО (так что такие, особенно профессиональные публикации - редкость). Всегда лучше разрабатывать свое, беря за основу концепции построения наиболее полностью удовлетворяющие функциональные потребности проекта.
haker_fox
Цитата
Что Вы конкретно хотели бы узнать (концепции построения, структура, код, дизайн)?
Как правило это все назавается GUI или UI в зависимости от реализации применения. К тому же является одной из стратегий и фирменным отличием для производителя ПО (так что такие, особенно профессиональные публикации - редкость). Всегда лучше разрабатывать свое, беря за основу концепции построения наиболее полностью удовлетворяющие функциональные потребности проекта.


Трудно сказать, что мне надо, пажалуй все по этой теме. Как я уже писал мне просто хочется взглянуть на чужую работу. Графический интерфейс мне пока не нужен. У меня меню, типа как в китайских часах, но может чуть посложнее. Я его уже сделал, но хотел бы посмотреть как это делают другие. Но раз это такая редкость, не страшно - ведь меню-то я сделал.
andrvisht
Цитата(haker_fox @ Oct 25 2005, 10:38)
Здравствуйте! Ни кто не ткнет ссылкой на исходники меню для встраиваемых систем? Разработал для своего девайса подсистему меню и вот теперь хочу поглюдеть на чужие творенья, т.к. считаю, что мой код не оптимальный. Устройства ввода-вывода у меня чрезывачайно "приметивные": пять кнопок и десятиразрядный семисегментный ЖКД с микроконтроллером. Управляющий МК ATmega8-16PI.

Искал в нете, но ничего путнего не нашел: все для компьютера. Плохо искал значит  biggrin.gif
*


Гляди в почте мой вариант smile.gif Только он под обычный ЖКД но структура сходная...
GeorgyBey
Нажмите для просмотра прикрепленного файла
Цитата(haker_fox @ Oct 25 2005, 10:38)
Здравствуйте! Ни кто не ткнет ссылкой на исходники меню для встраиваемых систем? ...
*



А в исходниках к Баттерфляю? "AVR_Butterfly_application_rev06.zip"
BVU
Посмотрите следующие сайты различных проектов:
http://www.microsyl.com/
http://www.tietomyrsky.fi/projektit/aOS/aO...n.htm#_Toc72110
http://www.myplace.nu/avr/index.htm
и вообще смотрите проекты, где присутствуют средства индикации с возможностью установки параметров, а так же дальнейшего их просмотра.
prottoss
Я делал меню для граф.ЖКИ.
Описывал все пункты вот такой структурой:

typedef struct Menu_Item_Type Menu_Item;

struct Menu_Item_Type
{ CONST_CHAR *icon; // адрес пиктограммы
CONST_CHAR *help; // адрес текстового пояснения к меню

// указатели на соседние с данным пункты меню
MENU_ITEM *left; // если смежных пунктов с данным нет, должен указывать на самого себя
MENU_ITEM *right; // если смежных пунктов с данным нет, должен указывать на самого себя
MENU_ITEM *up; // если родительских пунктов нет, должен быть равен NULL
MENU_ITEM *down; // если нисходящих пунктов нет, должен быть равен NULL

int flags; // флаги
void (*metod)(); // функция, выполняющаяся при условиях, установленных флагами
};
haker_fox
Всем спасибо!
GrayCat
Вдогон к сказанному prottoss:

Из подобных записей организуется таблица. Кроме того, заводится указатель Menu_Item *CurrentItem, котрый указывает на строку таблицы с текущим выбранным пунктом (работа с "готовым" указателем быстрее и короче вычисления адреса по индексу массива при каждом обращении). Для переключения пунктов вводится процедура int SwitchMenu(int NewMenu), котрая проверяет допустимость переключения, устанавливает *CurrentItem, выполняет всякие дополнительные действия типа уведомления других процессов о переключении, перерисовки экрана и т.п.

Иногда в состав struct Menu_Item_Type приходится включать указатели на процедуры обработки кнопок и вывода на экран, чтобы в каждом пункте они выполнялись по-своему.
-Tумблер-
Цитата(haker_fox @ Oct 25 2005, 11:19)
Трудно сказать, что мне надо, пажалуй все по этой теме. Как я уже писал мне просто хочется взглянуть на чужую работу. Графический интерфейс мне пока не нужен.
*


Совсем простой вариант - и по быстрому:
.
.
.
for (;;)
runfor

type_crlf (line);
outstr ("0. TEST RS-485\r\n", line);
outstr ("1. TEST R-29 INC\r\n", line);
outstr ("2. TEST R-29 FLOAT 1\r\n", line);
outstr ("ESC- EXIT\r\n", line);
outstr ("^C - MAIN MENU\r\n", line);
type_crlf (line);

for (j=0; j leq 0;)
run1
b =getbyte (line);
switch ( b )
runswitch

case space:
case cr:
j=1;
break;

case '0':
rs485_menu ();
j=1;
break;

case '1':

test_r29_inc ();
j=1;
break;

case '2':
test_r29_f (1);
j=1;
break;

case esc: return;

case ctlc:
ret_main_menu ();

endswitch
end1
endfor
.
.
.
_artem_
Statya po GUI dlya embedded systems. Ne sovsem primitivnaya i ne ochen optimizirovannaya.

Ochen legko menyu delat pri pomosi rekursivnix funkciy . No pri bolsom urovne vlozeniy problemi so stekom ne minovat.
haker_fox
Спасибо Вам всем большое за ответы!
bialix
Цитата(_artem_ @ Oct 29 2005, 07:27)
Statya po GUI dlya embedded systems. Ne sovsem primitivnaya i ne ochen optimizirovannaya.

Ochen legko menyu delat pri pomosi rekursivnix funkciy . No pri bolsom urovne vlozeniy  problemi so stekom ne minovat.
*


Рекурсивные функции? Этоплохой тиль и не пример для подражания.

Учитывая, что меню живет в человеческом реальном времени и между обновлениями экрана будут проходить сотни мс, то наиболее оптимально строить поддержку меню, точнее пользовательского интерфейса, включая кнопки, индикацию, попискивание и т.п., на основе конечных автоматов.
haker_fox
Цитата
Рекурсивные функции? Этоплохой тиль и не пример для подражания.

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


Не разу еще не использовал рекурсии, не на PC не в embedded. Но чутье подсказывает, что рекурсия будет жрать стек, как уже выше сказал _artem_. Я создал свое меню, на основе переключателя switch, примерно так
while(menu_rk!=CANCEL_KEY) //пока не нажали "Отмена"
{
switch(menu_root_ptr) //в зависимости от указателя меню
{
case 0: //показываем соответствующий пункт, тут же, если была нажат клавиша "Вход" вызываем функцию подменю, для настройки некого параметра (например времени)

case 1:

case 2:
.....................
}
menu_rk=read_key(); //читаем код нажатой клавиши
switch(menu_rk)
{
//здесь тоже в зависимости от нажатой клавиши выполняем некие действия (изменяем указатель menu_root_ptr и др)
}
}
Sergey'F
Еще такой совет - так как большая часть действий в интерфейсе с несколькими клавишами для большинства пунктов меню в значительной степени совпадает (обновление индикации, переход по меню и т.д.), то для избежания длинных switch можно завести массивы указателей на функции и выбирать по текущему индексу меню

Код
//вывод на индикатор в большинстве случае одинаковый - строка из массива
void fsmDefault();
void fsmeSetStart();
menu_handler code ShowMenu[cMenuItems] = {
    fsmDefault,      fsmeSetStart,
    ...
}

//на Enter переход вниз в большинстве случаев
void fceDefault();
void fceeSetStart();
menu_handler code CheckEnter[cMenuItems] = {
    fceDefault,      fceeSetStart,
    ...
}

То есть если нужно просто перейти вниз по нажатию Enter, это делает Default(), а если нужно что-то еще сделать, то
void fcceSetStart()
{
    ... //Do something
    fceDefault();
}

А дальше в программе просто
//check keys
switch (key)
{
case kbEnter: (CheckEnter[hMenu])(); break;
case kbUp: ...
...}
//update ind
(ShowMenu[hMenu])();
_artem_
Rekursiya ochen elegantnoe resenie dlya prostix menyu , v prtotivnom sluchae vam pridetsya ili dla kazdogo vidgeta ego view state pisat (polozenie, fokus ..) ili ze rezervirovat dinamiceski strukturu dlya etogo posredstvom malloc ili tomu podobnoe . No pri rekusrii nelzja ubivat okna kotorie gde to poseredine dereva gui .

Da ese nasel , vot posmotrite po etoy ssilke . On vidgeti sam napisal . Mozno ego kak ideyu dlya tekstovoy gui ispolzovat . Edinstvennoe avtor tam menu ispolzuet iz windoza a vse ostalnie widgeti delaet sam . Po moemu xorosiy source dlya osmisleniya vnutrennostey gui .

http://utenti.lycos.it/dcg/alfagui.html
bialix
Цитата(_artem_ @ Oct 29 2005, 21:50)
Rekursiya ochen elegantnoe resenie dlya prostix menyu , v prtotivnom sluchae vam pridetsya ili dla kazdogo vidgeta ego view state pisat (polozenie, fokus ..) ili ze rezervirovat dinamiceski strukturu dlya etogo posredstvom malloc ili tomu podobnoe . No pri rekusrii nelzja ubivat okna kotorie gde to poseredine dereva gui .


Не уверен я насчет элегантности. Даже в виндовсе не используется рекурсия для построения графического интерфейса. Там используются callback функции. Рекурсия очень плохая штука, если у вас многозадачная система. Редкая система может быть однозадачной, а при построении пользовательского интерфейса я себе плохо представляю как ее можно нормально сделать не многозадачной и при этом не только заниматься рисованием менюшек, но еще и производить обмен по паре-тройке интерфейсов, производить измерения в каналах АЦП и выводить результаты на экран, не говоря про то, что органы управления (кнопки или проч.) надо тоже опрашивать.

"Баба-яга против" (с)
haker_fox
Вот решил выложить свое творение, может быть кто и оценит, если есть свободное время. Конечно там до оптимизации далеко, но это первый опыт!
_artem_
Цитата(bialix @ Oct 31 2005, 01:15)
Не уверен я насчет элегантности. Даже в виндовсе не используется рекурсия для построения графического интерфейса. Там используются callback функции. Рекурсия очень плохая штука, если у вас многозадачная система. Редкая система может быть однозадачной, а при построении пользовательского интерфейса я себе плохо представляю как ее можно нормально сделать не многозадачной и при этом не только заниматься рисованием менюшек, но еще и производить обмен по паре-тройке интерфейсов, производить измерения в каналах АЦП и выводить результаты на экран, не говоря про то, что органы управления (кнопки или проч.) надо тоже опрашивать.

"Баба-яга против" (с)
*


Pod elegantnostyu ya imel vvidu prostotu. V windows i drugix GUI sistemax konechno nelzya ispolzovat rekursiyu. Ya popdrazumeval tekstoviy LCD i obyazatelnoe ispolzovanie RTOS'a - mozno odnu zadachu s nizkim prioritetom videlit na nee, pri uslovii esli razmer dereva menyu izvesten ( kolichestvo urovney) chtobi izbezat perepolneniya steka.
Chto libo bolee seryeznoe uze ne predpolagaet ispolzovanie rekursii.
ObitJr
Цитата(bialix @ Oct 31 2005, 01:15)
Цитата(_artem_ @ Oct 29 2005, 21:50)
Rekursiya ochen elegantnoe resenie dlya prostix menyu , v prtotivnom sluchae vam pridetsya ili dla kazdogo vidgeta ego view state pisat (polozenie, fokus ..) ili ze rezervirovat dinamiceski strukturu dlya etogo posredstvom malloc ili tomu podobnoe . No pri rekusrii nelzja ubivat okna kotorie gde to poseredine dereva gui .


Не уверен я насчет элегантности. Даже в виндовсе не используется рекурсия для построения графического интерфейса. Там используются callback функции. Рекурсия очень плохая штука, если у вас многозадачная система. Редкая система может быть однозадачной, а при построении пользовательского интерфейса я себе плохо представляю как ее можно нормально сделать не многозадачной и при этом не только заниматься рисованием менюшек, но еще и производить обмен по паре-тройке интерфейсов, производить измерения в каналах АЦП и выводить результаты на экран, не говоря про то, что органы управления (кнопки или проч.) надо тоже опрашивать.

"Баба-яга против" (с)
*



Что Вы понимаете под многозадачностьсю ?
haker_fox
Цитата
Что Вы понимаете под многозадачностьсю ?


Наверно тут все-таки говорится не о многозадачности как таковой, т.е. о выделении отдельных задач, их переключении, сохранении контекста и т.д. А о своеобразной псевдомногозадачсти (прошу прощения за такое выражение). Здесь я полностью согласен с bialix. Действительно, нужно и меню выводить, и (в моем случае) температуру измерять, да еще и за UART'ом следить. Но не встраивать же туда ОС. Просто, в холостом цикле опрашиваются кнопки для нужд меню + вызывается функция снятия показаний с термодатчиков + функция обработки сообщений от UART. И все отлично работает. В прилагаемых мной исходниках (выше на странице) это видно, там вызывается функция msr_wake_service(), которая опрашивает датчики и выполняет сервис связи по UART.
Ну и конечно прерывания от таймера используются, а кудаж без них:-)
GrayCat
Цитата(ObitJr @ Oct 31 2005, 13:43)
Что Вы понимаете под многозадачностьсю ?
*

Например, простенькая "кооперативная" многозадачность а-ля Salvo или JacOS. Что интересно -- работает!!! blink.gif biggrin.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.