+2
Делал что-то подобное, но задачи минимизировать затраты ОЗУ не стояло. Выложу в качестве идеи.

Каждый пункт меню содержит название, указатель на функцию «обработчик» и два параметра для функции «обработчика». Эти параметры каждая функция может обрабатывать по своему (как в SendMessage() Win32).

//---------------------------------------------------------------------------------------------------------------------
typedef BOOL (*MenuHandler)(void * param, DWORD size);

//---------------------------------------------------------------------------------------------------------------------
typedef struct {
	const char Name[33];
	MenuHandler Handler;
	void * Param;
	DWORD ParamSize;
} MenuItem;


Вот пример описания меню с подменю

подменю

//---------------------------------------------------------------------------------------------------------------------
const MenuItem StatusMenu[] = {
		{"Баланс GSM", ShowGSM_Balance, NULL, 0},
		{"Сигнал GSM", ShowGSM_SignalLevel, NULL, 0},
		{"Процессор", ShowSPU_IDLE, NULL, 0},
		{"Диск", ShowFlashCardFree, NULL, 0}
};


основное меню

//---------------------------------------------------------------------------------------------------------------------
const MenuItem MainMenu[] = {
		{"Настройки", ShowMenu, (void  *) ConfigureMenu, sizeof(ConfigureMenu) / sizeof(ConfigureMenu[0])},
		{"Статус", ShowMenu, (void  *) StatusMenu, sizeof(StatusMenu) / sizeof(StatusMenu[0])}
};


Вот вся логика обработки меню

//---------------------------------------------------------------------------------------------------------------------
BOOL ShowMenu(void * Menu, DWORD MenuSize) {
	MenuItem * menu  = (MenuItem *) Menu;
	BYTE i = 0;

	for(;;) {
		CP_DisplayClear();
		CP_DisplayPutString(menu[i].Name);

		BYTE Key = 0;
		for(;;) {
			Key = CP_GetKey();
			if(Key) break;
			vTaskDelay(CHECK_KEY_INTERVAL);
		}

		switch(Key & 0x0F) {
			case KEY_UP:
					i = i > 0 ? i - 1 : MenuSize - 1;
					break;
			case KEY_DOWN:
					i = i < MenuSize - 1 ? i + 1 : 0;
					break;
			case KEY_ENTER:
					if(menu[i].Handler && menu[i].Handler(menu[i].Param, menu[i].ParamSize) == FALSE) return FALSE;
					break;
			case KEY_CANCEL:
					return (Key & 0xF0) ? FALSE : TRUE;
		}
	}
}


Для старта всего этого просто вызываем и передаем как параметры указатель на верхнее меню и кол-во пунктов этого меню.

//---------------------------------------------------------------------------------------------------------------------
void ShowMainMenu(void) {
	ShowMenu((void *) MainMenu, sizeof(MainMenu) / sizeof(MainMenu[0]));
}

Обратите внимание, что при переходе на подменю происходит рекурсивный вызов ShowMenu()
  • avatar
  • e_mc2
  • 23 июля 2014, 20:02
0
Итак, обещал фотки.
Сфоткать то что хотел не получилось((( Девайс на даче рулит поливом, вот только когда доберусь на дачу не знаю.
Но! Рылся в закромах и нашел свой первый девайсик с такой панелькой.
Как говориться, первый блин комом, по этому и не хотел выкладывать. Но все же выложу…
Повторюсь — это была всего лишь проба пера!



Из плюсов такой технологии — ничего не нужно чертить, вырезать, и т.д. Нарисовал в кореле(или в чем-то другом), распечатал, вырезал контур, лаком покрыл и наклеил. Все!
Тут же продавливаемые кнопки.

Из минусов конкретно этого примера, и почему не удачная реализация:
— Напечатано не на фото бумаге а на какой-то толстой картонке. Потому и зерно такое и качество, и полу прозрачности нету.
— Картон хуже впитывает лак. На фотобумагу лаком брызгаешь, он впитывается моментально, а тут разводы и т.д.
— Плохо просвечивается 7-сегментник из-за толщины картона.
— Плохо совместились отверстия под светодиоды и их принты на панельке (не было сверла нужного диаметра).
— Семисегментник должен был быть размером побольше. За неимением поставили какой был.

Но все равно, надеюсь, идея понятна. У Вас должно получиться лучше!
+2
Я вот делаю то же, только по другому. И как по мне — результат получше.
1. Печатаю наклейку на струйнике в цвете на фотобумаге.
2. вырезаю все что надо.
3. Покрываю прозрачным лаком из баллончика с двух сторон. Он пропитает бумагу и она станет прозрачной. Кроме того не боится ни воды ни жира от пальцев ни грязи.
4. Сверлю в корпусе дырки, подбираю кнопки под толщину корпуса. Делаю ГЛУБОКУЮ и ШИРОКУЮ зеньковку (вроде так называется). Где-то в два диаметра кнопки и глубиной практически на 90% от толщины корпуса.
5. На напечатанной панели подкладываю под кнопки кевларовую пленку (ну можно и что-то другое придумать, например изо ленту в два слоя).
6. Клею. Все.

Получается морда, которая не боится ни воды ни грязи. Все светодиоды и 8-сегментники просвечиваются прямо через нее(благодаря лаку). Для любителей — можно вырезать под них и подложить пленку.
Кнопки напечатанные продавливаются. Как на пленочных клавиатурах.
Может выложу потом выложу фотку.
+1
  • avatar
  • Lyrri
  • 03 августа 2012, 13:31
0
В настройках Measurements включите Show Timing Markers
P.S.: недавно обнаружил, что у Saleae есть SDK для разработки библиотек анализатора протокола. Так что можно запилить анализ любого протокола. Wiegand например, или азбуки Морзе )))
  • avatar
  • Lyrri
  • 03 августа 2012, 13:01