/** http://electronix.ru/forum/index.php?showtopic=93624&view=findpost&p=964475 Примерно лет шесть делаю так: */ // в .h-файле: // кол-во времени до события "длинное нажатие" #define TIMER_COUNT 250 // кол-во кнопок #define KEY_COUNT 4 // время автоинкремента #define TIMER_SCROLL 20 // состояние кнопки enum {KN_DOWN =0, KN_UP =1, KN_PRESS=2 }; // тип функции кнопки typedef byte(KeyFunc)(void); // структура хранящая набор переменных для каждой кнопки typedef struct key_struct__ { byte state; // состояние кнопки byte mask; // маска клавиши byte pins; // буфер значений с клавиши byte count; // счетчик нажатий KeyFunc * exec_down; KeyFunc * exec_up; KeyFunc * exec_pres; }key_struct; // в .c-файле: //***************************************************************************** // Драйвер кнопок // назначение кнопок // 1- MiNUS 2-PLUS 3- Select 4- Enter //***************************************************************************** //============================================================================= // состояния кнопок static key_struct key_mass [KEY_COUNT] = { //state mask pins count exec_down exec_up exec_pres {KN_UP, PIN_KEY_MINUS, 0xFF,0x00, kn_empty, kn_minus_up ,kn_minus_up } ,{KN_UP, PIN_KEY_PLUS, 0xFF,0x00, kn_empty, kn_plus_up ,kn_plus_up } ,{KN_UP, PIN_KEY_SELECT, 0xFF,0x00, kn_empty, kn_select_up ,kn_empty } ,{KN_UP, PIN_KEY_ENTER, 0xFF,0x00, kn_empty, kn_empty ,kn_enter_press } }; //============================================================================= ISR(TIMER1_COMPA_vect) { #define Sta key->state #define Pin key->pins #define Cnt key->count #define Msk key->mask #define Down key->exec_down #define Up key->exec_up #define Pres key->exec_pres key_struct * key = key_mass; for(byte i=0; i< KEY_COUNT ; i++) { Pin *=2; // * or << if(KEY_PIN & Msk) Pin |= 0x01; if(Sta == KN_UP) { if(!Pin) // начало счета - нажатие { Down(); Sta = KN_DOWN; Cnt = 0x00; } } else // down or press { if(Pin==0xFF) // отпустили { if(Sta == KN_DOWN) Up(); Sta = KN_UP; } else// удерживаем { if(Cnt <= TIMER_COUNT) ++Cnt; if(Cnt == TIMER_COUNT) // длительное удержание - попадаем один раз!! { if(Pres()) Cnt = TIMER_COUNT - TIMER_SCROLL; else Sta = KN_PRESS; } } } key++; } } /** Таймер в CTC-режиме на порядка 5....15 мсек */