Урок 36
Часть 2
Модуль LCD 16×2 .Продолжаем работать с кнопками
В первой части занятия мы настроили проект, также содали проект для протеуса, настроили таймер и добавили некоторые макроподстановки для хранения определённых статусов.
Сегодня же мы продолжим начатое дело.
Начнём писать работу кнопок.
В файле реализации функций библиотеки button.c создадим функцию для определения текущего статуса кнопки
//—————————————
unsigned char Read_Button_Press(unsigned char b)
{
switch(b)
{
case Button_Right:
if(adc_value<25) return ST_PRESSED;
else return ST_UNPRESSED;
break;
case Button_Up:
if((adc_value>25)&&(adc_value<65)) return ST_PRESSED;
else return ST_UNPRESSED;
break;
case Button_Down:
if((adc_value>65)&&(adc_value<115)) return ST_PRESSED;
else return ST_UNPRESSED;
break;
case Button_Left:
if((adc_value>115)&&(adc_value<180)) return ST_PRESSED;
else return ST_UNPRESSED;
break;
case Button_Select:
if((adc_value>180)&&(adc_value<230)) return ST_PRESSED;
else return ST_UNPRESSED;
break;
}
return ST_ERROR;
}
Добавим массив счётчиков в файле button.c
#include «button.h»
//—————————————
static unsigned char but_cnt[5]={0};
Массив счётчиков для каждой кнопки нам потребуется для устранения дребезга кнопок. Но именно такой счётчик нужен для каждой кнопки. По-другому нельзя. Я пробовал, получается каша и ничего не работает.
Теперь напишем функцию обработки состояния кнопки и установки окончательного статуса
//—————————————
void Read_Button_State (unsigned char b)
{
if ((button_state[b]&ST_LOCKED)!=0) return;
if(Read_Button_Press(b)==ST_UNPRESSED)
{
if (but_cnt[b]>0)
{
but_cnt[b]—;
}
else
{
if ((button_state[b]&ST_PRESSED)!=0)
{
button_state[b] |= ST_UNPRESSURE;
button_state[b] &= ~ST_PRESSED;
button_state[b] |= ST_UNPRESSED;
}
}
}
else
{
if (but_cnt[b]<5)
{
but_cnt[b]++;
}
else
{
if ((button_state[b]&ST_UNPRESSED)!=0)
{
button_state[b] |= ST_PRESSURE;
button_state[b] &= ~ST_UNPRESSED;
button_state[b] |= ST_PRESSED;
}
}
}
}
//——————————————
Чтобы данная функция виделась из функции-обработчика прерывания от таймера, прототип на неё добавим в файле button.c в начале кода
static unsigned char cnt=0, but_cnt[5]={0};
//—————————————
void Read_Button_State (unsigned char b);
Напишем функцию инициализации статусов кнопок
//——————————————
void Buttons_Ini(void)
{
unsigned char i;
//обнулим счётчики и сбросим статусы
for (i=0;i<5;i++)
{
button_state[i] = ST_UNPRESSED;
}
//запустим таймер
init_button_timer();
}
//——————————————
Напишем на неё прототип и вызовем в файле main.c в главной функции main()
#define ST_LOCKED 0b00100000 //кнопка недоступна
//——————————————-
void Buttons_Ini(void);
//——————————————-
#endif /* BUTTON_H_ */
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
ADC_Init(); //инициализируем АЦП
Buttons_Ini(); //инициализируем состояние кнопок
Соберём код и опять проверим данный код протеусе, что у нас по-прежнему всё нормально работает и что таймер ни как не мешает и не влияет на работоспособность нашего кода.
Дальнейшую работу с написанными нами функциями для обеспечения отслеживания всех статусов и изменения статусов кнопок мы продолжим в следующей части.
Предыдущая часть Программирование МК AVR Следующая часть
Приобрести программатор USBASP USBISP с адаптером можно здесь USBASP USBISP 3.3 с адаптером
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
а есть код на ассемблере?