STM Урок 61. Модуль LCD 16×2. Работаем с кнопками. Часть 1

 

 

 

 

Урок 61

 

Модуль LCD 16×2. Работаем с кнопками

 

Часть 1

 

 

Продолжаем работать с модулем LCD с кнопками и регулятором контрастности, с которым мы познакомились и уже написали некоторый код для определения нажатых кнопок в уроке 59.

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

Проект мы создадим из проекта LCDBUTTON и назовём его LCDBUTTONMODE.

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

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

Создадим ещё два новых файла button.c и button.h в соответствующих папках.

Текст файла button.h стандартный

 

#ifndef BUTTON_H_
#define BUTTON_H_
//————————————————
#include "stm32f4xx_hal.h"
#include "stdint.h"
//————————————————
#endif /* BUTTON_H_ */

 

Подключим данный файл и в button.c и в main.c

 

#include "button.h"

 

Для хранения состояния кнопок в файле button.с создадим массив для хранения статусов кнопок

 

#include "button.h"
//————————————————
uint8_t button_state[5];

 

В файле button.h создадим ещё и макросы для каждой кнопки

 

unsigned char button_state[5];
//————————————————
#define Button_Right 0x00
#define Button_Up 0x01
#define Button_Down 0x02
#define Button_Left 0x03
#define Button_Select 0x04

 

Кроме макросов для самих кнопок нам пригодятся также макросы для их состояний. Делаем всё по аналогии с уроком по AVR, чтобы сто раз не сочинять одно и то же, единственное то, что мы не можем использовать двоичные переменные, так как в Keil таких нет, поэтому двоичные значения напишем в комментариях

 

#define Button_Select 0x04
//————————————————
#define ST_PRESSED  0x01 //0b00000001 — кнопка нажата
#define ST_UNPRESSED 0x02 //0b00000010 — кнопка отжата
#define ST_ERROR   0x04 //0b00000100 — не удалось считать статус
#define ST_PRESSURE  0x08 //0b00001000 — процесс нажатия кнопки
#define ST_UNPRESSURE 0x10 //0b00010000 — процесс отжатия кнопки
#define ST_LOCKED   0x20 //0b00100000 — кнопка недоступна

 

 

Для мониторинга состояния входа ADC (он же выход делителя на кнопках) подключим глобальную переменную в файл button.c, а также добавим ещё одну переменную, в которую будем сохранять значение АЦП на время функции.

 

uint8_t button_state[5];
extern uint16_t ADC_Data;
uint16_t adc_value=0;

 

В этом же файле создадим функцию для определения текущего статуса кнопки

 

//————————————————
uint8_t Read_Button_Press(uint8_t b)
{
 adc_value=ADC_Data;
 switch(b)
 {
  case Button_Right:
   if(adc_value<200) return ST_PRESSED;
   else return ST_UNPRESSED;
  case Button_Up:
   if((adc_value>200)&&(adc_value<700)) return ST_PRESSED;
   else return ST_UNPRESSED;
  case Button_Down:
   if((adc_value>700)&&(adc_value<1200)) return ST_PRESSED;
   else return ST_UNPRESSED;
  case Button_Left:
   if((adc_value>1200)&&(adc_value<1800)) return ST_PRESSED;
   else return ST_UNPRESSED;
  case Button_Select:
   if((adc_value>1800)&&(adc_value<2300)) return ST_PRESSED;
   else return ST_UNPRESSED;
 }
 return ST_ERROR;
}

 

break здесь не требуется, так как при любом условии у нас выход из функции и мы до него не дойдём.

Давайте ещё немного поборемся с глюками.

Во-первых, в файле lcd.c в функции инициализации дисплея добавим ещё один раз отправку 0x28 в контроллер дисплея. В некоторой документации указано именно так

 

 LCD_Command(0x28);//еще раз для верности
 HAL_Delay(1);
 LCD_Command(0x28);//еще раз для верности
 HAL_Delay(1);

 

Итого таких отправок будет 3.

В функции main() разобьём секундную задержку пополам вокруг функции старта ADC

 

 LCD_Clear();
 HAL_Delay(500);
 HAL_ADC_Start_IT(&hadc1);
 HAL_Delay(500);

 

Добавим массив счётчиков в файле button.c

 

uint16_t adc_value=0;
static uint8_t but_cnt[5]={0};

 

Массив счётчиков для каждой кнопки нам потребуется для устранения дребезга кнопок. Но именно такой счётчик нужен для каждой кнопки. По-другому нельзя. Я пробовал, получается каша и ничего не работает.

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

А продолжим работать с нашей задачей мы в следующей части занятия.

 

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

 

 

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

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

 

 

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

 

STM32 Модуль LCD 16×2. Работаем с кнопками

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

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

*