Подавление дребезга кнопок - это в любом случае та или иная разновидность ФНЧ. Для небольшого числа кнопок можно при периодическом опросе просто задвигать в байтовую переменную текущее состояние входа, таким образом накапливая последние 8 отсчётов. Если они все равны 1 - значит кнопка нажата, если все 0 - отпущена, если другое значение - дребезг ещё продолжается, этакий вырожденный случай фильтра скользящего среднего на 8 отсчётов.
Пример, простой терминал о четырёх кнопках и LCD-индикаторе (на AVR):
Код
/* кнопки, 4 штуки, подключены к выводам порта D и земле */
#define iBTN1 PIND_Bit2
#define iBTN2 PIND_Bit3
#define iBTN3 PIND_Bit4
#define iBTN4 PIND_Bit5
#define ON (0xff)
#define OFF (0)
volatile char btn1 = 0;
volatile char btn2 = 0;
volatile char btn3 = 0;
volatile char btn4 = 0;
enum {not_pressed, pressed};
char keys_state = not_pressed;
#pragma vector = TIMER0_OVF_vect
__interrupt void TIMER0_OVF(void)
{
btn1 = (btn1 << 1) | ! iBTN1; // кнопки подключены к земле,
btn2 = (btn2 << 1) | ! iBTN2; // сразу инвертируем состояние входов iBTNx
btn3 = (btn3 << 1) | ! iBTN3;
btn4 = (btn4 << 1) | ! iBTN4;
}
__C_task void main(void)
{
/* ..инициализация периферии пропущена...*/
while(1)
{
int ch;
if( (ch = getc()) != EOF )
LCD_putchar(ch);
if( keys_state == pressed )
{
// нажатие кнопки уже отработано, ничего не делаем пока не отпустят
if( (btn1 == OFF) && (btn2 == OFF) && (btn3 == OFF) && (btn4 == OFF) )
keys_state = not_pressed;
}
else
{
if( btn1 == ON )
{ putc('\r'); keys_state = pressed; }
else if( btn2 == ON )
{ putc('['); keys_state = pressed; }
else if( btn3 == ON )
{ putc('-'); keys_state = pressed; }
else if( btn4 == ON )
{ putc('+'); keys_state = pressed; }
}
} // while(1)
}