Урок 63
Часть 3
Модуль LCD 16×2. МЕНЮ
В предыдущей части урока мы уже начали работать с реакцией на пункты нашего меню и написали код в один из кейсов функции пунктов главного меню
Добавим код в следующие четыре подобных кейса
case MAIN_MENU_STATE_MM2_WAIT: //ожидание выбора 2 пункта
BlinkItem(1);
//правая клавиша
if(button_state[Button_Right]&ST_UNPRESSURE)
{
SetButtonState(Button_Right,ST_LOCKED);
ResetButtonState(Button_Right,ST_UNPRESSURE);
SetButtonState(Button_Right,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Right,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM3_WAIT;
LCD_SetPos(5,0);
LCD_String(str2[1]); //зажжем 2 пункт, а то вдруг он в потухшем состоянии
}
//левая клавиша
if(button_state[Button_Left]&ST_UNPRESSURE)
{
SetButtonState(Button_Left,ST_LOCKED);
ResetButtonState(Button_Left,ST_UNPRESSURE);
SetButtonState(Button_Left,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Left,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM1_WAIT;
LCD_SetPos(5,0);
LCD_String(str2[1]); //зажжем 2 пункт, а то вдруг он в потухшем состоянии
}
//клавиша вниз
if(button_state[Button_Down]&ST_UNPRESSURE)
{
SetButtonState(Button_Down,ST_LOCKED);
ResetButtonState(Button_Down,ST_UNPRESSURE);
SetButtonState(Button_Down,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Down,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM5_WAIT;
LCD_SetPos(5,0);
LCD_String(str2[1]); //зажжем 2 пункт, а то вдруг он в потухшем состоянии
}
//клавиша SELECT
if(button_state[Button_Select]&ST_UNPRESSURE)
{
SetButtonState(Button_Select,ST_LOCKED);
ResetButtonState(Button_Select,ST_UNPRESSURE);
SetButtonState(Button_Select,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Select,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM2;
LCD_SetPos(5,0);
LCD_String(str2[1]); //зажжем 2 пункт, а то вдруг он в потухшем состоянии
}
break;
case MAIN_MENU_STATE_MM3_WAIT: //ожидание выбора 3 пункта
BlinkItem(2);
//правая клавиша
if(button_state[Button_Right]&ST_UNPRESSURE)
{
SetButtonState(Button_Right,ST_LOCKED);
ResetButtonState(Button_Right,ST_UNPRESSURE);
SetButtonState(Button_Right,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Right,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM4_WAIT;
LCD_SetPos(10,0);
LCD_String(str2[2]); //зажжем 3 пункт, а то вдруг он в потухшем состоянии
}
//левая клавиша
if(button_state[Button_Left]&ST_UNPRESSURE)
{
SetButtonState(Button_Left,ST_LOCKED);
ResetButtonState(Button_Left,ST_UNPRESSURE);
SetButtonState(Button_Left,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Left,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM2_WAIT;
LCD_SetPos(10,0);
LCD_String(str2[2]); //зажжем 3 пункт, а то вдруг он в потухшем состоянии
}
//клавиша вниз
if(button_state[Button_Down]&ST_UNPRESSURE)
{
SetButtonState(Button_Down,ST_LOCKED);
ResetButtonState(Button_Down,ST_UNPRESSURE);
SetButtonState(Button_Down,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Down,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_EXIT_WAIT;
LCD_SetPos(10,0);
LCD_String(str2[2]); //зажжем 3 пункт, а то вдруг он в потухшем состоянии
}
//клавиша SELECT
if(button_state[Button_Select]&ST_UNPRESSURE)
{
SetButtonState(Button_Select,ST_LOCKED);
ResetButtonState(Button_Select,ST_UNPRESSURE);
SetButtonState(Button_Select,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Select,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM3;
LCD_SetPos(10,0);
LCD_String(str2[2]); //зажжем 3 пункт, а то вдруг он в потухшем состоянии
}
break;
case MAIN_MENU_STATE_MM4_WAIT: //ожидание выбора 4 пункта
BlinkItem(3);
//правая клавиша
if(button_state[Button_Right]&ST_UNPRESSURE)
{
SetButtonState(Button_Right,ST_LOCKED);
ResetButtonState(Button_Right,ST_UNPRESSURE);
SetButtonState(Button_Right,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Right,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM5_WAIT;
LCD_SetPos(0,1);
LCD_String(str2[3]); //зажжем 4 пункт, а то вдруг он в потухшем состоянии
}
//левая клавиша
if(button_state[Button_Left]&ST_UNPRESSURE)
{
SetButtonState(Button_Left,ST_LOCKED);
ResetButtonState(Button_Left,ST_UNPRESSURE);
SetButtonState(Button_Left,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Left,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM3_WAIT;
LCD_SetPos(0,1);
LCD_String(str2[3]); //зажжем 4 пункт, а то вдруг он в потухшем состоянии
}
//клавиша вверх
if(button_state[Button_Up]&ST_UNPRESSURE)
{
SetButtonState(Button_Up,ST_LOCKED);
ResetButtonState(Button_Up,ST_UNPRESSURE);
SetButtonState(Button_Up,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Up,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM1_WAIT;
LCD_SetPos(0,1);
LCD_String(str2[3]); //зажжем 4 пункт, а то вдруг он в потухшем состоянии
}
//клавиша SELECT
if(button_state[Button_Select]&ST_UNPRESSURE)
{
SetButtonState(Button_Select,ST_LOCKED);
ResetButtonState(Button_Select,ST_UNPRESSURE);
SetButtonState(Button_Select,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Select,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM4;
LCD_SetPos(0,1);
LCD_String(str2[3]); //зажжем 4 пункт, а то вдруг он в потухшем состоянии
}
break;
case MAIN_MENU_STATE_MM5_WAIT: //ожидание выбора 5 пункта
BlinkItem(4);
//правая клавиша
if(button_state[Button_Right]&ST_UNPRESSURE)
{
SetButtonState(Button_Right,ST_LOCKED);
ResetButtonState(Button_Right,ST_UNPRESSURE);
SetButtonState(Button_Right,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Right,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_EXIT_WAIT;
LCD_SetPos(5,1);
LCD_String(str2[4]); //зажжем 5 пункт, а то вдруг он в потухшем состоянии
}
//левая клавиша
if(button_state[Button_Left]&ST_UNPRESSURE)
{
SetButtonState(Button_Left,ST_LOCKED);
ResetButtonState(Button_Left,ST_UNPRESSURE);
SetButtonState(Button_Left,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Left,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM4_WAIT;
LCD_SetPos(5,1);
LCD_String(str2[4]); //зажжем 5 пункт, а то вдруг он в потухшем состоянии
}
//клавиша вверх
if(button_state[Button_Up]&ST_UNPRESSURE)
{
SetButtonState(Button_Up,ST_LOCKED);
ResetButtonState(Button_Up,ST_UNPRESSURE);
SetButtonState(Button_Up,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Up,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM2_WAIT;
LCD_SetPos(5,1);
LCD_String(str2[4]); //зажжем 5 пункт, а то вдруг он в потухшем состоянии
}
//клавиша SELECT
if(button_state[Button_Select]&ST_UNPRESSURE)
{
SetButtonState(Button_Select,ST_LOCKED);
ResetButtonState(Button_Select,ST_UNPRESSURE);
SetButtonState(Button_Select,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Select,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM5;
LCD_SetPos(5,1);
LCD_String(str2[4]); //зажжем 5 пункт, а то вдруг он в потухшем состоянии
}
break;
Соберём проект, прошьём контроллер и посмотрим результат.
Все пункты нормально переключаются и мигают, ну конечно за исключением EXIT
Напишем код в следующий кейс — для ожидания нажатия на кнопку выхода из главного меню
case MAIN_MENU_STATE_EXIT_WAIT: //ожидание выбора пункта EXIT
BlinkItem(5);
//правая клавиша
if(button_state[Button_Right]&ST_UNPRESSURE)
{
SetButtonState(Button_Right,ST_LOCKED);
ResetButtonState(Button_Right,ST_UNPRESSURE);
SetButtonState(Button_Right,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Right,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM1_WAIT;
LCD_SetPos(10,1);
LCD_String(str2[5]); //зажжем пункт EXIT, а то вдруг он в потухшем состоянии
}
//левая клавиша
if(button_state[Button_Left]&ST_UNPRESSURE)
{
SetButtonState(Button_Left,ST_LOCKED);
ResetButtonState(Button_Left,ST_UNPRESSURE);
SetButtonState(Button_Left,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Left,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM5_WAIT;
LCD_SetPos(10,1);
LCD_String(str2[5]); //зажжем пункт EXIT, а то вдруг он в потухшем состоянии
}
//клавиша вверх
if(button_state[Button_Up]&ST_UNPRESSURE)
{
SetButtonState(Button_Up,ST_LOCKED);
ResetButtonState(Button_Up,ST_UNPRESSURE);
SetButtonState(Button_Up,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Up,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_MM3_WAIT;
LCD_SetPos(10,1);
LCD_String(str2[5]); //зажжем пункт EXIT, а то вдруг он в потухшем состоянии
}
//клавиша SELECT
if(button_state[Button_Select]&ST_UNPRESSURE)
{
SetButtonState(Button_Select,ST_LOCKED);
ResetButtonState(Button_Select,ST_UNPRESSURE);
SetButtonState(Button_Select,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Select,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_EXIT;
LCD_SetPos(10,1);
LCD_String(str2[5]); //зажжем пункт EXIT, а то вдруг он в потухшем состоянии
}
break;
Соберём код, прошьём контроллер и проверим ещё раз способность переключать выбор пунктов по кругу в разные стороны и сверху вниз.
Добавим глобальную переменную в файл menu.c
static uint8_t i=0;
char str1[6];
Напишем функцию для обработки входа в определённый пункт меню
//———————————————-
//вход в любой пункт главного меню
void MainMenuItemProcess(uint8_t ind)
{
LCD_Clear();
LCD_SetPos(0,0);
LCD_String(«ITEM «);
sprintf(str1,»%d»,ind);
LCD_String(str1);
LCD_String(» Press»);
LCD_SetPos(0,1);
LCD_String(«SELECT from exit»);
//здесь будут функции, вызываемые пунктами меню
switch (ind)
{
case 1:
//функция-обработчик 1 пункта меню
break;
case 2:
//функция-обработчик 2 пункта меню
break;
case 3:
//функция-обработчик 3 пункта меню
break;
case 4:
//функция-обработчик 4 пункта меню
break;
case 5:
//функция-обработчик 5 пункта меню
break;
}
while (1)
{
if(button_state[Button_Select]&ST_UNPRESSURE)
{
LCD_Clear();
SetButtonState(Button_Select,ST_LOCKED);
ResetButtonState(Button_Select,ST_UNPRESSURE);
SetButtonState(Button_Select,ST_PRESSURE);
//обработка нажатия кнопки
HAL_Delay(50);
ResetButtonState(Button_Select,ST_LOCKED);
return;
}
HAL_Delay(50);
}
}
Добавим на неё прототип вверху файла,
void BlinkItem(uint8_t ind);
void MainMenuItemProcess(unsigned char ind);
Добавим ещё один строчный массив
char str1[6];
char str3[5];
И в конце занятия добавим реакцию на выбор пунктов меню в функции MainMenuProcess
case MAIN_MENU_STATE_MM1: //выбор пункта 1
main_menu_state = MAIN_MENU_STATE_IDLE;
MainMenuItemProcess(1);
LCD_Clear();
break;
case MAIN_MENU_STATE_MM2: //выбор пункта 2
main_menu_state = MAIN_MENU_STATE_IDLE;
MainMenuItemProcess(2);
LCD_Clear();
break;
case MAIN_MENU_STATE_MM3: //выбор пункта 3
main_menu_state = MAIN_MENU_STATE_IDLE;
MainMenuItemProcess(3);
LCD_Clear();
break;
case MAIN_MENU_STATE_MM4: //выбор пункта 4
main_menu_state = MAIN_MENU_STATE_IDLE;
MainMenuItemProcess(4);
LCD_Clear();
break;
case MAIN_MENU_STATE_MM5: //выбор пункта 5
main_menu_state = MAIN_MENU_STATE_IDLE;
MainMenuItemProcess(5);
LCD_Clear();
break;
case MAIN_MENU_STATE_EXIT: //выбор пункта EXIT
menu_state = MENU_STATE_IDLE;
return;
}
При нажатии кнопки EXIT происходит именно выход из всей функции, а не из switch.
Собираем код, прошиваем контроллер, и если всё работает, то цель урока считаю достигнутой.
А уже конкретно реакцию в обработчике каждого пункта каждый будет писать под себя, в зависимости от того, какие именно будет он решать задачи, кто-то будет чем-то управлять, а кто-то напишет ещё какое то меню и произойдёт вход уже в него, благодаря тому, что в сегодняшнем уроке он научился, как именно это делать.
Предыдущая часть Программирование МК STM32 Следующий урок
Отладочную плату можно приобрести здесь STM32F4-DISCOVERY
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
Здравствуйте! Большое Вам спасибо за ваш труд. Очень интересно и познавательно.
И Вам спасибо за оценку!