Obsługa przycisków jest często jednym z pierwszych wyzwań, jakich podejmują się początkujący adepci programowania układów wbudowanych. I bardzo często zderzają się wówczas z “magicznym” zachowaniem 🙂 W naszym projekcie również musimy sobie z tym poradzić – a więc do dzieła!
Załóżmy, że przycisk chwilowy jest podłączony do portu mikrokontrolera w następujący sposób:
Gdyby zarejestrować przebieg jaki pojawia się na wejściu cyfrowym mikrokontrolera w momencie naciskania i puszczania przycisku, zobaczylibyśmy coś następującego:
Zarówno przy naciskaniu jak i zwalnianiu pojawia się seria szybkich przełączeń stanu logicznego. Zazwyczaj przypisywana jest zjawisku “drgania styków”. W rzeczywistości w momencie zwierania oraz rozwierania styku rezystancja gwałtownie zmienia się nie tylko ze względów czysto mechanicznych. Powierzchnia obu kontaktów jest bowiem zawsze pokryta cienką warstwą utlenionego metalu, kurzu, soli i innych zanieczyszczeń, których przemieszczanie się pod wpływem nacisku powoduje gwałtowne wahanie się rezystancji połączenia przez kilka-kilkanaście milisekund.
Jak to wpłynie na zachowanie naszego układu?
W każdym niemalże kursie programowania mikrokontrolerów przedstawia się metodę wykrywania naciśnięcia przycisku za pomocą przerwania, reagującego na zbocze opadające i narastające. Wspomniane “drgania styków” spowodują, że zostanie wygenerowana cała seria następujących po sobie przerwań (czerwone strzałeczki).
Należy pamiętać, iż każde przerwanie wywłaszcza procesor na czas obsługi, przerywając aktualnie wykonywane zadanie o niższym priorytecie. W przypadku wydajnego procesora nie ma to większego wpływu na działanie układu, jednak jest rozwiązaniem mało eleganckim. Dlatego wprowadza się tzw. strefę nieczułości lub strefę zakazaną, w której sprawdzanie stanu wejścia jest zablokowane. Pozwala to ograniczyć liczbę generowanych przerwań. Najczęściej do odmierzania czasu jej trwania stosuje się dedykowany, sprzętowy licznik. Generuje on własne przerwanie, na którym ponownie sprawdzany jest stan portu. Jeśli pokrywa się ze zboczem, które wymusiło pierwsze przerwanie, możemy założyć, że stan przycisku jest stabilny. Pewnym rozszerzeniem tej metody jest cykliczne sprawdzanie stanu wejścia w czasie trwania strefy nieczułości.
Czas jednak zadać sobie kardynalne pytanie – czy na prawdę potrzebujemy aż przerwania? Warto zauważyć, że większość procesorów ma mocno ograniczoną liczbę zewnętrznych wejść, które są w stanie je generować. Marnowanie ich możliwości na obsługę przycisków nie jest najlepszym pomysłem. Dodatkowo są one często przypisane “sztywno” do określonych pinów układu, co utrudnia późniejsze projektowanie płytki drukowanej.
Czy zatem stosowanie przerwania do obsługi przycisku ma w ogóle sens?
Tak. Jeśli korzystamy z trybów uśpienia, przerwanie może zostać wykorzystane do “obudzenia” procesora. Po obsłużeniu żądania, ponownie przejdzie on w tryb zmniejszonego poboru mocy i będzie oczekiwał na kolejne naciśnięcie przycisku.
Ta sytuacja nie dotyczy jednak omawianego urządzenia. Zastanówmy się więc nad alternatywą.
A co jeśli periodycznie sprawdzalibyśmy wejście i w przypadku ustabilizowania się jego stanu po kilku-kilkunastu odczytach, zatrzaskiwali jego wartość?
Brzmi sensownie. Z pomocą przychodzi nam tu podstawa czasu, którą zbudowaliśmy nieco wcześniej. Praktyka pokazuje, że człowiek nie jest w stanie przełączać przycisku szybciej, niż co około 50ms. Nie warto więc sprawdzać stanu przycisku częściej, niż co 10ms (żółte strzałki). Stan nieustalony na wejściu będzie trwał maksymalnie kilkanaście milisekund, w przypadku mocno zużytych styków. Można więc śmiało założyć, że jeśli przy trzech kolejnych odczytach (pogrubione strzałki) stan portu się nie zmienia, pozycja przycisku jest stabilna.
Zaproponowana metoda jest niezwykle prosta i skuteczna. Nie wymaga przy tym stosowania przerwań i dedykowanych liczników/timerów. Mamy więc informację kiedy kierowca naciśnie jeden z przycisków na manetce, co jednak zrobić, żeby przełożyć to na przykład na zmianę pozycji menu? Trzeba zastanowić się nad rozsądnym interfejsem, ale o tym w następnym odcinku.