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

 
 
> Отображение меню на жк, реализация на CVAVR
ps1x
сообщение Mar 28 2006, 18:49
Сообщение #1


Местный
***

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



Ставлю три пива тому, кто даст мне пример (с комментариями) реализации вложенного меню для 2х строчного жк в среде CVAVR. Уже второй день бюсь ап стену, но ничего путного не выходит - то меню которое написал я, уже (недоделаное) занимает 1312 слов blink.gif . Сдается мне что это не есть гут. Но придумать ничего лучше бесконечных switch case не могу ( sad.gif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
ps1x
сообщение Mar 29 2006, 10:18
Сообщение #2


Местный
***

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



Да, но вот как обратиться к структуре, чтоб отображала например
[current_poz]???
Я просто со структурами на Вы ))
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Dec 5 2014, 19:30
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 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

Сообщений в этой теме
- ps1x   Отображение меню на жк   Mar 28 2006, 18:49
- - vet   Не зацикливайтесь на вложенности. Пункт меню - сам...   Mar 28 2006, 19:08
- - rezident   Попробуйте так. Отделите интерпретатор меню и соб...   Mar 28 2006, 19:38
- - e-moe   Я реализовал так: Код//Структура описывает пункт ...   Mar 28 2006, 19:57
- - ps1x   Спасибо за ответы, сейчас буду разбираться...   Mar 28 2006, 20:50
- - ps1x   Код/**********************************************...   Mar 28 2006, 21:18
- - defunct   Когда копируете текст с русскоязычными коментариям...   Mar 28 2006, 21:28
|- - ps1x   Цитата(defunct @ Mar 29 2006, 01:28) Когд...   Mar 28 2006, 21:33
- - defunct   по конкретному коду - у Вас лишняя запятая.   Mar 28 2006, 21:52
- - ps1x   Большое спасибо! С меня 2 пива для e-moe и одн...   Mar 28 2006, 22:10
- - ps1x   Цитата(current_poz<=0)?current_poz=menu[current...   Mar 28 2006, 23:41
- - WHALE   И я пива хочу А если серьезно,открой в хелпе Code...   Mar 29 2006, 04:33
- - ps1x   Да нет, с функциям лсд я разобрался, но вот как от...   Mar 29 2006, 09:49
- - e-moe   Выше написано: Кодstatic SELECTION menu_m0[...   Mar 29 2006, 10:11
- - e-moe   Кодmenu[current_menu].m[current_poz...   Mar 29 2006, 10:34
- - vet   ps1x Совет: не пожалейте времени, прочитайте какой...   Mar 29 2006, 12:10
- - ps1x   спасибо за совет, но я уже так и делаю, только уче...   Mar 29 2006, 12:26
- - ps1x   Код/**********************************************...   Mar 29 2006, 14:08
- - e-moe   может стоит без приведении к int попробовать? Кодi...   Mar 29 2006, 15:25
- - ps1x   Цитатаможет стоит без приведении к int попробовать...   Mar 29 2006, 15:52
- - ps1x   Неужели никто на этом форуме не знает язык С??? Эт...   Mar 29 2006, 20:29
- - prottoss   Делал меню под заказ. Правда для графических диспл...   Mar 30 2006, 10:47
- - e-moe   Нашёл я проблему по которой невозможно быйти из по...   Mar 31 2006, 16:00
- - ps1x   Все получилось, хотя сначала делал вариант с пункт...   Mar 31 2006, 23:36
- - LSerg   Спасибо, сделал себе меню таким же образом. Легко ...   Jan 21 2010, 04:59
- - ARV   я тоже делал меню, правда на WinAVR. любая вложенн...   Jan 22 2010, 09:00
|- - Qwertty   Цитата(ARV @ Jan 22 2010, 12:00) я тоже д...   Jan 22 2010, 10:03
|- - ARV   Цитата(Qwertty @ Jan 22 2010, 13:03) Есть...   Jan 22 2010, 11:20
|- - Qwertty   Цитата(ARV @ Jan 22 2010, 14:20) рекурсию...   Jan 22 2010, 12:12
- - ARV   для собственно TUI опрос кнопок без разницы но ск...   Jan 22 2010, 13:19
- - vvkka   да согласен код слишком запутаный, как то реолизов...   Jan 24 2010, 08:41
|- - ARV   Цитата(vvkka @ Jan 24 2010, 11:41) да сог...   Jan 25 2010, 09:16
- - reload   Недавно переделал Micro-Menu под dsPIC (MPLAB C30 ...   May 10 2010, 12:45
- - ps1x   RE: Отображение меню на жк   May 11 2010, 14:02
|- - ut1wpr   RE: Отображение меню на жк   May 12 2010, 09:21
||- - TimurArs   Цитата(ut1wpr @ May 12 2010, 10:21) А теп...   Mar 30 2018, 21:47
|- - Loshara   Цитата(ps1x @ May 11 2010, 17:02) Вот око...   Dec 24 2012, 07:55
- - ChaiSER   Здравствуйте! Понравилась данная реализация ме...   Feb 14 2011, 12:18
- - Saadov   Цитата1. Вывод текстовой информации на ЖКИ и выход...   Feb 15 2011, 16:57
- - ChaiSER   Цитата(Saadov @ Feb 15 2011, 19:57) В кей...   Feb 15 2011, 18:11
- - Saadov   Все названные функции для примера Кодvvod_chisla...   Feb 19 2011, 22:30
- - EmDMAl   Разобрался с меню. Но при размещении большого коли...   Nov 10 2014, 11:40
- - binarick   Здравствуйте уважаемые Хочу воскресить темку т.к. ...   Mar 16 2015, 09:58


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

 


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


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