123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- /**
- 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 мсек
- */
|