(2 głosujących) W układach mikroprocesorowych bardzo często w roli interfejsu między urządzeniem a jego użytkownikiem wykorzystujemy klawiaturę złożoną z przycisków uSwitch. Gdy jest kilka przycisków to wystarczy proste podłączenie między portem mikrokontrolera a masą, dla większej liczby klawiszy wygodnie będzie zrobić klawiaturę matrycową, bo uzyskamy wtedy większą liczbę klawiszy a wykorzystamy mniej pinów procesora. Przedstawione tutaj procedury dotyczą obsługi tych dwóch typów klawiatury. Język Bascom AVRPoniżej przedstawiona jest prosta procedura odczytu czterech przycisków podłączonych do jednego portu, niewrażliwa na drgania styków i pozwalająca ustawić różny czas reakcji przy pojedynczym kliknięciu i podczas trzymania klawisza: Przyciski: Sw = PIND And &B11110000 'maskowanie nieużywanych pinów If Sw <> &B11110000 And Stan_sw = Sw Then Incr Licznik_sw If Licznik_sw = 100 Then Licznik_sw = 0 Select Case Stan_sw Case &B01110000: 'tutaj to co będzie po kliknięciu S1 Case &B10110000: 'tutaj to co będzie po kliknięciu S2 Case &B11010000: 'tutaj to co będzie po kliknięciu S3 Case &B11100000: 'tutaj to co będzie po kliknięciu S4 Case &B00110000: 'tutaj to co będzie po kliknięciu S1 i S2 razem End Select End If Else Stan_sw = Sw Licznik_sw = 80 End If Return Procedura dotyczy podłączenia jak na rysunku poniżej, zakładamy że inne piny tego portu są wykorzystywane w dowolny sposób i nie mamy wpływu na ich stany logiczne podczas odczytu klawiatury: Jak widać przyciski są podłączone do starszych 4 bitów portu D mikrokontrolera (żeby nie było za prosto). Musimy zatem uniezależnić się od zmieniających się stanów logicznych na pozostałych 4 bitach tego portu aby nie było problemów z klawiaturą. Wykonujemy to w pierwszej linijce procedury przypisując do zmiennej Sw(byte) wartość całego portu D ale z wyzerowanymi za pomocą polecenia And &B11110000 wartościami najmłodszych bitów (starsze 4 są bez zmian). Jeżeli nic nie zostało naciśnięte to stan odczytu przycisków wynosi zatem &B11110000, bo żaden nie zwarł do masy pinu procesora. Sprawdzane jest to w pierwszej instrukcji warunkowej i w spoczynku kiedy nic nie naciskamy to zawsze wykonują się polecenia po instrukcji Else, czyli przypisywanie aktualnego Stanu klawiatury do zmiennej Stan_sw, która przechowuje poprzednią wartość stanu przycisków, oraz ustawianie Licznik_sw = 80 na określoną wartość. Gdy Przycisk został wciśnięty to warunek sprawdza jeszcze dodatkowo czy stan klawisza jest taki jak był poprzednio (czy to na przykład nie jest drganie styku) i jeśli tak to zwiększany jest stan licznika (Licznik_sw). Gdy licznik dojdzie do ustalonej wartości (przycisk odpowiednio długo trzymany) to zostanie wykonana akcja dla klawiatury w zależności od tego co zostało kliknięte. Załatwia to wewnętrzna instrukcja Select Case Stan_sw, która wykonuje odpowiedni Case w zależności od stanu klawiszy. Dla przykładu stan &B01110000 odpowiada za kliknięcie przycisku S1 (zero na pinie PD.7), a &B00110000 odpowiada jednoczesnemu wciśnięciu S1 i S2 (zera na pinach PD.7 i PD.6) Tłumaczenia mogą jeszcze wymagać wartość zmiennej Licznik_sw pojawiające się w dwóch miejscach w procedurze. Zależą one od częstotliwości wywoływania procedury obsługi klawiatury przez program, oraz od żądanego czasu reakcji klawisza na przyciskanie. Wartości te zostały dobrane dla procedury wywoływanej co 4ms. Podczas spoczynku gdy nic nie jest naciskane zmienna Licznik_sw ma wartość 80, a podczas naciśnięcia przycisku jej wartość jest zwiększana aż do 100 po czym następuje reakcja na naciśnięcie, gdy Licznik_sw nie urośnie do 100 zanim puścimy przycisk to zostanie ustawiony znów na 80. Różnica między tymi wartościami pomnożona przez czas odstępu między wywołaniami procedury daje czas reakcji na naciśnięcie przycisku (w tym przypadku: (100-80)*4ms = 80ms). Gdy natomiast licznik urośnie do 100 to jego wartość zostanie wyzerowana i wykona się obsługa klawiatury. Dalsze trzymanie klawisza będzie teraz zwiększało licznik od 0 a zatem podczas trzymania klawisza reakcja nastąpi co 100*4ms=400ms. W efekcie po pierwszym wciśnięciu przycisk zareaguje po 80ms a gdy trzymamy ciągle to co każde 400ms. Kiedy potrzebujemy większej liczby klawiszy to przeważnie wybór pada na klawiaturę matrycową, podobną do tej na rysunku poniżej(cztery młodsze bity są wejściami, a cztery starsze wyjściami i należy je podłączyć poprzez rezystory np. 1k): Przy takim ustawieniu jak nie trudno zauważyć nie da się odczytać od razu całej klawiatury. Najprościej jest przeskanować całą klawiaturę a wynik zapisać do 16-bitowej zmiennej typu Word. Mając już stan klawiszy można skorzystać z procedury działającej analogicznie jak wyżej. Skanowanie klawiatury może się odbywać za pomocą procedury: Matrycowka: Klawisze = 0 For Wiersz = 4 To 7 Portd = Portd Or &B11111111 Portd.Wiersz = 0 Shift Klawisze , Left , 4 Stan_Wiersz = Pind And &B00001111 Klawisze = Klawisze + Stan_Wiersz Next Wiersz Return Procedura ta odczytuje wszystkie przyciski i zapisuje ich stan do 16-bitowej zmiennej Klawisze, jej bity począwszy od najstarszego odpowiadają klawiszom w kolejności: S4, S3, S2, S1, S8, S7, S6, S5, S12, S11, S10, S9, S16, S15, S14, S13. Odczyt przebiega następująco: Za pomocą pętli For zmienna pomocniacza Wiersz zmienia swoje wartości od 4 do 7 co odpowiada ustawieniu stanu niskiego po kolei na pinach PD.4 do PD.7. Jednocześnie podczas gdy kolejne piny przyjmują stan niski z pozostałych 4 młodszych pinów portu odczytywany jest stan 4 przycisków i wpisywany do zmiennej Klawisze, potem bity są przesuwane w lewo o 4 pozycje (Shift Klawisze , Left , 4) aby kolejne 4 przyciski zapisały się na wolnych miejscach w zmiennej Klawisze. Mówiąc w skrócie odczyt klawiatury jest dynamiczny, ustawiamy niski stan logiczny na jednym wierszu, po czym odczytujemy na które młodsze bity portu D stan ten się przeniósł. Potem ustawiamy 0 w drugim wierszu i znowu odczytujemy młodsze bity. Bezpośrednio po odczycie klawiatury musimy jeszcze zinterpretować stan klawiatury, wykonujemy to za pomocą procedury analogicznej jak przy zwykłej klawiaturze: Przyciski: If Klawisze <> &B1111111111111111 And Stan_sw = Klawisze Then Incr Licznik_sw If Licznik_sw = 56 Then Licznik_sw = 0 Select Case Stan_sw Case &B1111111111111110: 'tutaj akcja klawisza S13 Case &B1111111111111101: 'tutaj akcja klawisza S14 Case &B1111111111111011: Case &B1111111111110111: Case &B1111111111101111: Case &B1111111111011111: Case &B1111111110111111: Case &B1111111101111111: Case &B1111111011111111: Case &B1111110111111111: Case &B1111101111111111: Case &B1111011111111111: Case &B1110111111111111: Case &B1101111111111111: Case &B1011111111111111: Case &B0111111111111111: End Select End If Else Stan_sw = Klawisze Licznik_sw = 50 End If Return Ponieważ działanie jest takie samo jak w przypadku zwykłej klawiatury, nie będę omawiał szczegółowy wszystkich punktów procedury. Wartości zmiennej Klawisze są 16-bitowe podobnie jak Stan_sw. Działanie liczników jest analogiczne jak wyżej. Ponieważ procedura ta jest bardziej skomplikowana lepiej nie wykonywać jej co 4ms a np co 20ms. Z tak ustawionymi licznikami dało by to czas reakcji 120ms dla pierwszego kliknięcia i 1120ms dla ciągłego trzymania. Wywoływanie procedur klawiatury matrycowej powinno wyglądać tak: Gosub Matrycowka Gosub Przyciski
|
|||
Atmega8 + matrycówka 4x4 na dwóch portach
Witam, przymierzam się do budowy sterownika piły (długo by tu pisać) i planuję do tego wykorzystać klawiaturę matrycową. W projekcie chcę również użyć gotowego modułu wyświetlacza z układem TM1637 który jest sterowany tylko dwoma liniami mikroprocesora. Na przyszłość wolałbym sobie zostawić piny TxD oraz RxD nie używane, dlatego też podłączenie klawiatury matrycowej muszę rozdzielić na dwa porty - osobno kolumny i wiersze. Wydaje mi się że najlepszym rozwiązaniem w układzie ATmega8 będzie podłączenie jednego pod linie PD4-PD7, a drugiego pod linie PC0-PC3.
Czy ktoś już testował podobną konfigurację? Jak powinienem wtedy skonfigurować porty? Czy nie będzie z tym problemu? Testowałem już tę klawiaturę na jednym porcie - jak w przykładnie ale nigdy nie na dwóch, tak jak teraz to planuję zrobić.
Wolałbym wcześniej zapytać (zanim zaprojektuję PCB) czy ktoś już z tym miał problemy, bo jeśli tak to najwyżej zrobię klawiaturę na całym porcie D, a jak będę potrzebował port szeregowy to rozwiążę go programowo...
Trzeba tylko zmienić
Trzeba tylko zmienić procedure skanujaca klawiaturę....
pinc0-3 ma być wejściami z pullupem
pind4-7 to wyjścia
UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.
nie jestem teraz pewny, ale
nie jestem teraz pewny, ale jeśli się nie mylę to "Or" ustawia jedynki tylko tam gdzie w zapisie jest 1, a tam gdzie jest 0 - pozostawia stan taki jaki jest faktycznie na pinie? Analogicznie "And" ustawia 0 tam gdzie jest w zapisie 0, a tam gdzie jest 1 pozostawia stan taki jaki jest faktycznie?
Pytam gdyż zdążyłem już zapomnieć o podstawach tj maskowaniu, ale chyba tak to właśnie było?
Re: klawiatura
Dokładnie tak
UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.