ps1x 0 28 марта, 2006 Опубликовано 28 марта, 2006 · Жалоба Ставлю три пива тому, кто даст мне пример (с комментариями) реализации вложенного меню для 2х строчного жк в среде CVAVR. Уже второй день бюсь ап стену, но ничего путного не выходит - то меню которое написал я, уже (недоделаное) занимает 1312 слов :blink: . Сдается мне что это не есть гут. Но придумать ничего лучше бесконечных switch case не могу ( :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vet 0 28 марта, 2006 Опубликовано 28 марта, 2006 · Жалоба Не зацикливайтесь на вложенности. Пункт меню - самодостаточный набор данных и кода для его прорисовки и переходов в другие пункты. Модель меню - простой граф, где вершины - пункты, а ребра - переходы по нажатиям клавиш. Задача программы - реализовать прорисовку и переходы. Это очень просто. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 28 марта, 2006 Опубликовано 28 марта, 2006 · Жалоба Попробуйте так. Отделите интерпретатор меню и собственно описание каждого пункта меню. В описании пункта меню должен содержаться заголовок меню, адрес функции выполняющейся при входе в меню, при выходе из меню и при нажатии каждой функциональной кнопки. Интерпретатор меню должен прочитать описание пункта меню, выполнить какие-то действия по отображению заголовка/считыванию данных/отображению данных и выполнить функцию назначенную для нажатия клавиши, взяв ее из описания меню. Если данные отображаемые в данном пункте меню должны отображаться динамически, то периодически интерпретатор меню запускает функцию получения данных. Отделение функциональной части меню от описательной немного усложняет его реализацию, но зато делает более наглядным исходный текст и позволяет легко расширять само меню как по функциональности, так и по количеству пунктов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
e-moe 0 28 марта, 2006 Опубликовано 28 марта, 2006 (изменено) · Жалоба Я реализовал так: //Структура описывает пункт меню typedef struct _selection { unsigned char *mas; // Указатель на название пункта void (*function)(void); //Указатель на функцию выполняющуюся по нажатии на enter/escape unsigned ent_f: 4; //Флаг входа 4 бита - обычно ID меню в которое надо войти unsigned esc_f: 4; //Флаг выхода 4 бита - обычно ID меню в которое надо вернуться }SELECTION; //Структура описывает меню/подменю typedef struct _menu { unsigned char id; //Номер меню/подменю unsigned char num_selections; //Количество пунктов данного меню/подменю SELECTION *m; //Указатель намассив пунктов данного меню/подменю }MENU; //Номера меню/подменю enum __menu__id { MAIN_MENU, //Главное меню SETTINGS_MENU, //Меню настроек REPORT_MENU //Меню отчёта }; //Имена пунктов unsigned char X1[]={"Пункт 1"}; ... unsigned char X7[]={"Пункт 1"}; //Заголовки функций void func1(void); ... void func7(void); //Массив хранищий пункты главного меню (структура SELECTION) static SELECTION menu_[]={ {X1, func1, 0, 0}, //Пункт 1 {X2, func2, 0, 0}, //Пункт 2 {X3, goto_menu, SETTINGS_MENU, 0}, //Пункт 3 {X4, goto_menu, REPORT_MENU, 0} //Пункт 4 }; //Массив хранищий пункты меню настроек (структура SELECTION) static SELECTION menu_m0[]={ {X5, func5, 0, MAIN_MENU}, //Пункт 1 {X6, func6, 0, MAIN_MENU}, //Пункт 2 {X7, func7, 0, MAIN_MENU}, //Пункт 3 }; //Главный массив хранит в себе все меню/подменю //Все меню/подменю должны описываться в таком же порядке как и в enum __menu__id ... static MENU menu[] = { {MAIN_MENU, 4, menu_}, //Меню 1 {SETTINGS_MENU, 3, menu_m0} //Меню 2 }; Далее обявляю 2 переменные: int current_menu=0; //Переменная указывает на текущее меню int current_poz=0; //Переменная указывает на текущий пункт меню/подменю Далее что бы вывести текущее меню делаю так: Функция_вывода_строки(menu[current_menu].m[current_poz].mas); Для перехода в подменю и обратно достаточчно организовать такой код для всех пунктов: void goto_menu(void) { switch (КодКнопки) { case ENTER: {current_menu=menu[current_menu].m[current_poz].ent_f; break;};//enter case ESC: {current_menu=menu[current_menu].m[current_poz].esc_f; break;};//escape } current_poz=0; }; Вот так вот вызываю функцию для текущего пункта: menu[current_menu].m[current_poz].function(); Приблизительно так организовал работу с ним... while(TRUE) { switch (КодКнопки) { case DOWN: { (current_poz<=0)?current_poz=menu[current_menu].num_selections:current_poz--; print_menu(); break; }; case UP: { (current_poz>=menu[current_menu].num_selections)?current_poz=0:current_poz++; print_menu(); break; }; case ENTER: { menu[current_menu].m[current_poz].function(); print_menu(); break; }; case ESC: { menu[current_menu].m[current_poz].function(); print_menu(); break; }; }; }; Вроде бы всё, поидее всё это должно работать с любой вложеностью... Изменено 28 марта, 2006 пользователем e-moe Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ps1x 0 28 марта, 2006 Опубликовано 28 марта, 2006 · Жалоба Спасибо за ответы, сейчас буду разбираться... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ps1x 0 28 марта, 2006 Опубликовано 28 марта, 2006 (изменено) · Жалоба /***************************************************** This program was produced by the CodeWizardAVR V1.24.5 Standard Automatic Program Generator © Copyright 1998-2005 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com e-mail:[email protected] Project : Version : Date : 28.03.2006 Author : ps1x Company : ccc Comments: Chip type : ATmega8 Program type : Application Clock frequency : 1,000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256 *****************************************************/ #include <mega8.h> // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x18;PORTB #endasm #include <lcd.h> char kod; int current_menu=0; //Ïåðåìåííàÿ óêàçûâàåò íà òåêóùåå ìåíþ int current_poz=0; //Ïåðåìåííàÿ óêàçûâàåò íà òåêóùèé ïóíêò ìåíþ/ïîäìåíþ void goto_menu(void); //Ñòðóêòóðà îïèñûâàåò ïóíêò ìåíþ typedef struct _selection { unsigned char *mas; // Óêàçàòåëü íà íàçâàíèå ïóíêòà void (*function)(void); //Óêàçàòåëü íà ôóíêöèþ âûïîëíÿþùóþñÿ ïî íàæàòèè íà enter/escape unsigned ent_f: 4; //Ôëàã âõîäà 4 áèòà - îáû÷íî ID ìåíþ â êîòîðîå íàäî âîéòè unsigned esc_f: 4; //Ôëàã âûõîäà 4 áèòà - îáû÷íî ID ìåíþ â êîòîðîå íàäî âåðíóòüñÿ }SELECTION; //Ñòðóêòóðà îïèñûâàåò ìåíþ/ïîäìåíþ typedef struct _menu { unsigned char id; //Íîìåð ìåíþ/ïîäìåíþ unsigned char num_selections; //Êîëè÷åñòâî ïóíêòîâ äàííîãî ìåíþ/ïîäìåíþ SELECTION *m; //Óêàçàòåëü íàìàññèâ ïóíêòîâ äàííîãî ìåíþ/ïîäìåíþ }MENU; //Íîìåðà ìåíþ/ïîäìåíþ enum __menu__id { MAIN_MENU, //Ãëàâíîå ìåíþ SETTINGS_MENU, //Ìåíþ íàñòðîåê REPORT_MENU //Ìåíþ îò÷¸òà }; //Èìåíà ïóíêòîâ unsigned char X1[]={"Ïóíêò 1"}; unsigned char X2[]={"Ïóíêò 2"}; unsigned char X3[]={"Ïóíêò 3"}; unsigned char X4[]={"Ïóíêò 4"}; unsigned char X5[]={"Ïóíêò 5"}; unsigned char X6[]={"Ïóíêò 6"}; unsigned char X7[]={"Ïóíêò 7"}; //Çàãîëîâêè ôóíêöèé void func1(void); void func2(void); void func3(void); void func4(void); void func5(void); void func6(void); void func7(void); //Ìàññèâ õðàíèùèé ïóíêòû ãëàâíîãî ìåíþ (ñòðóêòóðà SELECTION) static SELECTION menu_[]={ {X1, func1, 0, 0}, //Ïóíêò 1 {X2, func2, 0, 0}, //Ïóíêò 2 {X3, goto_menu, SETTINGS_MENU, 0}, //Ïóíêò 3 {X4, goto_menu, REPORT_MENU, 0} //Ïóíêò 4 }; //Ìàññèâ õðàíèùèé ïóíêòû ìåíþ íàñòðîåê (ñòðóêòóðà SELECTION) static SELECTION menu_m0[]={ {X5, func5, 0, MAIN_MENU}, //Ïóíêò 1 {X6, func6, 0, MAIN_MENU}, //Ïóíêò 2 {X7, func7, 0, MAIN_MENU}, //Ïóíêò 3 } <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<--------ЗДЕСЬ РУГАЕТСЯ (invalid expression) //////////////////////////////////////////#///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////#//#/////////////////////////////////////////////////////////////////////////// //////////////////////////////////////#//#///#//////////////////////////////////////////////////////////////////////// ////////////////////////////////////#////#////#/////////////////////////////////////////////////////////////////////// //////////////////////////////////////////#//////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////#//////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////#//////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////#####//////////////////////////////////////////////////////////////////////// //Ãëàâíûé ìàññèâ õðàíèò â ñåáå âñå ìåíþ/ïîäìåíþ //Âñå ìåíþ/ïîäìåíþ äîëæíû îïèñûâàòüñÿ â òàêîì æå ïîðÿäêå êàê è â enum __menu__id ... static MENU menu[] = { {MAIN_MENU, 4, menu_}, //Ìåíþ 1 {SETTINGS_MENU, 3, menu_m0} //Ìåíþ 2 }; void goto_menu(void) { switch (kod) { case 'e': {current_menu=menu[current_menu].m[current_poz].ent_f; break;};//enter case 'b': {current_menu=menu[current_menu].m[current_poz].esc_f; break;};//escape } current_poz=0; } В коде я выделил ошибку вот так "<<<<<<<<<<<-----" почему ругается? Изменено 28 марта, 2006 пользователем ps1x Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 28 марта, 2006 Опубликовано 28 марта, 2006 · Жалоба Когда копируете текст с русскоязычными коментариями из редактора, то не забывайте предварительно переключить раскладку клавиатры на "русскую", тогда при вставке в форум не будет в тексте нечитаемых иероглифов.. в этой ветке приводил пример для работы со строками меню. Может он и вам пригодится... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ps1x 0 28 марта, 2006 Опубликовано 28 марта, 2006 · Жалоба Когда копируете текст с русскоязычными коментариями из редактора, то не забывайте предварительно переключить раскладку клавиатры на "русскую", тогда при вставке в форум не будет в тексте нечитаемых иероглифов.. в этой ветке приводил пример для работы со строками меню. Может он и вам пригодится... 1)про раскладку, я учту обязательно. 2)спасибо, конечно, посмотрел ссылку, много интересного, но я прошу помочь с конкретным кодом... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 28 марта, 2006 Опубликовано 28 марта, 2006 · Жалоба по конкретному коду - у Вас лишняя запятая. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ps1x 0 28 марта, 2006 Опубликовано 28 марта, 2006 (изменено) · Жалоба Большое спасибо! С меня 2 пива для e-moe и одно defunct! (current_poz<=0)?current_poz=menu[current_menu].num_selections:current_poz--; - на эту строчку пишет missing ':'! что это за оператор такой? Изменено 28 марта, 2006 пользователем ps1x Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ps1x 0 28 марта, 2006 Опубликовано 28 марта, 2006 · Жалоба (current_poz<=0)?current_poz=menu[current_menu].num_selections:current_poz--; - на эту строчку пишет missing ':'! что это за оператор такой? - с этим уже вроде разобрался, теперь вопрос: void print_menu() { } - как реализовывать? что-нибудь типа: lcd_puts(menu[current_menu].SELECTION);??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
WHILE 0 29 марта, 2006 Опубликовано 29 марта, 2006 · Жалоба И я пива хочу ;) А если серьезно,открой в хелпе CodeVision Library Function- в ней пункт LCD Function- там все подробно описано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ps1x 0 29 марта, 2006 Опубликовано 29 марта, 2006 · Жалоба Да нет, с функциям лсд я разобрался, но вот как отобразить именно то что нужно, как к структуре обращаться??? Гляньте код если не лень, конечно ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
e-moe 0 29 марта, 2006 Опубликовано 29 марта, 2006 · Жалоба Выше написано: static SELECTION menu_m0[]={ {X5, func5, 0, MAIN_MENU}, {X6, func6, 0, MAIN_MENU}, {X7, func7, 0, MAIN_MENU}, //!!! } Скорее всего из-за того, что запятая там случайно стоит... Потому и ругается.... У меня в IAR не ругался... Вот такой вот код: (current_poz<=0)?current_poz=menu[current_menu].num_selections:current_poz--; Можно заменить аналогом: if (current_poz<=0) {current_poz=menu[current_menu].num_selections;} else {current_poz--;}; Вывод меню на экран - print_menu() это уже фантазия... В CodeVision есть библиотеки работы с ЖКИ, при помощи них можно добиться вывода одной строки, а в print_menu() можно вызывать выод строки [сurrent_poz], потом переход курсора на сдлед. строку и вывод строки [сurrent_poz+1]. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ps1x 0 29 марта, 2006 Опубликовано 29 марта, 2006 · Жалоба Да, но вот как обратиться к структуре, чтоб отображала например [current_poz]??? Я просто со структурами на Вы )) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться