Так или иначе, всем разработчикам программ для микроконтроллеров
приходится сталкиваться с механическими контактами. Это могут быть
кнопки, механические датчики и т.п.  Не помню уже где, я подсмотрел
красивое и простое решение для программного подавления дребезга
контактов.

В кратце, суть решения заключается в хранении нескольких результатов
опроса входа и переключении его логического состояния только если все
эти состояния совпадают.

Для каждого входа заводится переменная-аккумулятор, в которой при опросе
входа сначала делается побитовый сдвиг на 1 бит, а затем заносится в
младший бит текущее состояние. Если переменная принимает значение,
состоящее из всех единиц, значит вход активен. Если переменная принимает
значение из всех нулей, значит вход не активен.

Приведу пример кода:

// Key Accumulator
static uint16_t KeyAcc = 0;

// Key State
static uint16_t Key = 0;

// Read Key
void ReadKey() {
   KeyAcc = KeyAcc << 1;
   KeyAcc |= !(KEYPORT & KEYPIN);
   if(KeyAcc == 0xFFFF) Key = 1;
   if(KeyAcc == 0) Key = 0;
}

Функция ReadKey() вызывается либо из главного цикла программы, либо по
прерыванию таймера. В главном цикле обрабатывается переменная Key.

if(Key) {
  кнопка нажата
}