Я, например, вот так сделал (для обработки коротких и длинных нажатий трёх кнопок):
uint8_t buttonFlags = 0; // буфер флагов зарегистрированных нажатий
// ОПРОС КНОПОК
void buttons_check(void)
{
uint8_t buttonState = 0; // буфер для текущего состояния кнопок
static uint8_t buttonPressCounter[] = { 0, 0, 0 }; // счётчики продолжительности нажатия кнопок
buttonState = ( BUTTON0_STATE | BUTTON1_STATE << 1 | BUTTON2_STATE << 2 ) ^ 0x07;
for ( uint8_t i = 0; i <= 2; i++ ) // для каждой из 3 кнопок проверяем:
{
if ( ((buttonState >> i) & 1) ) // если кнопка нажата
{
buttonPressCounter[i]++; // увеличиваем значение счётчика
if ( buttonPressCounter[i] == 3 ) // если кнопка нажата около 50мс
{
buttonFlags |= ( 1 << i ); // фиксируем короткое нажатие
}
else if ( buttonPressCounter[i] == 95 ) // если кнопка нажата около 1.5 секунд
{
buttonFlags |= ( 1 << i ) | ( 1 << (i+3) ); // фиксируем длинное нажатие
buttonPressCounter[i] = 80; // повторяем действие длинного нажатия при удерживании кнопки (примерно 4 раза в секунду)
}
else
{
buttonFlags &= ~( 1 << i ); // сбрасываем флаг короткого нажатия кнопки
}
}
else // если кнопка отпущена
{
buttonPressCounter[i] = 0; // сбрасываем счётчик
buttonFlags &= ~( ( 1 << i ) | ( 1 << (i+3)) ); // сбрасываем флаги нажатия кнопки
}
}
}
Функция вызывается в теле обработчика прерывания по таймеру, перед функцией - обработчиком нажатий, в зависимости от текущего состояния переменной
buttonFlags, и там же, делаем другие нужные нам вещи, типа обновления информации на дисплее, и т.д.) Таким образом, всего одним таймером убиваем сразу всех зайцев :)
P.S. Значения счётчиков - 3, 80 и 95 - с расчётом, что прерывание по таймеру срабатывает каждые 16мс.
P.P.S. Если чё, сильно не пинять - я ни разу не программист, а так, балуюсь немножко ))