Поиск по этому блогу

4 нояб. 2016 г.

Обработка нажатия кнопки в прерывании


Для обработки факта нажатия/отпускания кнопки так же можно использовать прерывания. Преимущества такого способа — в отсутствии необходимости в программе постоянно контролировать уровень сигнала на входе, к которому подключена кнопка.
Для отработки состояния кнопки в прерывании нужно определить процедуру обработки и подключить ее в качестве обработчика аппаратного прерывания по какому-нибудь входу (для Arduino UNO — это pin2 (Int0) или pin3 (Int1).

#define p_Sw 2  //вход для кнопки (Int0) pin2
#define t_Dreb 50  //интервал для устранения дребезга (мс)

unsigned int n_Key = 0;   //считаем число нажатий на кнопку
int t_Tek = 0;    //текущий отсчет времени при определении нажатия
int t_Pred = 0;   //предыдущий отсчет
int t_T1 = 0;     //длительность отсутствия реакции на кнопку
int pin_Tek = 1;  //состояние кнопки (0 - замкнута)

void setup() { 
  Serial.begin(9600);  
  pinMode(p_Sw, INPUT_PULLUP); //вход с внутр.резистором на VCC
  attachInterrupt(0, pressK, CHANGE);  //кнопка на Int0 (pin2)
}

void loop() {
  Serial.println(n_Key);
  delay(2000);
}

void pressK()  //обработка прерывания от кнопки (Int0)
{
   pin_Tek = digitalRead(p_Sw); //читаем текущее состояние pin2 (Int0)
   t_Tek = millis(); //текущий отсчет времени
   if (t_Tek > t_T1) {//если время подавления дребезга не прошло - игнорируем
        if (pin_Tek == 0) { //замкнуто
            n_Key ++; //подсчет числа нажатий
            t_Pred = t_Tek; //начало для определения след.периода
       }
   }
   t_T1 = t_Tek + t_Dreb; //определяем время отсутствия реакции
}
Приведенный пример выводит в последовательный канал состояние переменной n_Key, которая наращивается при каждом нажатии и отпускании кнопки. Кнопка подключена одним контактом к входу прерываний Int0 (pin2 Arduino), а другим — к общему проводу. Функция
attachInterrupt(0, pressK, CHANGE);
назначает процедуру pressK как обработчик прерывания по этому входу (нолик в первом аргументе). CHANGE — означает, что вызов процедуры будет по любому изменению на входе (иные варианты: LOW — по нулю; RISING — по переходу из 0 в 1; FALLING — по спаду из 1 в 0).
Процедура обработки «нечувствительна» к изменениям на входе в течение времени t_Dreb (задано 50 мс) после первого срабатывания, тем самым «как-бы подавляя дребезг контактов кнопки»).
Надо сказать, что подключение кнопки к входу прерываний — «дурной тон». Слишком уж непредсказуем дребезг контактов: процедура может быть вызвана слишком большое число раз :(. Но в не слишком ответственных системах можно поступить и так.