ARV 0 22 января, 2010 Опубликовано 22 января, 2010 · Жалоба для собственно TUI опрос кнопок без разницы :) но скажите мне, где это может помешать?! у меня меню так же на основе структур, только я отказался от связного списка, в пользу массивов, как раз из-за простоты восприятия. плюс в списке надо хранить ссылки на следующего-предыдущего-корневого, а для массива не надо - FLASH экономится :) а разобраться сложно - так можно и не разбираться, достаточно интерфейс понять :) описание системы меню не сложнее, чем у MicroMenu - так же при помощи макросов, единственное, до чего я не догнал сразу - так это определить сразу тип для структуры в PROGMEM, и пришлось извращаться с предварительным описанием текстовых строк в виде констант. MicroMenu весьма лаконично - признаю. у меня более путано - да. не стремился к суперлаконичности, старался больше вариантов охватить :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vvkka 0 24 января, 2010 Опубликовано 24 января, 2010 · Жалоба да согласен код слишком запутаный, как то реолизовал нечто подобное. вопервых можно все масивы вынести во флеш, ОЗУ сильно секономит, вовторых с нажатием кнопок несовсем понял фиксация по временной задержке, непрощели одно нажатие одно срабатывание Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 0 25 января, 2010 Опубликовано 25 января, 2010 · Жалоба да согласен код слишком запутаный, как то реолизовал нечто подобное. вопервых можно все масивы вынести во флеш, ОЗУ сильно секономит, вовторых с нажатием кнопок несовсем понял фиксация по временной задержке, непрощели одно нажатие одно срабатываниесогласен с чем? ;) все массивы и так во FLASH :) и кнопки именно так: одно нажатие - одно срабатывание. но предусмотрен случай автоповтора при длительном нажатии (у меня в TUI). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
reload 0 10 мая, 2010 Опубликовано 10 мая, 2010 (изменено) · Жалоба Недавно переделал Micro-Menu под dsPIC (MPLAB C30 v2.04). Делюсь опытом: Все изменения в файле Menu.h Во-первых, выбрасываем #include <avr/pgmspace.h> Во-вторых, вместо typedef struct { void *Next; void *Previous; void *Parent; void *Sibling; FuncPtr SelectFunc; FuncPtr EnterFunc; const char Text[]; } Menu_Item PROGMEM; должно быть typedef const struct { void *Next; void *Previous; void *Parent; void *Sibling; FuncPtr SelectFunc; FuncPtr EnterFunc; char Text[]; }Menu_Item; и в-третьих, вместо #define PREVIOUS *((Menu_Item*)pgm_read_word(&CurrMenuItem->Previous)) #define NEXT *((Menu_Item*)pgm_read_word(&CurrMenuItem->Next)) #define PARENT *((Menu_Item*)pgm_read_word(&CurrMenuItem->Parent)) #define SIBLING *((Menu_Item*)pgm_read_word(&CurrMenuItem->Sibling)) #define ENTERFUNC *((FuncPtr*)pgm_read_word(&CurrMenuItem->EnterFunc)) #define SELECTFUNC *((FuncPtr*)pgm_read_word(&CurrMenuItem->SelectFunc)) должно быть #define PREVIOUS *((Menu_Item*)(CurrMenuItem->Previous)) #define NEXT *((Menu_Item*)(CurrMenuItem->Next)) #define PARENT *((Menu_Item*)(CurrMenuItem->Parent)) #define SIBLING *((Menu_Item*)(CurrMenuItem->Sibling)) #define ENTERFUNC *((FuncPtr*)(CurrMenuItem->EnterFunc)) #define SELECTFUNC *((FuncPtr*)(CurrMenuItem->SelectFunc)) Вроде, всё. Надеюсь, кому-нибудь поможет. Изменено 10 мая, 2010 пользователем reload Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ps1x 0 11 мая, 2010 Опубликовано 11 мая, 2010 · Жалоба Вот окончательный полностью работающий вариант меню. /***************************************************** This program was produced by the CodeWizardAVR V1.24.6 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 : 15.01.2010 Author : ps1x Company : asd Comments: Chip type : ATmega8 Program type : Application Clock frequency : 8,000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256 *****************************************************/ #include <mega8.h> #include <16x2.h> // Declare your global variables here char kod; char last_item; int current_menu=0; //Переменная указывает на текущее меню int current_poz=1; //Переменная указывает на текущий пункт меню/подменю void goto_menu(void); void print_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, //Главное меню DELAY_MENU, //Меню настроек FOCUS_MENU, QUANTITY_MENU, TIME_MENU //Меню отчёта }; //Имена пунктов unsigned char X1[]={"Задержка"}; unsigned char X2[]={"1 сек"}; unsigned char X3[]={"2 сек"}; unsigned char X4[]={"3 сек"}; unsigned char X5[]={"4 сек"}; unsigned char X6[]={"5 сек"}; unsigned char X7[]={"8 сек"}; unsigned char X8[]={"10 сек"}; unsigned char X9[]={"15 сек"}; unsigned char X10[]={"20 сек"}; unsigned char X11[]={"30 сек"}; unsigned char X12[]={"Фокусировка"}; unsigned char X13[]={"Выкл"}; unsigned char X14[]={"0,5 сек"}; unsigned char X15[]={"1 сек"}; unsigned char X16[]={"Кол. фоток"}; unsigned char X17[]={"50 шт"}; unsigned char X18[]={"100 шт"}; unsigned char X19[]={"200 шт"}; unsigned char X20[]={"300 шт"}; unsigned char X21[]={"500 шт"}; unsigned char X22[]={"800 шт"}; unsigned char X23[]={"1000 шт"}; unsigned char X24[]={"Время фотогр."}; unsigned char X25[]={"Непрерывно"}; unsigned char X26[]={"5 мин"}; unsigned char X27[]={"10 мин"}; unsigned char X28[]={"15 мин"}; unsigned char X29[]={"пол часа"}; unsigned char X30[]={"час"}; unsigned char X31[]={"два часа"}; unsigned char X32[]={"Старт съемки"}; //Заголовки функций void func1(void){} void func2(void){} void func3(void){} void func4(void){} void func5(void){} void func6(){} void func7(void){} //Массив хранищий пункты главного меню (структура SELECTION) static SELECTION menu_[]={ {X1, goto_menu, DELAY_MENU, MAIN_MENU}, //Punkt 1 {X12, goto_menu, FOCUS_MENU, MAIN_MENU}, //Punkt 2 {X16, goto_menu, QUANTITY_MENU, MAIN_MENU}, //Punkt 3 {X24, goto_menu, TIME_MENU, MAIN_MENU}, //Punkt 4 {X32, func7, 0, 0} //Punkt 4 }; //Массив хранищий пункты меню настроек (структура SELECTION) static SELECTION menu_m0[]={ {X2, func6, 0, 0}, //Punkt 1 {X3, func6, 0, 0}, //Punkt 2 {X4, func6, 0, 0}, //Punkt 3 {X5, func6, 0, 0}, //Punkt 2 {X6, func6, 0, 0}, //Punkt 2 {X7, func6, 0, 0}, //Punkt 2 {X8, func6, 0, 0}, //Punkt 2 {X9, func6, 0, 0}, //Punkt 2 {X10, func6, 0, 0}, //Punkt 2 {X11, func6, 0, 0} //Punkt 2 }; static SELECTION menu_m1[]={ {X13, func6, 0, 0}, //Punkt 1 {X14, func6, 0, 0}, //Punkt 2 {X15, func6, 0, 0} //Punkt 3 }; static SELECTION menu_m2[]={ {X17, func6, 0, 0}, //Punkt 1 {X18, func6, 0, 0}, //Punkt 2 {X19, func6, 0, 0}, //Punkt 3 {X20, func6, 0, 0}, //Punkt 1 {X21, func6, 0, 0}, //Punkt 2 {X22, func6, 0, 0}, //Punkt 3 {X23, func6, 0, 0} //Punkt 1 }; static SELECTION menu_m3[]={ {X25, func6, 0, 0}, //Punkt 1 {X26, func6, 0, 0}, //Punkt 2 {X27, func6, 0, 0}, //Punkt 3 {X28, func6, 0, 0}, //Punkt 1 {X29, func6, 0, 0}, //Punkt 2 {X30, func6, 0, 0}, //Punkt 3 {X31, func6, 0, 0} //Punkt 1 }; //Главный массив хранит в себе все меню/подменю //Все меню/подменю должны описываться в таком же порядке как и в enum __menu__id ... static MENU menu[] = { {MAIN_MENU, 5, menu_}, //Меню 1 {DELAY_MENU, 10, menu_m0}, //Меню 2 {FOCUS_MENU, 3, menu_m1}, {QUANTITY_MENU, 7, menu_m2}, {TIME_MENU, 7, menu_m3} }; void goto_menu(void) { switch (kod) { case 'e': {current_menu=menu[current_menu].m[current_poz].ent_f; last_item=current_poz; break;}; //enter case 'b': {current_menu=menu[current_menu].m[current_poz].esc_f; break;}; //escape } current_poz=0; } void print_menu() { lcd_clear(); lcd_putsf("> "); lcd_puts(menu[current_menu].m[current_poz].mas); lcd_gotoxy(2,1); if (current_poz == menu[current_menu].num_selections-1) { lcd_puts(menu[current_menu].m[0].mas); // lcd_putsf("-------------------"); } else { lcd_puts(menu[current_menu].m[current_poz+1].mas); } delay_ms(100); kod='k'; } void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization // Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTC=0x00; DDRC=0xFF; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0xFF; DDRD=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped TCCR0=0x00; TCNT0=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2 output: Disconnected ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off MCUCR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00; lcd_init(); lcd_clear(); lcd_putsf(" МИЭМ"); lcd_gotoxy(0,1); lcd_putsf(" USB частотомер"); print_menu(); while (1) { if(PIND.0==0){delay_ms(150);kod='u';} if(PIND.1==0){delay_ms(150);kod='d';} if(PIND.2==0){delay_ms(150);kod='e';} if(PIND.3==0){delay_ms(150);kod='b';} switch (kod) { case 'u': { if (current_poz<=0){current_poz=menu[current_menu].num_selections-1;}else{current_poz--;} print_menu(); break; }; case 'd': { if(current_poz>=menu[current_menu].num_selections-1){current_poz=0;}else{current_poz++;} print_menu(); break; }; case 'b': { goto_menu(); current_poz=last_item; print_menu(); break; }; case 'e': { menu[current_menu].m[current_poz].function(); print_menu(); break; }; }; }; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ut1wpr 0 12 мая, 2010 Опубликовано 12 мая, 2010 · Жалоба Вот окончательный полностью работающий вариант меню. /***************************************************** This program was produced by the CodeWizardAVR V1.24.6 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 : 15.01.2010 Author : ps1x Company : asd Comments: Chip type : ATmega8 Program type : Application Clock frequency : 8,000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256 *****************************************************/ #include <mega8.h> #include <16x2.h> // Declare your global variables here char kod; char last_item; int current_menu=0; //Переменная указывает на текущее меню int current_poz=1; //Переменная указывает на текущий пункт меню/подменю void goto_menu(void); void print_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, //Главное меню DELAY_MENU, //Меню настроек FOCUS_MENU, QUANTITY_MENU, TIME_MENU //Меню отчёта }; //Имена пунктов unsigned char X1[]={"Задержка"}; unsigned char X2[]={"1 сек"}; unsigned char X3[]={"2 сек"}; unsigned char X4[]={"3 сек"}; unsigned char X5[]={"4 сек"}; unsigned char X6[]={"5 сек"}; unsigned char X7[]={"8 сек"}; unsigned char X8[]={"10 сек"}; unsigned char X9[]={"15 сек"}; unsigned char X10[]={"20 сек"}; unsigned char X11[]={"30 сек"}; unsigned char X12[]={"Фокусировка"}; unsigned char X13[]={"Выкл"}; unsigned char X14[]={"0,5 сек"}; unsigned char X15[]={"1 сек"}; unsigned char X16[]={"Кол. фоток"}; unsigned char X17[]={"50 шт"}; unsigned char X18[]={"100 шт"}; unsigned char X19[]={"200 шт"}; unsigned char X20[]={"300 шт"}; unsigned char X21[]={"500 шт"}; unsigned char X22[]={"800 шт"}; unsigned char X23[]={"1000 шт"}; unsigned char X24[]={"Время фотогр."}; unsigned char X25[]={"Непрерывно"}; unsigned char X26[]={"5 мин"}; unsigned char X27[]={"10 мин"}; unsigned char X28[]={"15 мин"}; unsigned char X29[]={"пол часа"}; unsigned char X30[]={"час"}; unsigned char X31[]={"два часа"}; unsigned char X32[]={"Старт съемки"}; //Заголовки функций void func1(void){} void func2(void){} void func3(void){} void func4(void){} void func5(void){} void func6(){} void func7(void){} //Массив хранищий пункты главного меню (структура SELECTION) static SELECTION menu_[]={ {X1, goto_menu, DELAY_MENU, MAIN_MENU}, //Punkt 1 {X12, goto_menu, FOCUS_MENU, MAIN_MENU}, //Punkt 2 {X16, goto_menu, QUANTITY_MENU, MAIN_MENU}, //Punkt 3 {X24, goto_menu, TIME_MENU, MAIN_MENU}, //Punkt 4 {X32, func7, 0, 0} //Punkt 4 }; //Массив хранищий пункты меню настроек (структура SELECTION) static SELECTION menu_m0[]={ {X2, func6, 0, 0}, //Punkt 1 {X3, func6, 0, 0}, //Punkt 2 {X4, func6, 0, 0}, //Punkt 3 {X5, func6, 0, 0}, //Punkt 2 {X6, func6, 0, 0}, //Punkt 2 {X7, func6, 0, 0}, //Punkt 2 {X8, func6, 0, 0}, //Punkt 2 {X9, func6, 0, 0}, //Punkt 2 {X10, func6, 0, 0}, //Punkt 2 {X11, func6, 0, 0} //Punkt 2 }; static SELECTION menu_m1[]={ {X13, func6, 0, 0}, //Punkt 1 {X14, func6, 0, 0}, //Punkt 2 {X15, func6, 0, 0} //Punkt 3 }; static SELECTION menu_m2[]={ {X17, func6, 0, 0}, //Punkt 1 {X18, func6, 0, 0}, //Punkt 2 {X19, func6, 0, 0}, //Punkt 3 {X20, func6, 0, 0}, //Punkt 1 {X21, func6, 0, 0}, //Punkt 2 {X22, func6, 0, 0}, //Punkt 3 {X23, func6, 0, 0} //Punkt 1 }; static SELECTION menu_m3[]={ {X25, func6, 0, 0}, //Punkt 1 {X26, func6, 0, 0}, //Punkt 2 {X27, func6, 0, 0}, //Punkt 3 {X28, func6, 0, 0}, //Punkt 1 {X29, func6, 0, 0}, //Punkt 2 {X30, func6, 0, 0}, //Punkt 3 {X31, func6, 0, 0} //Punkt 1 }; //Главный массив хранит в себе все меню/подменю //Все меню/подменю должны описываться в таком же порядке как и в enum __menu__id ... static MENU menu[] = { {MAIN_MENU, 5, menu_}, //Меню 1 {DELAY_MENU, 10, menu_m0}, //Меню 2 {FOCUS_MENU, 3, menu_m1}, {QUANTITY_MENU, 7, menu_m2}, {TIME_MENU, 7, menu_m3} }; void goto_menu(void) { switch (kod) { case 'e': {current_menu=menu[current_menu].m[current_poz].ent_f; last_item=current_poz; break;}; //enter case 'b': {current_menu=menu[current_menu].m[current_poz].esc_f; break;}; //escape } current_poz=0; } void print_menu() { lcd_clear(); lcd_putsf("> "); lcd_puts(menu[current_menu].m[current_poz].mas); lcd_gotoxy(2,1); if (current_poz == menu[current_menu].num_selections-1) { lcd_puts(menu[current_menu].m[0].mas); // lcd_putsf("-------------------"); } else { lcd_puts(menu[current_menu].m[current_poz+1].mas); } delay_ms(100); kod='k'; } void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization // Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTC=0x00; DDRC=0xFF; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0xFF; DDRD=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped TCCR0=0x00; TCNT0=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2 output: Disconnected ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off MCUCR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00; lcd_init(); lcd_clear(); lcd_putsf(" МИЭМ"); lcd_gotoxy(0,1); lcd_putsf(" USB частотомер"); print_menu(); while (1) { if(PIND.0==0){delay_ms(150);kod='u';} if(PIND.1==0){delay_ms(150);kod='d';} if(PIND.2==0){delay_ms(150);kod='e';} if(PIND.3==0){delay_ms(150);kod='b';} switch (kod) { case 'u': { if (current_poz<=0){current_poz=menu[current_menu].num_selections-1;}else{current_poz--;} print_menu(); break; }; case 'd': { if(current_poz>=menu[current_menu].num_selections-1){current_poz=0;}else{current_poz++;} print_menu(); break; }; case 'b': { goto_menu(); current_poz=last_item; print_menu(); break; }; case 'e': { menu[current_menu].m[current_poz].function(); print_menu(); break; }; }; }; } А теперь то же самое, но для четырёх языков, русский, украинский, польский и английский. :) Во! А мне приходилось наворачивать.... В принципе, ничего особенного, просто добавляются ещё вложения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
babolik 0 14 февраля, 2011 Опубликовано 14 февраля, 2011 · Жалоба Здравствуйте! Понравилась данная реализация меню для ЖКИ. Сделал себе по такому же принципу, но нужно добавить две функции: 1. Вывод текстовой информации на ЖКИ и выход из функции по нажатию ESC. 2. Ввод значения целого числа с клавиатуры (использую клавиатуру 3х4) и выход из функции с сохранением значения по нажатию ENTER и без сохранения по ESC. Пока разбираюсь с первой функцией вывод текста и выход из неё по ESC. Делаю так: void func2(void) { do { LCDClear(); //очистить LCD LCDWriteString("Hello World!"); //вывод строки на LCD _delay_ms(1000); //задержка для проверки } while (key == ESC); //Для выхода - ESC } И получаеться так, что после отображения текста 1сек. меня выбрасывает в меню, хотя возврат должен происходить по нажатию ESC... Что я не так делаю? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Saadov 0 15 февраля, 2011 Опубликовано 15 февраля, 2011 · Жалоба 1. Вывод текстовой информации на ЖКИ и выход из функции по нажатию ESC. В кей по идее и остается ESC, просто перед входом в цикл обнулите кей. 1. Вывод текстовой информации на ЖКИ и выход из функции по нажатию ESC. В кей по идее и остается ESC, просто перед входом в цикл обнулите кей. do while (key != ESC) Выполняем цикл пока кей не равен ESC, как только кей равен, т.е. нажата кнопка ESC, выходим из цикла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
babolik 0 15 февраля, 2011 Опубликовано 15 февраля, 2011 · Жалоба В кей по идее и остается ESC, просто перед входом в цикл обнулите кей. Saadov, спасибо, заработало как надо! :) Осталось реализовать вторую функцию: 2. Ввод значения целого числа с клавиатуры (использую клавиатуру 3х4) и выход из функции с сохранением значения по нажатию ENTER и без сохранения по ESC. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Saadov 0 19 февраля, 2011 Опубликовано 19 февраля, 2011 · Жалоба Все названные функции для примера vvod_chisla(){ key = null; znachenie = 0; do{ znachenie = obrabotka_knopok(); //смотрите апноут у атмела по подключению и обработке матрицы кнопок, ну или сами придумаете. }while(key == null); if(key == ENTER) eeprom_write( znachenie ); } Лучше не оффтопить, а создать отдельную тему в http://electronix.ru/forum/index.php?showforum=191 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Loshara 0 24 декабря, 2012 Опубликовано 24 декабря, 2012 · Жалоба Вот окончательный полностью работающий вариант меню. Спасибо за код,в Протеусе посмотрел,всё-ОК :rolleyes: Теперь,извините меня за тупость :01: , обьясните пожалуйста, как связать это с реальной жизнью, т.е. как менять свои переменные связав их именно с нужными пунктами и значениями меню. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EmDMAl 0 10 ноября, 2014 Опубликовано 10 ноября, 2014 (изменено) · Жалоба Разобрался с меню. Но при размещении большого количества структур забилась вся оперативная память. И встал вопрос о размещении структур в флешь памяти. ... //Структура описывает пункт меню 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; ... //Массив хранищий пункты главного меню (структура SELECTION) static SELECTION menu_[]={ {X1, goto_menu, DELAY_MENU, MAIN_MENU}, //Punkt 1 {X12, goto_menu, FOCUS_MENU, MAIN_MENU}, //Punkt 2 {X16, goto_menu, QUANTITY_MENU, MAIN_MENU}, //Punkt 3 {X24, goto_menu, TIME_MENU, MAIN_MENU}, //Punkt 4 {X32, func7, 0, 0} //Punkt 4 }; //Массив хранищий пункты меню настроек (структура SELECTION) static SELECTION menu_m0[]={ {X2, func6, 0, 0}, //Punkt 1 {X3, func6, 0, 0}, //Punkt 2 {X4, func6, 0, 0}, //Punkt 3 {X5, func6, 0, 0}, //Punkt 2 {X6, func6, 0, 0}, //Punkt 2 {X7, func6, 0, 0}, //Punkt 2 {X8, func6, 0, 0}, //Punkt 2 {X9, func6, 0, 0}, //Punkt 2 {X10, func6, 0, 0}, //Punkt 2 {X11, func6, 0, 0} //Punkt 2 }; ... Так вот, кто-нибудь размещал эти структуры во флешь памяти? Изменено 5 декабря, 2014 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 5 декабря, 2014 Опубликовано 5 декабря, 2014 (изменено) · Жалоба Как-то так: menu.h: //======================================================================== #ifndef MENU_H #define MENU_H #include "menu.h" //======================================================================== //======================================================================== #include <pgmspace.h> #include <stdbool.h> #include "avrlibtypes.h" #include "kbd_drv.h" //======================================================================== //======================================================================== // Typedefs: typedef void (*FuncPtr)(void); //======================================================================== //======================================================================== typedef struct menu_item { void *Parent; void *Child; void *Next; void *Prev; FuncPtr NumFunc; FuncPtr EnterFunc; FuncPtr MenuFunc; char Text[20]; } menu_item; //======================================================================== // Externs: //======================================================================== extern menu_item __flash *CurrMenuItem; // Текущий пункт меню. extern menu_item __flash *BeginCurrMenuLevel; // Начало массива текущего уровня меню. extern __flash menu_item Null_Menu; extern char Menu_Str_Buf []; // Буфер для вывода текста. extern void (*MenuFuncPtr)(void); //======================================================================== // Defines and Macros: //======================================================================== #define NULL_ENTRY Null_Menu #define NULL_FUNC (void*)0 #define NULL_TEXT 0x00 #define PAGE_MENU 3 //======================================================================== //======================================================================== #define MAKE_MENU(Name, Parent, Child, Next, Prev, NumFunc, EnterFunc, MenuFunc, Text) \ extern menu_item __flash Parent; \ extern menu_item __flash Child; \ extern menu_item __flash Next; \ extern menu_item __flash Prev; \ menu_item __flash Name \ { \ (menu_item*) &Parent, \ (menu_item*) &Child, \ (menu_item*) &Next, \ (menu_item*) &Prev, \ NumFunc, \ EnterFunc, \ MenuFunc, \ {Text} \ } //======================================================================== //======================================================================== #define PARENT *((menu_item __flash*) (CurrMenuItem->Parent)) #define CHILD *((menu_item __flash*) (CurrMenuItem->Child)) #define NEXT *((menu_item __flash*) (CurrMenuItem->Next)) #define PREV *((menu_item __flash*) (CurrMenuItem->Prev)) #define NUM_FUNC *((FuncPtr) (CurrMenuItem->NumFunc)) #define ENTER_FUNC *((FuncPtr) (CurrMenuItem->EnterFunc)) #define MENU_FUNC *((FuncPtr) (CurrMenuItem->MenuFunc)) //======================================================================== //======================================================================== #define SET_MENU_LEVEL(x) \ Set_Menu_Level(&x) #define SET_MENU_ITEM(x) \ Set_Menu_Item(&x) #define GO_MENU_FUNC(x) \ MenuFunc((FuncPtr*)&x) #define EXTERN_MENU(Name) \ extern menu_item __flash Name; //======================================================================== //======================================================================== enum { SET_LEVEL = 0, SET_NEXT, SET_PREV, }; //======================================================================== // Prototypes: //======================================================================== void Set_Menu_Level (menu_item __flash *NewMenu); void Set_Menu_Item (menu_item __flash *NewMenu); void MenuFunc(FuncPtr* Function); //======================================================================== //======================================================================== EXTERN_MENU (L_OUT_MODE); //======================================================================== //======================================================================== void Out_Menu_Items_Init (void); void Out_Menu_Items (void); //======================================================================== //======================================================================== bool proc_menu_keys (void); //======================================================================== //======================================================================== void out_name_level (void); u08 count_chars (char __flash *data); void make_page_menu (void); void inc_pos_y_curs (void); void dec_pos_y_curs (void); void set_pos_curs (void); //======================================================================== #endif menu.c: //======================================================================== #include "menu.h" //======================================================================== //======================================================================== static u08 quant_items; static u08 pos_y_curs; //======================================================================== //======================================================================== ============================================================== menu_item __flash *CurrMenuItem; // Текущий пункт меню. menu_item __flash *BeginCurrMenuLevel; // Начало массива текущего уровня меню. menu_item __flash *temp_menu; menu_item __flash Null_Menu = {(void*)0, (void*)0, (void*)0, (void*)0, NULL_FUNC, NULL_FUNC, NULL_FUNC, {NULL_TEXT}}; void (*MenuFuncPtr)(void); //======================================================================== ============================================================== //======================================================================== void Set_Menu_Level (menu_item __flash *NewMenu) { if ((void*)NewMenu == (void*)&NULL_ENTRY) return; CurrMenuItem = NewMenu; Out_Menu_Items_Init (); // Так как новый уровень, инициализация переменных. Out_Menu_Items (); // Вывод названия уровня меню и пунктов меню, курсора. GO_MENU_FUNC (ENTER_FUNC); } //======================================================================== //======================================================================== void Set_Menu_Item (menu_item __flash *NewMenu) { if ((void*)NewMenu == (void*)&NULL_ENTRY) return; CurrMenuItem = NewMenu; Out_Menu_Items (); // Вывод названия уровня меню и пунктов меню, курсора. GO_MENU_FUNC (ENTER_FUNC); } //======================================================================== //======================================================================== void MenuFunc (FuncPtr* Function) { if ((void*) Function == (void*) NULL_FUNC) return; ((FuncPtr) Function)(); } //======================================================================== //======================================================================== bool proc_menu_keys (void) { bool a = false; u08 key; if (Get_Event (EV_ID_KEY_PRESSED)) { key = GetKeyCode (); switch (key) { case KEY_ESC_COD: SET_MENU_LEVEL (PARENT); a = true; break; case KEY_ENTER_COD: SET_MENU_LEVEL (CHILD); a = true; break; case KEY_NEXT_COD: inc_pos_y_curs (); SET_MENU_ITEM (NEXT); a = true; break; case KEY_PREV_COD: dec_pos_y_curs (); SET_MENU_ITEM (PREV); a = true; break; default: break; } if (key < 10) { GO_MENU_FUNC (NUM_FUNC); // Сервисные меню. Ввод числовых параметров. a = true; } } if (a) return true; else return false; } //======================================================================== /* Уровни, пункты, текст - все выводится автоматом. Так как все переходы по меню расписаны в структуре, то отпадает надобность в запоминании перемещений по меню. */ //======================================================================== void Out_Menu_Items_Init (void) { quant_items = 1; pos_y_curs = 1; // Получение адреса начала массива уровня меню. BeginCurrMenuLevel = CurrMenuItem; temp_menu = (menu_item __flash *)(CurrMenuItem->Prev); while (1) { if ((void*)temp_menu == (void*)&NULL_ENTRY) { break; } else { BeginCurrMenuLevel = temp_menu; temp_menu = (menu_item __flash *)(temp_menu->Prev); } } // Получение количества пунктов меню. temp_menu = (menu_item __flash *)(BeginCurrMenuLevel->Next); while (1) { if ((void*)temp_menu == (void*)&NULL_ENTRY) { break; } temp_menu = (menu_item __flash *)(temp_menu->Next); quant_items++; } // Позиция курсора. if (quant_items > 1) { temp_menu = BeginCurrMenuLevel; while (1) { if ((void*)temp_menu == (void*)&NULL_ENTRY) return; if (temp_menu == CurrMenuItem) return; else pos_y_curs++; temp_menu = (menu_item __flash *)(temp_menu->Next); } } } void Out_Menu_Items (void) { clr_dsp_buf (); out_name_level (); // Вывод названия уровня меню. make_page_menu (); // Вывод пунктов меню. set_pos_curs (); // Установка позиции и вывод курсора. } //======================================================================== //======================================================================== // Вывод названия уровня меню. void out_name_level (void) { temp_menu = (menu_item __flash *)(CurrMenuItem->Parent); // Считывание названия уровня меню из пункта меню в верхнем уровне. if ((void*)temp_menu != (void*)&NULL_ENTRY) { char __flash *data = temp_menu->Text; u08 i = count_chars (data); // Подсчет кол-ва символов в строке. // Выравнивание текста посередине строки дисплея. u08 a = i; i = (20 - i); // Дисплей 20x4. Отнимаем от 20 число символов. i >>= 1; // Делим остаток на 2. if (a & (1<<0)) i += 2; // Если число нечетное. else i++; // Если число четное. Print_Buf (1, i, temp_menu->Text); } } //======================================================================== //======================================================================== // Подсчет кол-ва символов в строке. u08 count_chars (char __flash *data) { u08 i = 0; while (data [i]) { i++; } return i; } //======================================================================== //======================================================================== void make_page_menu (void) { signed char tmp_pos_y_curs; u08 i; // Счетчик страниц. u08 j; // Страница меню. if (quant_items > 1) // Если пунктов меню больше 1, значит есть что выводить. { temp_menu = BeginCurrMenuLevel; if (pos_y_curs > PAGE_MENU) { tmp_pos_y_curs = pos_y_curs; i = 0; // Счетчик страниц. while (tmp_pos_y_curs > 0) { tmp_pos_y_curs -= PAGE_MENU; i++; } tmp_pos_y_curs += PAGE_MENU; j = PAGE_MENU; // Страница меню. while (i-- > 1) { while (j--) { temp_menu = (menu_item __flash *)(temp_menu->Next); // Следующий пункт меню. } j = PAGE_MENU; // Страница меню. } } u08 pos_y_text_item = 2; // j = PAGE_MENU; // Страница меню. while (j--) { Print_Buf (pos_y_text_item, 2, temp_menu->Text); // вывод названия пункта меню. temp_menu = (menu_item __flash *)(temp_menu->Next); // Следующий пункт меню. if ((void*)temp_menu == (void*)&NULL_ENTRY) // Если элемент Next return; // пустой, то выход. else pos_y_text_item++; } } } //======================================================================== //======================================================================== void inc_pos_y_curs (void) { if (quant_items > 1) { if (pos_y_curs < quant_items) pos_y_curs++; } } void dec_pos_y_curs (void) { if (quant_items > 1) { if (pos_y_curs > 1) pos_y_curs--; } } //======================================================================== //======================================================================== void set_pos_curs (void) { if (quant_items > 1) { signed char tmp = pos_y_curs; while (tmp > 0) { tmp -= PAGE_MENU; } if (tmp <= 0) tmp += PAGE_MENU; PrintChar (tmp + 1, 1, ARROW_RIGHT); } } //======================================================================== Пример использования: Где-то создаем точку входа в меню: SET_MENU_LEVEL (YOU_MENU); Где-то делаем опрос клавиатуры и где-то проверяем, было ли событие клавиатуры: if (proc_menu_keys ()) return; Пример меню: // NAME PARENT CHILD NEXT PREV NUM_FUNCE ENTER_FUNC MENU_FUNC TEXT MAKE_MENU (ITEM_1, NULL_ENTRY, NULL_ENTRY, ITEM_2, NULL_ENTRY, NULL_FUNC, NULL_FUNC, NULL_FUNC, "ПУНКТ 1"); MAKE_MENU (ITEM_2, NULL_ENTRY, NULL_ENTRY, ITEM_3, ITEM_1, NULL_FUNC, NULL_FUNC, NULL_FUNC, "ПУНКТ 2"); MAKE_MENU (ITEM_3, NULL_ENTRY, NULL_ENTRY, ITEM_4, ITEM_2, NULL_FUNC, NULL_FUNC, NULL_FUNC, "ПУНКТ 3"); MAKE_MENU (ITEM_4, NULL_ENTRY, SUBITEM_1, NULL_ENTRY, ITEM_3, NULL_FUNC, NULL_FUNC, NULL_FUNC, "ПУНКТ 4"); MAKE_MENU (SUBITEM_1, ITEM_4, NULL_ENTRY, SUBITEM_2, NULL_ENTRY, NULL_FUNC, NULL_FUNC, NULL_FUNC, "ПОДПУНКТ 1"); MAKE_MENU (SUBITEM_2, ITEM_4, NULL_ENTRY, SUBITEM_3, SUBITEM_1, NULL_FUNC, NULL_FUNC, NULL_FUNC, "ПОДПУНКТ 2"); MAKE_MENU (SUBITEM_3, ITEM_4, NULL_ENTRY, SUBITEM_4, SUBITEM_2, NULL_FUNC, NULL_FUNC, NULL_FUNC, "ПОДПУНКТ 3"); MAKE_MENU (SUBITEM_4, ITEM_4, NULL_ENTRY, NULL_ENTRY, SUBITEM_4, NULL_FUNC, NULL_FUNC, NULL_FUNC, "ПОДПУНКТ 4"); Так как используется структура, нет надобности в запоминании навигации по меню. Вся информация в структуре. Видео пробного проекта меню Изменено 5 декабря, 2014 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
binarick 0 16 марта, 2015 Опубликовано 16 марта, 2015 (изменено) · Жалоба Здравствуйте уважаемые Хочу воскресить темку т.к. форум не даёт отправлять личные сообщения ..... почемуто Очень нужно сделать своё меню, не хочу использовать МикроМеню а тут относительно просто всё и понятно. Но запустить не получается... Точнее меню ТС запустил, но в конце темы уважаемый demiurg1978 показал чтото очень хорошее ). Юзаю CodeVisionAVR 3.12 Так вот эта штука у меня не взлетает 1. avrlibtypes.h нашёл такую библиотеку но там используются х64 (long long) я просто закоментил строки в данной библиотеке. 2. SET_MENU_LEVEL (YOU_MENU); что такое YOU_MENU ? как создать ? 3. Любая строка из примера (MAKE_MENU (ITEM_1, NULL_ENTRY, NULL_ENTRY, ITEM_2, NULL_ENTRY, NULL_FUNC, NULL_FUNC, NULL_FUNC, "ПУНКТ 1");) даёт непонятную мне ошибку "Error: C:\Project\IntKeyNew\intkey.c(83): storage modifier not allowed in this context" Не пинайте сильно учусь только ещё Спасибо за ваше время и ответы Изменено 16 марта, 2015 пользователем binarick Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
timurars 0 30 марта, 2018 Опубликовано 30 марта, 2018 · Жалоба А теперь то же самое, но для четырёх языков, русский, украинский, польский и английский. :) Во! А мне приходилось наворачивать.... В принципе, ничего особенного, просто добавляются ещё вложения. приветствую. тут есть кто нибудь? не могу разобраться с кодом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться