реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Реализация меню для работы со знакосинтезирующим ЖКИ, Поделитесь опытом. Пожалуйста.
Alex2578
сообщение Aug 6 2007, 13:34
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 20-02-07
Пользователь №: 25 515



Всех приветствую.

Поделитесь пожалуйста опытом, кто как организует меню для работы со занакосинтезирующим ЖКИ.

Задача:
- просмотр информации о состоянии чего-либо;
- внесение данных, типа калибровка и т.д.;
- кофигурирование;
- ну и чего-нибудь еще....

Думаю, в глубину будет уровня 3-4, не больше.

С чего начать? Как организовать иерархию?

Прошу пардон, но на этот момент вопросы только общие, более конкретные, быть может, появятся позже.

Спасибо.
Go to the top of the page
 
+Quote Post
GDI
сообщение Aug 6 2007, 14:01
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



В исходниках программ и библиотек смотрели уже?
http://electronix.ru/forum/index.php?showtopic=10934


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
man with no name
сообщение Aug 6 2007, 14:44
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 158
Регистрация: 6-08-07
Из: Moscow
Пользователь №: 29 586



Можно делать следующим образом: описываем структуру одного элемента меню, в которой пишем строку и указатель на функцию, которая вызывается по нажатию кнопки enter или подобной.
Код
typedef struct
{
  char menu_str[LCD_WIDTH+1];
  MENU_HANDLER_PROC func;
} S_MENU_ITEM;


MENU_HANDLER_PROC - тип-функция void func(void). описывается как
typedef void (*MENU_HANDLER_PROC)(void);

делаем процедуру вывода меню на экран
Код
void ShowMenu(S_MENU_ITEM *menu, int element0, int cursor_pos)
{
  ...
}


тогда процедура самого меню будет выглядеть примерно так:
Код
void Menu(S_MENU_ITEM *menu)
{
  char ret_menu = 0;
  int cursor = 0;
  int element0 = 0;
  while (!ret_menu)
  {
    ShowMenu(menu, element0, cursor);
    switch(ch)
    {
    case VK_UP:
      // перемещаем вверх курсор, если он не 0, либо первый выводимый элемент меню (element0)
      // ...
      break;
    case VK_DOWN:
      // то же самое, только с точностью до наоборот
      // ...
      break;
    case VK_ENTER:
      menu[element0+cursor].func();
      break;
    case VK_EXIT:
      ret_menu = 1;
      break;
    }
  }
}


а в обработчиках рекурсивно запускаем эту же функцию Menu, но с другими параметрами.

Можно и по-другому, но я делал так. Только структуры хранил во флэше. Отличается только запуск функции-обработчика и вывод строки (а он здесь и не описан).
Go to the top of the page
 
+Quote Post
Alex2578
сообщение Aug 7 2007, 03:54
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 20-02-07
Пользователь №: 25 515



Цитата(GDI @ Aug 6 2007, 18:01) *
В исходниках программ и библиотек смотрели уже?
http://electronix.ru/forum/index.php?showtopic=10934


Смотрел. одно сообщение нашел.
Go to the top of the page
 
+Quote Post
GDI
сообщение Aug 7 2007, 14:24
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Вот тема как нельзя кстати всплыла http://electronix.ru/forum/index.php?showtopic=23625


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
VDG
сообщение Aug 11 2007, 13:21
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 845
Регистрация: 10-02-06
Пользователь №: 14 193



Цитата(Alex2578 @ Aug 6 2007, 17:34) *
Поделитесь пожалуйста опытом, кто как организует меню для работы со занакосинтезирующим ЖКИ.

Использую "оконные" процедуры и систему сообщений наподобие Windows.


--------------------
Go to the top of the page
 
+Quote Post
Aesthete Animus
сообщение Dec 18 2007, 10:09
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 222
Регистрация: 9-06-07
Пользователь №: 28 317



Имеется мега16 с подключенными к ней двухстрочным LCD и мартицей кнопок 2х3. Нужно написать достаточно сложную иерархическую менюшку. Подскажите, как это лучше реализовать? Сейчас я это сделал целиком на case`ах, т.е. в зависимости от кадра, в котором нахожусь, я анализирую варианты нажатия кнопок, что - то вроде этого:

Код
switch (frame_index)
{                
    ....
    
    case FRAME_SET_TIME:
    case FRAME_SET_DATE:
        switch (button_mask)
        {
            case BTN_YES:    
                if(systime_set(&systime_input))
                {// Неправильный ввод    
                    // Если время введено неправильно,
                    // то возвращаться следует в этот кадр
                    stack_push(&frame_stack,frame_index);
                    frame_index = FRAME_INVALID_DATA;
                }
                else
                    frame_index = FRAME_SET_DONE;
                
                print_flag = 1;
                break;
                
            case BTN_NO:
                frame_index = stack_pop(&frame_stack);
                print_flag = 1;
                break;
    ...    
}


Оно работает вполне неплохо, но уж слишком большого размера получается и код и прошивка. Добавить какой-то новый пункт - очень трудоемкая задача.

Есть некоторые мысли, что бы сделать что-то типа шаблона меню а также некоторые более идиотские идеи. Но возникает сомнение, не сожрет ли такая обработка все ресурсы (скорее всего срам память) контроллера? Подскажите, кто сталкивался с такой задачей?
Go to the top of the page
 
+Quote Post
umup
сообщение Dec 18 2007, 10:16
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 226
Регистрация: 2-06-06
Пользователь №: 17 720



сделать массив struct-ов, в каждом - текст пункта меню, тип (unsigned/signed 8-,16-,32-bit, string, список) и адрес переменной, которая отображается в этом пункте. каждому пункту присвоить уникальный номер и номер группы (подменю), в которую входит данный пункт. навигация и редактирование в таком варианте очень простые.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Dec 18 2007, 10:25
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Aesthete Animus @ Dec 18 2007, 14:09) *
Имеется мега16 с подключенными к ней двухстрочным LCD и мартицей кнопок 2х3. Нужно написать достаточно сложную иерархическую менюшку.

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


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Aesthete Animus
сообщение Dec 18 2007, 10:30
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 222
Регистрация: 9-06-07
Пользователь №: 28 317



Цитата(umup @ Dec 18 2007, 13:16) *
сделать массив struct-ов, в каждом - текст пункта меню, тип (unsigned/signed 8-,16-,32-bit, string, список) и адрес переменной, которая отображается в этом пункте. каждому пункту присвоить уникальный номер и номер группы (подменю), в которую входит данный пункт. навигация и редактирование в таком варианте очень простые.

У меня была такая мысль. Но меня настораживает вопрос, сколько памяти съест такая реализация и как быстро это будет работать (хотя, это менее критично)?
Go to the top of the page
 
+Quote Post
umup
сообщение Dec 18 2007, 10:57
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 226
Регистрация: 2-06-06
Пользователь №: 17 720



Цитата
сколько памяти съест такая реализация

ну посчитайте - сколько текста и данных на каждый пункт меню, плюс логика - навигация очень немного (фактически переход на следующий/предыдущий пункт с проверкой находится ли след.пункт в одном подменю с предыдущим, и переход в другое подменю по номеру), редактирование параметров - немного больше. думаю по коду в 0.5 - 1 килобайт можно уложиться. по быстроте вообще проблем быть не должно - состояние изменяется только при нажатии клавиш редактирования.

Сообщение отредактировал umup - Dec 18 2007, 10:58
Go to the top of the page
 
+Quote Post
Aesthete Animus
сообщение Dec 18 2007, 11:26
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 222
Регистрация: 9-06-07
Пользователь №: 28 317



Цитата(umup @ Dec 18 2007, 13:57) *
ну посчитайте - сколько текста и данных на каждый пункт меню, плюс логика - навигация очень немного (фактически переход на следующий/предыдущий пункт с проверкой находится ли след.пункт в одном подменю с предыдущим, и переход в другое подменю по номеру), редактирование параметров - немного больше. думаю по коду в 0.5 - 1 килобайт можно уложиться. по быстроте вообще проблем быть не должно - состояние изменяется только при нажатии клавиш редактирования.

Хм... Ну что ж... Буду грести в этом направлении.
Go to the top of the page
 
+Quote Post
ochkarik_
сообщение Feb 23 2008, 14:15
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 1-07-07
Пользователь №: 28 824



А как вам такой принцип реализации меню?
Прикрепленный файл  menu.rar ( 108.33 килобайт ) Кол-во скачиваний: 236


В приложенном файле реализация для обычного консольного приложения Windows, с целью показать принцип.

Реализация для атмеги есть на работе, почти полная версия, вкупе с обработкой клавиатуры.
Функция main для атмеги выглядит примерно так:
Код
while(1)
{
   .......
   if(MAIN_NOT_BUSY) //условие, дающие разрешение на работу терминала в этом цикле
     next_terminal_task();
}

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

Сообщение отредактировал ochkarik_ - Feb 23 2008, 14:28
Go to the top of the page
 
+Quote Post
KRS
сообщение Feb 23 2008, 17:04
Сообщение #14


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(ochkarik_ @ Feb 23 2008, 17:15) *
Ф функции next_terminal_task выполняется только один шаг из текущей задачи - или вывод одного символа на дисплей или один скан клавиатуры или обработка нажатой клавиши, или еще чего-то.
Но это уже другая история.

IMHO зачем изобретать велосипед, така идея реализована в switch технологии или автоматном программровании. здесь можно посомтреть инфу и пример
http://ru.wikipedia.org/wiki/Автоматное_программирование
А для серьезного использования лучше с первоисточника начать
http://is.ifmo.ru/

Еще в FreeRTOS есть co-routine, тоже очень удобная штука.

Сообщение отредактировал KRS - Feb 23 2008, 17:17
Go to the top of the page
 
+Quote Post
Getmanov
сообщение Feb 24 2008, 09:59
Сообщение #15


Участник
*

Группа: Свой
Сообщений: 66
Регистрация: 28-01-08
Из: Николаев
Пользователь №: 34 507



CODE


/****************************************************************/
/* Menu */
/****************************************************************/
// Структура хранящая пункты меню
typedef
struct {
unsigned char __flash *itemText; // Название Пункта
void (*itemFunction)(char); // Вызываемая функция
char itemArg; // Аргумент
}
_menuItem;
_menuItem MenuItem;

// Названия
static __flash unsigned char
_max[] = {77,65,88,32,72,97,190,112,0},
_min[] = {77,73,78,32,72,97,190,112,0},
_sens[] = {171,121,179,99,191,179,184,191,0},
_timeout[] = {84,105,109,101,32,79,117,116,0},
_beep[] = {66,101,101,112,72,114,115,20,0},
_sec[] = {83,104,111,119,32,83,101,99,0},
_stime[] = {83,101,116,32,84,105,109,101,0},
_deadzone[] = {68,101,97,100,90,111,110,101,0},
_service[] = {42,42,42,42,42,42,42,42,0};


// Загрузка структуры
static _menuItem __flash MenuItems[] =
{
_max, SetMaxV, 3,
_min, SetMinV, 2,
_sens, Sensitivity, 0,
_timeout, SetTimeOut, 0,
_deadzone, SetDead, 0,
_beep, SetBeepHrs, 0,
_sec, SetShowSec, 0,
_stime, SetTime, 0,
_service, Service, 0
};
/****************************************************************/

void Menu(char inp)
{
static _menuItem __flash *_mptr = MenuItems;
switch (inp)
{
case NEXT: // Next item
if (++_mptr > &MenuItems[(sizeof MenuItems)/(sizeof (_menuItem)) - 1])
_mptr = MenuItems;
OutStrFlash(_mptr->itemText,0x01);
PrintSymbol(4,0x00);
/* Вывод следующего пункта в след. строку */
if (++_mptr > &MenuItems[(sizeof MenuItems)/(sizeof (_menuItem)) - 1])
{
_mptr = MenuItems;
}
OutStrFlash(_mptr->itemText,0x40);
if (--_mptr < MenuItems) // Set pointer to the last item
_mptr = &MenuItems[(sizeof MenuItems)/(sizeof (_menuItem)) - 1];
Dev_State = MENU;
break;

case SELECT: // Выполнение выбранного пункта
Ctrl = 0;
Dev_State = MENU;
(*_mptr->itemFunction)(_mptr->itemArg);
ClrScr();
break;
}
}


Где то так делал я , на примере ув. Леонида Ивановича. Для навигации использовал 2 кнопки.
Меню одноуровневое, но добавить ещё уровней не проблема. Вместо указателя на исполняемую функцию нужно подставить указатель на функцию подменю. Работает это дело быстро, да и места не много занимает.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 20:40
Рейтинг@Mail.ru


Страница сгенерированна за 0.01481 секунд с 7
ELECTRONIX ©2004-2016