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



 

Урок 63

 

Часть 1

 

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

 

На последнем занятии по модулю LCD с кнопками мы проделали огромную работу, научившись отслеживать не только статус нажатия или отжатия кнопок, но и тот момент, когда происходит изменение этого статуса и реализовали это на нашем дисплее с кнопками.

Сегодня мы постараемся, используя опыт прошлых занятий, как-то это всё структурировать и, всё-таки, сочинить какую-нибудь навигацию или меню. А там посмотрим, что получится.

Проект был сделан из предыдущего проекта LCDBUTTONMODE и назван LCDBUTTONMENU.

Запустим новый проект в Cube MX и, ничего в нём не меняя и не трогая, сгенерируем проект для Keil и откроем его.

Настроим программатор на авторезет, подключим файлы button.c и lcd.c к дереву проекта и соберём проект.

Отключим оптимизацию и попытаемся, ещё раз собрав проект, прошить контроллер. чтобы убедиться. что всё работает

 

image00

 

Добавим ещё одну глобальную переменную в файл main.c

 

volatile uint16_t adctim_cnt=0;
volatile uint16_t menutim_cnt=0;

 

Она будет нам нужна для мигания пункта меню.

Добавим также код в обработчик ADC

 

 if(adctim_cnt>1000)
 {
  adctim_cnt=0;
  if(menutim_cnt>400)
  {
   menutim_cnt=0;
   HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_12);
  }
  menutim_cnt++;

  TIM_Callback();
 }

 

Пока помигаем зелёным светодиодом, чтобы оценить скорость мигания. Учитываем то, что пункты будут мигать вдвое быстрее.

Соберём проект, прошьём контроллер и посмотрим.

 

 

Теперь создадим и добавим в проект файлы menu.c и menu.h самым обычным образом. Подключим файл menu.h в файл main.h

 

#include «button.h»
#include «menu.h»

 

Также подключим файл menu.h в файл menu.c, а также добавим там пару переменных

 

#include «menu.h»
//———————————————-
extern uint16_t menutim_cnt;//счетчик для мигания пунктов
static uint8_t i=0;

 

Содержимое файла menu.h

 

#ifndef MENU_H_
#define MENU_H_
//————————————————
#include «stm32f4xx_hal.h»
#include «stdint.h»
//————————————————
#endif /* MENU_H_ */

 

Подключим в него также библиотеки дисплея и кнопок

 

#include «stdint.h»
#include «lcd.h»

#include «button.h»
 

Добавим функцию в файле menu.c

 

static uint8_t i=0;
//———————————————-
void MenuProcess(void)
{
  HAL_Delay(50);
}

 

Добавим для этой функции прототип в заголовочном файле

 

#include «stdint.h»
//————————————————
void MenuProcess(void);
//————————————————

 

 

Удалим задержку из бесконечного цикла главной функции main(), остальной код в теле данного цикла пока закомментируем, т.к. пригодится. Тажже вызовем в бесконечном цикле нашу только что написанную функцию

 

  while (1)
  {
   MenuProcess();
//  adc_value=ADC_Data;//занесём результат преобразований в переменную

 

Удалим объявление переменной в main()

 

 uint8_t i=0;

 

Массив str1 перенесем и немного исправим в файл menu.c, а в источнике удалим

 

static uint8_t i=0;
//———————————————-
char str1[6][11]=
{
  «MM_1 \0»,
  «MM_2 \0»,
  «MM_3 \0»,
  «MM_4 \0»,
  «MM_5 \0»,
  «EXIT \0»
};

//———————————————-

 

В файле menu.h добавим  две структуры для запоминания состояния нашей программы (типа в каком меню мы находимся)

 

#include «stdint.h»
//————————————————
typedef enum {
  MENU_STATE_IDLE = 0,
  MENU_STATE_WAIT,
  MENU_STATE_MAIN,
}MENU_StateTypeDef;

typedef enum {
  MAIN_MENU_STATE_IDLE = 0,
  MAIN_MENU_STATE_WAIT,
  MAIN_MENU_STATE_MM1,
  MAIN_MENU_STATE_MM2,
  MAIN_MENU_STATE_MM3,
  MAIN_MENU_STATE_MM4,
  MAIN_MENU_STATE_MM5,
  MAIN_MENU_STATE_EXIT,
  MAIN_MENU_STATE_MM1_WAIT,
  MAIN_MENU_STATE_MM2_WAIT,
  MAIN_MENU_STATE_MM3_WAIT,
  MAIN_MENU_STATE_MM4_WAIT,
  MAIN_MENU_STATE_MM5_WAIT,
  MAIN_MENU_STATE_EXIT_WAIT
}MAIN_MENU_StateTypeDef;

//————————————————

 

Добавим ещё две инициализированных переменных в файл menu.c

 

«EXIT \0»
};
MENU_StateTypeDef menu_state = MENU_STATE_IDLE;
MAIN_MENU_StateTypeDef main_menu_state = MAIN_MENU_STATE_IDLE;

 

В файле menu.c в функцию MenuProcess добавим следующий код, отслеживающий текущее состояние программы

 

void MenuProcess(void)
{
  switch (menu_state)
  {
    case MENU_STATE_IDLE: //старт программы
    break;
    case MENU_STATE_WAIT: //ждем запуска главного меню
    break;
    case MENU_STATE_MAIN: //запуск главного меню
    break;
  }

  HAL_Delay(50);

 

Добавим код в первый кейс

 

  case MENU_STATE_IDLE: //старт программы
   menu_state = MENU_STATE_WAIT;
   LCD_Clear();
   LCD_SetPos(0,0);//спозиционируем курсор
   LCD_String(«MENU»);
   LCD_SetPos(0,1);
   LCD_String(«Press SELECT»);

   break;

 

Можно собрать проект, прошить его в МК и проверить отображение данных строк.

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

 

 

Предыдущий урок Программирование МК STM32 Следующая часть

 

 

Отладочную плату можно приобрести здесь STM32F4-DISCOVERY

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

 

 

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

 

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

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

    Добрый день, Владимир! Если не трудно, то неплохо бы промежуточные варианты прошивки выкладывать! Говорю потому что там порой бывает что часть кода теряется и для возврата в промежуточный код много времени тратится и не всегда удачно!

    • Добрый день! Мне обычный код не так просто выкладывать, а Вы хотите промежуточный. Я вообще всегда был против всякого выкладывания кода. Люди начинают надеяться на готовый код, из-за этого материал не усваивается. Думаю, прекращать надо с выкладыванием кода, тогда вопросы все отпадут.

  2. Валерий:

    Это не претензия — это пожелание! Мне трудно с Вами спорить! Вы в этом ПРОФИ! Вам и так спасибо что тратите на нас время! Более того Вы в данном случае исходите безусловно из того чтобы не донимали вопросами по коду. Так все равно будут донимать по другим вопросам. Я же со своей точки зрения, поскольку в чем то я был все же в этой жизни ПРОФИ, и мне именно то что у ВАС есть коды нравиться не менее, чем сами уроки. Поскольку масса примеров есть, а кода нет и списывать его с экрана уйма времени, а сходу запомнить идею в моем возрасте уже проблема. Это для  тех кому до 30. А для разных категорий учеников — разные методы и подходы, не хочется повторять банальности.

  3. Александр:

    Спасибо Вам большое за труд!

    Очень не хватает общих слов, которые бы помогли понять в целом принцип работы и создания меню. Какие структуры нужны, в каком количестве? Сколько и каких функций? Как они взаимодействуют друг с другом? Это всё приходится выуживать самостоятельно, хотя это как мне кажется самая ценная информация конкретно для этого урока.

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

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

*