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

 
 
3 страниц V  < 1 2 3  
Reply to this topicStart new topic
> Отображение меню на жк, реализация на CVAVR
ARV
сообщение Jan 22 2010, 13:19
Сообщение #31


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



для собственно TUI опрос кнопок без разницы smile.gif но скажите мне, где это может помешать?!

у меня меню так же на основе структур, только я отказался от связного списка, в пользу массивов, как раз из-за простоты восприятия. плюс в списке надо хранить ссылки на следующего-предыдущего-корневого, а для массива не надо - FLASH экономится smile.gif

а разобраться сложно - так можно и не разбираться, достаточно интерфейс понять smile.gif описание системы меню не сложнее, чем у MicroMenu - так же при помощи макросов, единственное, до чего я не догнал сразу - так это определить сразу тип для структуры в PROGMEM, и пришлось извращаться с предварительным описанием текстовых строк в виде констант.

MicroMenu весьма лаконично - признаю. у меня более путано - да. не стремился к суперлаконичности, старался больше вариантов охватить smile.gif


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
vvkka
сообщение Jan 24 2010, 08:41
Сообщение #32


Участник
*

Группа: Участник
Сообщений: 57
Регистрация: 9-07-08
Из: Волгоградская обл
Пользователь №: 38 838



да согласен код слишком запутаный, как то реолизовал нечто подобное. вопервых можно все масивы вынести во флеш, ОЗУ сильно секономит, вовторых с нажатием кнопок несовсем понял фиксация по временной задержке, непрощели одно нажатие одно срабатывание
Go to the top of the page
 
+Quote Post
ARV
сообщение Jan 25 2010, 09:16
Сообщение #33


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Цитата(vvkka @ Jan 24 2010, 11:41) *
да согласен код слишком запутаный, как то реолизовал нечто подобное. вопервых можно все масивы вынести во флеш, ОЗУ сильно секономит, вовторых с нажатием кнопок несовсем понял фиксация по временной задержке, непрощели одно нажатие одно срабатывание
согласен с чем? wink.gif все массивы и так во FLASH smile.gif и кнопки именно так: одно нажатие - одно срабатывание. но предусмотрен случай автоповтора при длительном нажатии (у меня в TUI).


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
reload
сообщение May 10 2010, 12:45
Сообщение #34


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 17-03-09
Пользователь №: 46 202



Недавно переделал 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))


Вроде, всё.

Надеюсь, кому-нибудь поможет.

Сообщение отредактировал reload - May 10 2010, 12:48
Go to the top of the page
 
+Quote Post
ps1x
сообщение May 11 2010, 14:02
Сообщение #35


Местный
***

Группа: Свой
Сообщений: 300
Регистрация: 15-03-06
Из: Москва
Пользователь №: 15 284



Вот окончательный полностью работающий вариант меню.
CODE
/*****************************************************
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:office@hpinfotech.com

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;
};
};
};

}
Go to the top of the page
 
+Quote Post
ut1wpr
сообщение May 12 2010, 09:21
Сообщение #36


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

Группа: Участник
Сообщений: 98
Регистрация: 20-06-05
Пользователь №: 6 150



Цитата(ps1x @ May 11 2010, 17:02) *
Вот окончательный полностью работающий вариант меню.
CODE
/*****************************************************
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:office@hpinfotech.com

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;
};
};
};

}

А теперь то же самое, но для четырёх языков, русский, украинский, польский и английский. smile.gif
Во! А мне приходилось наворачивать.... В принципе, ничего особенного, просто добавляются ещё вложения.
Go to the top of the page
 
+Quote Post
ChaiSER
сообщение Feb 14 2011, 12:18
Сообщение #37





Группа: Новичок
Сообщений: 4
Регистрация: 14-02-11
Из: UA-RU
Пользователь №: 62 962



Здравствуйте! Понравилась данная реализация меню для ЖКИ. Сделал себе по такому же принципу, но нужно добавить две функции:
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... Что я не так делаю?
Go to the top of the page
 
+Quote Post
Saadov
сообщение Feb 15 2011, 16:57
Сообщение #38





Группа: Новичок
Сообщений: 9
Регистрация: 28-01-09
Из: Смоленск
Пользователь №: 44 099



Цитата
1. Вывод текстовой информации на ЖКИ и выход из функции по нажатию ESC.

В кей по идее и остается ESC, просто перед входом в цикл обнулите кей.

Цитата
1. Вывод текстовой информации на ЖКИ и выход из функции по нажатию ESC.

В кей по идее и остается ESC, просто перед входом в цикл обнулите кей.
Код
do
while (key != ESC)


Выполняем цикл пока кей не равен ESC, как только кей равен, т.е. нажата кнопка ESC, выходим из цикла.


--------------------
Я электронику люблю!
Возьму паяльничком пройду!
В ней нет проблем и главный плюс.
Мы совместимы как припой и флюс.
Go to the top of the page
 
+Quote Post
ChaiSER
сообщение Feb 15 2011, 18:11
Сообщение #39





Группа: Новичок
Сообщений: 4
Регистрация: 14-02-11
Из: UA-RU
Пользователь №: 62 962



Цитата(Saadov @ Feb 15 2011, 19:57) *
В кей по идее и остается ESC, просто перед входом в цикл обнулите кей.

Saadov, спасибо, заработало как надо! sm.gif

Осталось реализовать вторую функцию:
Цитата
2. Ввод значения целого числа с клавиатуры (использую клавиатуру 3х4) и выход из функции с сохранением значения по нажатию ENTER и без сохранения по ESC.
Go to the top of the page
 
+Quote Post
Saadov
сообщение Feb 19 2011, 22:30
Сообщение #40





Группа: Новичок
Сообщений: 9
Регистрация: 28-01-09
Из: Смоленск
Пользователь №: 44 099



Все названные функции для примера
Код
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


--------------------
Я электронику люблю!
Возьму паяльничком пройду!
В ней нет проблем и главный плюс.
Мы совместимы как припой и флюс.
Go to the top of the page
 
+Quote Post
Loshara
сообщение Dec 24 2012, 07:55
Сообщение #41





Группа: Новичок
Сообщений: 1
Регистрация: 24-12-12
Пользователь №: 74 955



Цитата(ps1x @ May 11 2010, 17:02) *
Вот окончательный полностью работающий вариант меню.


Спасибо за код,в Протеусе посмотрел,всё-ОК rolleyes.gif
Теперь,извините меня за тупость 01.gif , обьясните пожалуйста, как связать это с реальной жизнью, т.е. как менять свои переменные связав их именно с нужными пунктами и значениями меню. help.gif
Go to the top of the page
 
+Quote Post
EmDMAl
сообщение Nov 10 2014, 11:40
Сообщение #42





Группа: Новичок
Сообщений: 7
Регистрация: 13-05-12
Пользователь №: 71 815



Разобрался с меню. Но при размещении большого количества структур забилась вся оперативная память. И встал вопрос о размещении структур в флешь памяти.
CODE
...

//Структура описывает пункт меню
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
};
...

Так вот, кто-нибудь размещал эти структуры во флешь памяти?

Сообщение отредактировал IgorKossak - Dec 5 2014, 19:23
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Dec 5 2014, 19:30
Сообщение #43


Местный
***

Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709



Как-то так:

menu.h:
CODE
//========================================================================
#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:
CODE
//========================================================================
#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");


Так как используется структура, нет надобности в запоминании навигации по меню. Вся информация в структуре.

Видео пробного проекта меню

Сообщение отредактировал IgorKossak - Dec 5 2014, 19:29
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
binarick
сообщение Mar 16 2015, 09:58
Сообщение #44





Группа: Новичок
Сообщений: 5
Регистрация: 16-03-15
Пользователь №: 85 692



Здравствуйте уважаемые
Хочу воскресить темку т.к. форум не даёт отправлять личные сообщения ..... почемуто
Очень нужно сделать своё меню, не хочу использовать МикроМеню а тут относительно просто всё и понятно.

Но запустить не получается... Точнее меню ТС запустил, но в конце темы уважаемый 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")wink.gif
даёт непонятную мне ошибку "Error: C:\Project\IntKeyNew\intkey.c(83): storage modifier not allowed in this context"

Не пинайте сильно учусь только ещё

Спасибо за ваше время и ответы

Сообщение отредактировал binarick - Mar 16 2015, 09:59
Go to the top of the page
 
+Quote Post
TimurArs
сообщение Mar 30 2018, 21:47
Сообщение #45





Группа: Новичок
Сообщений: 1
Регистрация: 30-03-18
Пользователь №: 102 785



Цитата(ut1wpr @ May 12 2010, 10:21) *
А теперь то же самое, но для четырёх языков, русский, украинский, польский и английский. sm.gif
Во! А мне приходилось наворачивать.... В принципе, ничего особенного, просто добавляются ещё вложения.


приветствую. тут есть кто нибудь? не могу разобраться с кодом.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 16th June 2025 - 00:04
Рейтинг@Mail.ru


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