чтение состояния кнопок

Обсуждаем контроллеры компании Atmel.
Закрыто
Вымогатель припоя
Сообщения: 580
Зарегистрирован: Пт ноя 08, 2013 01:01:18

Сообщение melandr »

Добрый день, может кто подскажет. Использую где-то найденный код для чтения кнопок. Код нравится тем, что не зависает в цикле или задержке для исключения дребезга кнопок.
Вот файл button.h
Спойлер#ifndef BUTTON_H
#define BUTTON_H

//настройки параметров библиотеки
#define BTN_LOCK_TIME 20 /* время обработки дребезга в милисекундах (10-100) */
#define BTN_LONG_TIME 1000 /* время фиксации длинного нажатия в милисекундах (1000 - 2500) */

//настройка портов и линий
#define BTN_PORT PORTD /* порт кнопок */
#define BTN_PIN PIND
#define BTN_POWER (1<<0) /* линии кнопок */
#define BTN_UP (1<<5)
#define BTN_DOWN (1<<6)

//определения флагов кнопок
#define BTN_SHRT_UP (1<<0) /* флаги короткого нажатия кнопок */
#define BTN_SHRT_DOWN (1<<1)
#define BTN_SHRT_POWER (1<<2)
#define BTN_LONG_UP (1<<4) /* флаги длинного нажатия кнопок */
#define BTN_LONG_DOWN (1<<5)
#define BTN_LONG_POWER (1<<6)

//объявления функций
void BtnInit (void); //инициализация библиотеки
uint8_t BtnGet (void); //функция чтения маски нажатой кнопки
void BtnExe (void); //функция циклического опроса кнопок (вызывать с частотой 100Гц, например из прерывания)


#endif /* BUTTON_LIB_ */
и файл button.c
Спойлер#include <avr/io.h>
#include "button.h"

//-----------------------------------------------------------------------------------------------------------------------
//глобальные переменные
volatile uint8_t BtnFlags; //регистр флагов нажатых кнопок

//-----------------------------------------------------------------------------------------------------------------------
//функция инициализации портов (вызвать перед использованием библиотеки)
void BtnInit (void)
{
BTN_PORT |= (BTN_UP| BTN_DOWN | BTN_POWER);//подтяжка кнопок
}

//-----------------------------------------------------------------------------------------------------------------------
//функция чтения маски нажатых кнопок
//возвращает маску нажатых кнопок (биты 0-3 - коротк нажат, биты 4-7 - длинн нажат)
uint8_t BtnGet (void)
{
asm ("cli");
uint8_t temp = BtnFlags;
BtnFlags = 0;
asm ("sei");
return temp;
}


//-----------------------------------------------------------------------------------------------------------------------
//функция циклического опроса кнопок (вызывать с частотой 100Гц, например в прерывании)
void BtnExe (void)
{
static uint8_t BtnLockBit; //защелка (защита от дребезга)
static uint8_t BtnLockCoun; //счетчик защелки (защита от дребезга)
static uint8_t BtnLongCoun; //счетчик длинного нажатия
static uint8_t BtnMascLast; //запомнить маску нажатой кнопки для анализа после отжатия кнопки

uint8_t BtnMask = 0;
if (~BTN_PIN & BTN_UP) BtnMask = BTN_SHRT_UP;//формирование маски нажатых кнопок
if (~BTN_PIN & BTN_DOWN) BtnMask = BTN_SHRT_DOWN;
if (~BTN_PIN & BTN_POWER) BtnMask = BTN_SHRT_POWER;
//основной алгоритм обработки событий кнопки
if (BtnMask){ //клавиша нажата
BtnMascLast = BtnMask; //запоминаем для использования после отпускания кнопки

if (BtnLockCoun < (BTN_LOCK_TIME/10)){
BtnLockCoun++; //обработка дребезга
return;
}

BtnLockBit=1; //нажатие зафиксировано
if (BtnLongCoun >= (BTN_LONG_TIME/10))
return;

if (++BtnLongCoun >= (BTN_LONG_TIME/10))
BtnFlags |= (BtnMask << 4); //установка бита длинного нажатия (старшие 4 бита флагов ButtonByte)
}

else{ //клавиша отжата
if (BtnLockCoun){ //обработка дребезга
BtnLockCoun --;
return;
}

if (! BtnLockBit) //отжатие зафиксировано
return;

BtnLockBit =0;
if (BtnLongCoun < (BTN_LONG_TIME/10))
BtnFlags |= BtnMascLast; //установка бита короткого нажатия (младшие 4 бита флагов ButtonByte)

BtnLongCoun = 0;
}
}
Необходимо добавить отслеживание нажатия или отпускания кнопки POWER с учетом дребезга. В существующем коде определяется как длинное нажатие. А нужно если нажали POWER - включаем таймер, а если отпустили отключаем таймер.
Реклама
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

Вот тут выкладывали модуль опроса клавиатуры, длительного нажатия нету но там дальше я спрашивал как его сделать.
http://radiokot.ru/forum/viewtopic.php? ... 8#p1470598

И вот еще один алгоритм.
http://radiokot.ru/forum/viewtopic.php? ... 9#p2787149
Реклама
Закрыто

Вернуться в «AVR»