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

 

 

 

 

Урок 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 с кнопками

 

 

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

 

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

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

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

*