Понадобилась мне как-то простая менюшка. Посидел чуток и кое-чего получилось. Сейчас попробую рассказать как ее реализовать, если понадобится. Идея такая: На ЖКИ отображается какая то информация. И тут мы хотим что-нибудь подстроить и вызываем меню. На экране появляются пункты меню, которые мы можем пролистывать и устанавливать то что нам нужно. Когда все настройки закончились, нажимаем выход и на экране снова отображается нужные данные. Схема подключения кнопок и ЖКИ приведена на рисунке.
Обвязка микроконтроллера по питанию не показана. Т.е. у нас есть 4 кнопки - Menu, Exit, Left, Right. Menu - вызов меню и вход в подменю Exit - выход из меню и из подменю Left, Right - листаем пункты меню Чтобы двигаться дальше, нам нужна блок схема программы организации меню. Откровенно говоря, когда делал меню никакой блок схемы программы не было. Но для статьи решил нарисовать ее. В итоге получилась такая вот блок схема.
Немного страшновато выглядит, но легко реализуется. На схеме выделено, какие функции что выполняют в коде программы. Каждому пункту меню соответствует свой count. При переходах между подменю count умножается на 10. При переходах по пунктам в одном подменю, count прибавляется или вычитается (Right, Left соответственно). Также есть регистр в котором сохраняю последнюю операцию. Т.е. если мы нажимаем Left тогда установкой нужного бита записываем что была операция вычитания, если нажимаем Right тогда была операция сложения. Для чего это сделано? Если, например, вы листаете вправо и доходите до последнего меню, а дальше если нажать вправо будет снова прибавление count, но это было последний пункт в этом подменю и когда мы это определяем нам нужно вернуться на предыдущий пункт. Для этого смотрим бит последней операции и делаем с count противоположную. В общем рассмотрим кратко функции программы с комментариями. В конце статьи можно скачать проект в Proteus'e и исходник в WinAVR (сильно не заморачивался с задержками для четкого отображения, поэтому картинка на экране будет моргать). При работе с установкой и сбросом бита поставил числа в виде 0b..., мне кажется, так наглядней какой бит изменяем. Итак:
1. Объявляю глобальные переменные // Глобальные переменные unsigned int menu;//код нажатой кнопки unsigned int count=0; //массив строк с названиями пунктов меню char* str[]={"menu 1", "menu 2", "menu 3", "menu 1_1", "menu 1_2","menu 1_3", "menu 2_1", "menu 2_2", "menu 3_1", "menu 1_1_1", "menu 1_1_2"}; unsigned char MDCR=0;//регистр в котором 6-й бит будет определять последнюю операцию (+ или -)
2. Функции для работы с меню //Функция изменения активной шины кнопок (у нас их две) void fChangeButton(); //Функция возвращает код выбранной кнопки unsigned char fSelButton(); //Функция в зависимости от count отображает пункт меню void fDisplayMenu(unsigned int countmenu) { unsigned char tempmenu; switch(countmenu) {//Главное меню case 1: { LCDstring(str[countmenu-1], 6); break;} case 2: { LCDstring(str[countmenu-1], 6); break;} case 3: { LCDstring(str[countmenu-1], 6); break;} //Подменю первого пункта главного меню case 10: { LCDstring(str[3], 8); break;} case 11: { LCDstring(str[4], 8); break;} case 12: { LCDstring(str[5], 8); break;} . . . //Если не попал ни в один пункт меню default: { //если не попал ни в один пункт меню тогда проверяю бит 6 на последнюю операцию //и делаю противоположную if((tempmenu=(MDCR&0b01000000))==0b01000000)//последняя операция + count--; if((tempmenu=(MDCR&0b01000000))==0b00000000)//последняя операция - count++; break; } } } //Функция опроса клавиатуры void fMenu() { count=1; while(1) { _delay_ms(10); LCDclr(); fChangeButton(); menu=fSelButton(); //Menu if(menu==0x06) { count*=10; } //если выбран пункт меню Left if(menu==0x05) { count--; //сбрасываю бит 6 - значит последняя операция была - MDCR&=0b10111111; } //выбран пункт меню Right if(menu==0x09) { count++; //выставляю бит 6 в единицу, - значит последняя операция была + MDCR|=0b01000000; } //если выбран Exit if(menu==0x0A) { if(count<10) break; if(count>=10) { count/=10; } } //функция отображения пункта меню в зависимости от значения count fDisplayMenu(count); }; }
Кратко можно описать так: идет опрос клавиатуры, нажимаем кнопку, в зависимости от нажатой кнопки делаем соответствующую операцию с count, в зависимости от полученного значения выводим пункт меню. На этом буду заканчивать. Надеюсь все понятно. Если что задавайте вопросы в комментариях.
|