Урок 63
Часть 2
Модуль LCD 16×2. МЕНЮ
В предыдущей части нашего занятия мы создали проект, настроили его, создали функцию управления программой и заполнили в ней один кейс.
Что ж, продолжим.
Подключим ещё одну глобальную переменную в menu.c
extern uint16_t menutim_cnt;//счетчик для мигания пунктов
extern uint8_t button_state[5];
Добавим код во 2-й кейс
case MENU_STATE_WAIT: //ждем запуска главного меню
if(button_state[Button_Select]&ST_UNPRESSURE)
{
SetButtonState(Button_Select,ST_LOCKED);
ResetButtonState(Button_Select,ST_UNPRESSURE);
SetButtonState(Button_Select,ST_PRESSURE);
//обработка нажатия кнопки
menu_state = MENU_STATE_MAIN;
}
break;
Также уберём все локальные переменные из главной функции main()
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
Ещё раз соберем и прошьем код.
Начнём теперь реализовывать работоспособность кнопок.
Создадим ещё одну функцию в файле menu.c
//———————————————-
void MainMenuProcess(void)
{
while (1)
{
switch (main_menu_state)
{
case MAIN_MENU_STATE_IDLE: //старт главного меню
break;
case MAIN_MENU_STATE_WAIT: //Ожидаем выбора меню
break;
case MAIN_MENU_STATE_MM1_WAIT: //ожидание выбора 1 пункта
break;
case MAIN_MENU_STATE_MM2_WAIT: //ожидание выбора 2 пункта
break;
case MAIN_MENU_STATE_MM3_WAIT: //ожидание выбора 3 пункта
break;
case MAIN_MENU_STATE_MM4_WAIT: //ожидание выбора 4 пункта
break;
case MAIN_MENU_STATE_MM5_WAIT: //ожидание выбора 5 пункта
break;
case MAIN_MENU_STATE_EXIT_WAIT: //ожидание выбора пункта EXIT
break;
case MAIN_MENU_STATE_MM1: //выбор пункта 1
break;
case MAIN_MENU_STATE_MM2: //выбор пункта 2
break;
case MAIN_MENU_STATE_MM3: //выбор пункта 3
break;
case MAIN_MENU_STATE_MM4: //выбор пункта 4
break;
case MAIN_MENU_STATE_MM5: //выбор пункта 5
break;
case MAIN_MENU_STATE_EXIT: //выбор пункта EXIT
break;
}
}
}
Добавим для неё прототип в этом же файле сверху
static uint8_t i=0;
//———————————————-
void MainMenuProcess(void);
//———————————————-
Вызовем данную функцию в предыдущей функции:
case MENU_STATE_MAIN: //запуск главного меню
main_menu_state=MAIN_MENU_STATE_IDLE;
MainMenuProcess();
break;
Заполним первый кейс в функции MainMenuProcess
case MAIN_MENU_STATE_IDLE: //старт главного меню
LCD_SetPos(0,0);
for(i=0;i<3;i++)
{
LCD_String(str2[i]);
}
LCD_SetPos(0,1);
for(i=0;i<3;i++)
{
LCD_String(str2[i+3]);
}
HAL_Delay(50);
ResetButtonState(Button_Select,ST_LOCKED);
main_menu_state = MAIN_MENU_STATE_WAIT;
break;
Соберём код, прошьём контроллер и проверим вход в меню по кнопке «SELECT»
Заполним 2й кейс
case MAIN_MENU_STATE_WAIT: //Ожидаем выбора меню
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;
}
break;
Теперь напишем функцию, которая заставит мигать выбранный пункт меню
//———————————————-
//мигание пункта меню
void BlinkItem(uint8_t ind)
{
if(ind<3) LCD_SetPos(ind*5,0);
else LCD_SetPos((ind-3)*5,1);
if(menutim_cnt>200) LCD_String(str2[ind]);
else LCD_String(» «);
}
Наверху в этом же файле добавим для нее прототип
void MainMenuProcess(void);
void BlinkItem(uint8_t ind);
Напишем код в следующий кейс
case MAIN_MENU_STATE_MM1_WAIT: //ожидание выбора 1 пункта
BlinkItem(0);
//правая клавиша
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_MM2_WAIT;
LCD_SetPos(0,0);
LCD_String(str2[0]); //зажжем 1 пункт, а то вдруг он в потухшем состоянии
}
//левая клавиша
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_EXIT_WAIT;
LCD_SetPos(0,0);
LCD_String(str2[0]); //зажжем 1 пункт, а то вдруг он в потухшем состоянии
}
//клавиша вниз
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_MM4_WAIT;
LCD_SetPos(0,0);
LCD_String(str2[0]); //зажжем 1 пункт, а то вдруг он в потухшем состоянии
}
//клавиша 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_MM1;
LCD_SetPos(0,0);
LCD_String(str2[0]); //зажжем 1 пункт, а то вдруг он в потухшем состоянии
}
break;
Соберём код, прошьём контроллер и посмотрим реакцию на правую кнопку после выбора главного меню.
Работать с другими кейсами данной функции мы будем в следующей части нашего занятия.
Предыдущая часть Программирование МК STM32 Следующая часть
Отладочную плату можно приобрести здесь STM32F4-DISCOVERY
Дисплей с кнопками можно приобрести здесь Дисплей LCD 16×2 с кнопками
Смотреть ВИДЕОУРОК (нажмите на картинку)
Добавить комментарий