Nie mam teraz czasu, żeby pisać przykładowy kod lub dokładnie opisywać algorytm. Mogę podpowiedzieć Ci jedynie z grubsza, jak uniknąć czekania w procedurze obsługi przerwania.
Skoro używasz timera do cyklicznego sprawdzania stanu klawisza i ustaliłeś sobie stałą czasową debouncingu na 80ms, to spróbuj to zrobić tak (nie stosując oczywiście żadnych _delay_ms() w przerwaniu):
- skonfiguruj timer tak, aby generował przerwanie co 80ms,
- zdefiniuj sobie wewnątrz procedury obsługi przerwania zmienną statyczną, w której będziesz zapamiętywał poprzedni stan klawisza,
- odczytaj aktualny stan klawisza i porównaj go z poprzednim,
- jeśli poprzedni stan będzie "wciśnięty" i aktualny stan będzie "wciśnięty", to oznacza, że możesz uznać klawisz za wciśnięty,
- na końcu procedury zapamiętaj aktualny stan klawisza jako "poprzedni", aby przy następnym wywołaniu porównać go z następnym, itd.
Potraktuj procedurę obsługi przerwania jako funkcję która się wykonuje "w kółko", tylko robi sobie przerwy. Wtedy łatwiej będzie Ci zbudować właściwy algorytm.
W ten sposób efekt jest ten sam, czyli sprawdzasz klawisz dwa razy w odstępie 80ms, ale nie musisz czekać w przerwaniu na ponowne sprawdzenie. Przerwanie zostanie po prostu wywołane dwukrotnie w odstępie 80ms, sprawdzi tylko stan klawisza i się zakończy, a czas pomiędzy przerwaniami może być wykorzystany przez mikrokontroler na inne czynności.
80ms przy taktowaniu 16MHz to
1 280 000 taktów, więc mikrokontroler może w tym czasie zrobić naprawdę bardzo dużo pożytecznych rzeczy
Podejrzewam, że podobną technikę pokazał kolega Mirek w jakiejś książce, lub w którymś poradniku, ale to może ktoś inny podpowie (bo ja tego nie wiem), miałbyś się na czym wzorować, jeśli nie masz pomysłu, jak to zrobić.