Урок 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
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
Добавить комментарий