STM Урок 63. Модуль LCD 16×2. МЕНЮ. Часть 3



Урок 63

Часть 3

Модуль LCD 16×2. МЕНЮ

 

В предыдущей части урока мы уже начали работать с реакцией на пункты нашего меню и написали код в один из кейсов функции пунктов главного меню

Добавим код в следующие четыре подобных кейса

MAIN_MENU_STATE_MM2_WAIT

  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;

MAIN_MENU_STATE_MM3_WAIT

   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;

MAIN_MENU_STATE_MM4_WAIT

 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;

MAIN_MENU_STATE_MM5_WAIT

   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

image01

 

Напишем код в следующий кейс — для ожидания нажатия на кнопку выхода из главного меню

 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

Дисплей с кнопками можно приобрести здесь MДисплей LCD 16×2 с кнопками

Смотреть ВИДЕОУРОК (нажмите на картинку)

STM Модуль LCD 16×2. МЕНЮ

2 комментария на “STM Урок 63. Модуль LCD 16×2. МЕНЮ. Часть 3
  1. Андрей:

    Здравствуйте!  Большое Вам спасибо за ваш труд. Очень интересно и познавательно. 

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*