Перейти к содержанию

Отображение меню на жк

Ставлю три пива тому, кто даст мне пример (с комментариями) реализации вложенного меню для 2х строчного жк в среде CVAVR. Уже второй день бюсь ап стену, но ничего путного не выходит - то меню которое написал я, уже (недоделаное) занимает 1312 слов blink.gif . Сдается мне что это не есть гут. Но придумать ничего лучше бесконечных switch case не могу ( sad.gif

Поделиться сообщением


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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Попробуйте так.
Отделите интерпретатор меню и собственно описание каждого пункта меню.
В описании пункта меню должен содержаться заголовок меню, адрес функции выполняющейся при входе в меню, при выходе из меню и при нажатии каждой функциональной кнопки.
Интерпретатор меню должен прочитать описание пункта меню, выполнить какие-то действия по отображению заголовка/считыванию данных/отображению данных и выполнить функцию назначенную для нажатия клавиши, взяв ее из описания меню. Если данные отображаемые в данном пункте меню должны отображаться динамически, то периодически интерпретатор меню запускает функцию получения данных.
Отделение функциональной части меню от описательной немного усложняет его реализацию, но зато делает более наглядным исходный текст и позволяет легко расширять само меню как по функциональности, так и по количеству пунктов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Я реализовал так:

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


Вроде бы всё, поидее всё это должно работать с любой вложеностью...
Изменено пользователем e-moe

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Спасибо за ответы, сейчас буду разбираться...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Код
/*****************************************************
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:office@hpinfotech.com

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



В коде я выделил ошибку вот так "<<<<<<<<<<<-----" почему ругается?
Изменено пользователем ps1x

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Когда копируете текст с русскоязычными коментариями из редактора, то не забывайте предварительно переключить раскладку клавиатры на "русскую", тогда при вставке в форум не будет в тексте нечитаемых иероглифов..

в этой ветке приводил пример для работы со строками меню. Может он и вам пригодится...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(defunct @ Mar 29 2006, 01:28) <{POST_SNAPBACK}>
Когда копируете текст с русскоязычными коментариями из редактора, то не забывайте предварительно переключить раскладку клавиатры на "русскую", тогда при вставке в форум не будет в тексте нечитаемых иероглифов..

в этой ветке приводил пример для работы со строками меню. Может он и вам пригодится...


1)про раскладку, я учту обязательно.
2)спасибо, конечно, посмотрел ссылку, много интересного, но я прошу помочь с конкретным кодом...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Большое спасибо!
С меня 2 пива для e-moe и одно defunct!

(current_poz<=0)?current_poz=menu[current_menu].num_selections:current_poz--;

- на эту строчку пишет missing ':'!

что это за оператор такой?
Изменено пользователем ps1x

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата
(current_poz<=0)?current_poz=menu[current_menu].num_selections:current_poz--;

- на эту строчку пишет missing ':'!

что это за оператор такой?

- с этим уже вроде разобрался, теперь вопрос:
void print_menu()
{
}
- как реализовывать?

что-нибудь типа:
lcd_puts(menu[current_menu].SELECTION);???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
И я пива хочу wink.gif А если серьезно,открой в хелпе CodeVision Library Function- в ней пункт LCD Function-
там все подробно описано.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Да нет, с функциям лсд я разобрался, но вот как отобразить именно то что нужно, как к структуре обращаться??? Гляньте код если не лень, конечно )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Выше написано:
Код
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].

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Да, но вот как обратиться к структуре, чтоб отображала например
[current_poz]???
Я просто со структурами на Вы ))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация