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

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

menu[current_menu].m[current_poz].mas

menu - массив current_menu указывает на текущее меню .m обращаемся к помлю структуры в текущего меню т.к. там тоже массив, то current_poz указывает текущий пункт меню .mas есть указательна строку текущего меню и текущего пункта.

 

Если взять код выше, то:

menu[1].m[1].mas

Активно второе меню (т.к. счёт начинается с 0): SETTINGS_MENU, далее в подменю SETTINGS_MENU выбран пункт 2 и далее .mas указатель на строку...

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


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

ps1x

Совет: не пожалейте времени, прочитайте какой-нибудь учебник языка С, хотя бы тот же Керниган & Ритчи - будете программировать намного увереннее, и множество вопросов пропадёт.

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


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

/*****************************************************
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>
#include <stdio.h>
#include <delay.h>        
char kod; 
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, //Главное меню
  SETTINGS_MENU, //Меню настроек
  REPORT_MENU //Меню отчёта
};

//Имена пунктов
unsigned char X1[]={"Punkt 1"};
unsigned char X2[]={"Punkt 2"};
unsigned char X3[]={"Settings"};
unsigned char X4[]={"Report"};
unsigned char X5[]={"set 1"};
unsigned char X6[]={"set 2"};
unsigned char X7[]={"set 3"};

//Заголовки функций

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}, //Punkt 1
  {X2, func2, 0, 0}, //Punkt 2
  {X3, goto_menu, SETTINGS_MENU, MAIN_MENU}, //Punkt 3
  {X4, goto_menu, REPORT_MENU, MAIN_MENU} //Punkt 4
};

//Массив хранищий пункты меню настроек (структура SELECTION)
static SELECTION menu_m0[]={
  {X5, func5, 0, 0}, //Punkt 1
  {X6, func6, 0, 0}, //Punkt 2
  {X7, func7, 0, 0} //Punkt 3
};

//Главный массив хранит в себе все меню/подменю
//Все меню/подменю должны описываться в таком же порядке как и в   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;
}
void print_menu()
{         
lcd_clear();
lcd_puts(menu[current_menu].m[current_poz].mas);
lcd_gotoxy(0,1);
if (current_poz==(int) menu[current_menu].num_selections)  /////////////////////////////////////////
{lcd_putsf("-------------------");}/////////////////проблема здесь!!!!!!!!!!!!//////////////////////////////
else {lcd_puts(menu[current_menu].m[current_poz+1].mas);}////////////////////////////////////////
delay_ms(100);  
kod='k';
}

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here

}

// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Place your code here

} 

// Declare your global variables here


void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 
PORTB=0x00;
DDRB=0xFF;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 
PORTD=0xFF;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 0,977 kHz
TCCR0=0x05;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 3,906 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x04;
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=0x05;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// LCD module initialization
lcd_init(16);

// Global enable interrupts
#asm("sei")
while (1)
      {
      // Place your code here
        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;}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  'e': {
      menu[current_menu].m[current_poz].function();
      print_menu();
      break;
    };
    case  'b': {
      menu[current_menu].m[current_poz].function();
      print_menu();
      break;
    };
    };
      };

}

 

Возможные проблемы я выделил большим колличеством "//////".

Во первых, меню почти заработало, но есть две проблемы:

 

1) Почемуто не сравнивается количество пунктов меню и активный пункт меню???

(если не сравнивать то можно делать меню на котором отображается только 1 пункт, что не есть хорошо)

 

2) Вторая и САМАЯ ВАЖНАЯ проблема - не работает выход из подменю в предыдущее меню :(

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


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

может стоит без приведении к int попробовать?

if (current_poz==menu[current_menu].num_selections)

или же поля (esc_f и ent_f) объявить как char или int

попробуй вызывать переход как

void goto_menu(char);
////
void goto_menu(char kod) {...};
////
goto_menu(kod);

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


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

может стоит без приведении к int попробовать?

 

 

if (current_poz==menu[current_menu].num_selections)

 

- с этим уже разобрался, показывает сносно )

 

или же поля (esc_f и ent_f) объявить как char или int

попробуй вызывать переход как

 

void goto_menu(char);
////
void goto_menu(char kod) {...};
////
goto_menu(kod);

 

 

- В подменю входит, а выходить из него не хочет (((( ума не приложу, вроде-бы все seems to be alright....

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


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

Неужели никто на этом форуме не знает язык С??? Это же не драйвер видеокарты, а всего лишь менюшка! Полный код программы есть немного выше. Спасибо всем кто откликнется.

 

p.s. не отправляйте меня сразу книжки читать, я считаю что начинать изучение языка с типов переменных неправильно. Лучше изучать в примерах, имхо доступнее для понимания.

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


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

Делал меню под заказ. Правда для графических дисплеев. Вот исходник. Думаю, откинув (или заменив) функции вывода графики получите то что Вам надо

Menu_unit.rar

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


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

Нашёл я проблему по которой невозможно быйти из подменю...

Допустим я захожу в меню настройки. Там 3 пункта:

Настройка 1

>Настройка 2

Настройка 3

Активен пункт 2.

тогда при нажатии на ESC происходит вызов:

menu[current_menu].m[current_poz].function()

Совершенно очевидно что function() не является функцией goto_menu(), т.к. это функция вызовает опии пункта настройки 2.

Есть 2 выхода либо добавть отдельно пункт Выход в каждое подменю и поместить для вызова функцию goto_menu(), либо:

case  ESC: { 
      //убрать menu[current_menu].m[current_poz].function(&kkk);
      goto_menu(); //оставить
/*В таком случае при нажати на ESC всегда будет вызываться данная функция*/
      print_menu();
      . . .
      break;

 

P.S. В ИАР есть возможность посмотреть как ведёт себя код, какие переменные куда идут, в режиме отладки. Если нет возможности его использовать, то неплохо бы поставить AVRStudio и при критических ситуациях там просматривать, что происходит с кодом...

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


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

Все получилось, хотя сначала делал вариант с пунктом "назад" в каждом подменю, но то что предложили Вы гораздо удобнее с точки зрения юзера )) Большое спасибо.

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


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

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

Хороший Сайт.

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


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

я тоже делал меню, правда на WinAVR. любая вложенность подменю (делается рекурсивно, потому надо осторожность соблюдать), пункты меню разных видов (просто пункт, пункт-опция [аналог галочки в винде, типа "посветка вкл."], пункт-параметр [т.е. типа "громкость 35%"]). выбор просто пункта - просто возврат его Id, выбор пункта-параметра - вызов специальной функции изменения параметра (можно очень гибко все делать), пункт опция - так же вызов особой функции. описание системы пунктов меню при помощи макросов - достаточно простое, как мне кажется. предусмотрен вариант для ЖКИ с числом строк более 2 - тогда меню выглядит примерно как в древних мобилках типа Siemens.

 

мне кажется, портировать под CVAVR несложно.

 

кому интересно, подробности тут

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


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

я тоже делал меню, правда на WinAVR. любая вложенность подменю (делается рекурсивно, потому надо осторожность соблюдать)

Есть же MicroMenu (http://www.avrfreaks.net/index.php?module=Freaks%20Files&func=viewFile&id=2178&showinfo=1), там без рекурсий строится меню любой вложенности. Не обязательно брать 1 в 1, можно только принцип построения позаимствовать. Меню это ОЗУ вообще не расходует, что не мешает в него параметры вводить через константные уазатели. Принцип же построения простой и достаточно эффективный. А главное - удобный.

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


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

Есть же MicroMenu (http://www.avrfreaks.net/index.php?module=Freaks%20Files&func=viewFile&id=2178&showinfo=1), там без рекурсий строится меню любой вложенности. Не обязательно брать 1 в 1, можно только принцип построения позаимствовать. Меню это ОЗУ вообще не расходует, что не мешает в него параметры вводить через константные уазатели. Принцип же построения простой и достаточно эффективный. А главное - удобный.
рекурсию я имел ввиду для вызова функции, "путешествующей" по пунктам и возвращающей результат выбора пользователя, т.е. расход памяти на рекурсию небольшой. а что касается MicroMenu - кой чего интересного там подсмотрел, попробую улучшить свой вариант (у моего возможности шире).

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


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

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

Дело то не в возможностях, а в принципах построения. Меню на основе структур очень легко дооснастить требующемся функционалом, но при этом оно не будет запутанным, а останется легко редактируемым. В Вашем же варианте без поллитры вообще не разобраться. :)

Кстати остальные подходы в Вашей TUI тоже как то не очень оптимальны. Методы опроса кнопок с использованием софтовых задержек на 20мс удивляет.

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


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

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...