Oprogramowanie klawiatury matrycowej i alfanumerycznego wyświetlacza LCD 1. Wprowadzenie DuŜa grupa sterowników mikroprocesorowych wymaga obsługi przycisków, które umoŝliwiają uŝytkownikowi uruchamianie funkcji urządzenia, ustawianie parametrów, konfigurację pracy itd. Dla małej liczby przycisków moŝemy kaŝdy z nich podłączyć do oddzielnego wejścia mikrokontrolera. Stosując dodatkowe zewnętrzne lub wewnętrzne rezystory, przycisk wymusza zmianę stanu na wejściu, którą odczytujemy w programie obsługi. Dla większej ilości przycisków, aby zmniejszyć liczbę wykorzystywanych linii wejść/wyjść, stosuje się inne rozwiązanie w postaci klawiatury matrycowej, w której przyciski połączone są pomiędzy biegnącymi pionowo i poziomo przewodami umownie nazywanymi wierszami i kolumnami. Przykładem takiego rozwiązania moŝe być wykorzystywany na pracowni mikroprocesorów zestaw uruchomieniowy ZL10AVR, który zawiera 16-przyciskową klawiaturę w układzie matrycowym. Rys.1 przedstawia widok przycisków klawiatury oraz schemat ich połączeń. Rys.1 Widok przycisków i schemat klawiatury matrycowej w zestawie ZL10AVR 1
Zgodnie z Rys.1, aby klawiatura pracowała w trybie matrycowym, zworka JP26 powinna być w pozycji 4x4. Sygnały odpowiadające wierszom i kolumnom wyprowadzone są na złącze Z15 i mogą być, poprzez odpowiednie przewody, dołączone bezpośrednio do wybranego portu mikrokontrolera. Odczyt stanu klawiatury matrycowej jest bardziej skomplikowany niŝ w przypadku podłączenia kaŝdego przycisku do innego wejścia mikrokontrolera. Generalnie występują dwie metody skanowania klawiatury. Metoda 1: W metodzie tej przyjmujemy następujące załoŝenia: piny portu mikrokontrolera, do których połączone są wiersze klawiatury, są skonfigurowane jako wejścia, do pinów wejściowych podłączone są zewnętrzne lub wewnętrzne rezystory podciągające do napięcia zasilania, aby w przypadku braku wciśniętych przycisków odczytywać stan logiczny wysoki, piny portu mikrokontrolera, do których dołączone są kolumny klawiatury, są skonfigurowane jako wyjścia. Algorytm skanowania klawiatury polega na cyklicznym ustawianiu stanu niskiego dla kolejnych kolumn i odczycie stanu wierszy (wejść). JeŜeli dla danego wiersza odczytamy stan zera logicznego oznacza to, Ŝe przycisk umieszczony na przecięciu danego wiersza i kolumny, dla której ustawiony był stan niski, jest aktywny (zwarty). Metoda 2: W metodzie tej przyjmujemy następujące załoŝenia: piny portu mikrokontrolera, do których połączone są wiersze i kolumny klawiatury, mogą pracować na przemian jako wejścia lub wyjścia, do pinów wierszy i kolumn podłączone są zewnętrzne lub wewnętrzne rezystory podciągające do napięcia zasilania, aby w przypadku braku wciśniętych przycisków odczytywać stan logiczny wysoki. Algorytm odczytu stanu klawiatury składa się z dwóch faz. W pierwszej fazie kolumny ustawiane są jako wyjścia w stanie niskim i odczytywany jest stan wierszy. W drugiej fazie wiersze ustawiane są jako wyjścia w stanie niskim i odczytywany jest stan kolumn. Dla naszego przypadku klawiatury 4x4 oba odczyty traktujemy jako starszą i młodszą część bajtu, który stanowi tzw. kod skanowania. 2
2. Implementacja algorytmów: Uwagi : PoniewaŜ wewnętrzne rezystory podciągające dla procesora Atmega16 posiadają stosunkowo duŝą rezystancję (ok. 50 kω), wymagane jest dodatkowe opóźnienie pomiędzy ustawieniem nowego stanu kolumny a odczytem wierszy, aby osiągnąć 'pewny' stan przy przełączeniu ze stanu niskiego (0) do stanu wysokiego (1), Przedstawiony we wprowadzeniu algorytm dla pierwszej metody zakładał, Ŝe w dowolnej chwili tylko jeden przycisk jest aktywny (zwarty). W praktyce moŝe się zdarzyć jednoczesne naciśnięcie dwóch przycisków. JeŜeli przyciski będą w tym samym wierszu, moŝe nastąpić zwarcie pomiędzy pinami wyjść mikrokontrolera, które będą w przeciwnych stanach. Dla mikrokontrolerów z wyjściami typu OC sytuacja ta nie jest niebezpieczna. W przypadku procesora Atmega16 stan ten jest niepoŝądany. Dlatego algorytm naleŝy zmodyfikować tak, aby podczas skanowania zmieniać dodatkowo konfigurację kierunków portów w ten sposób, aby jako wyjście był ustawiony tylko ten pin, na którym wymuszamy stan zera. Konfiguracja zestawu uruchomieniowego ZL10AVR: mikrokontroler ATmega16 zworka JP21 w pozycji U2/3/5/6, konfiguracja klawiatury zworką JP26 w pozycji 4x4, wiersze klawiatury R0 R3 (Z15) połączone za pomocą przewodów do pinów PC0 PC3, kolumny klawiatury C0 C3 (Z15) połączone za pomocą przewodów do pinów PC4 PC7, diody 'LEDs' wykorzystane do testowania funkcji skanujących klawiaturę połączone do portu PB procesora - zworka JP22 w pozycji PB. Przedstawione dalej wydruki przedstawiają przykładowe kody funkcji skanujących metodą 1 i 2, które zwracają numer naciśniętego przycisku klawiatury. Wyświetlanie wyniku skanowania w postaci binarnej realizowane jest w funkcji main(), wynik skanowania podawany jest na port PB, do którego połączone są diody LED. 3
//definicja rejestrów portu do którego podlaczona jest klawiatura #define KB_PORT PORTC #define KB_DIR DDRC #define KB_PIN PINC //Funkcja skanujaca klawiaturę - wersja 1, zwraca //numer nacisnietego przycisku lub zero gdy brak detekcji znaku char KbScan(void) { char result=0; KB_DIR =0b00010000; KB_PORT=0b11101111; KB_DIR =0b00100000; KB_PORT=0b11011111; KB_DIR =0b01000000; KB_PORT=0b10111111; KB_DIR =0b10000000; KB_PORT=0b01111111; KB_PORT=0xFF; return result; //tylko kolumna C0 na wyjscie result=12; result=11; result=4; result=3; //tylko kolumna C1 na wyjscie result=14; result=13; result=6; result=5; //tylko kolumna C2 na wyjscie result=16; result=15; result=8; result=7; //tylko kolumna C3 na wyjscie result=18; result=17; result=10; result=9; Wydruk 1. Funkcja skanująca klawiaturę matrycową 4x4 według metody 1 4
//definicja rejestrów portu do którego podlaczona jest klawiatura #define KB_PORT PORTC #define KB_DIR DDRC #define KB_PIN PINC //Funkcja skanujaca klawiaturę - wersja 2 //Zwraca numeru nacisnietego przycisku lub zero gdy brak detekcji char KbScan(void) { unsigned char result=0; KB_DIR =0b11110000; //wymuszenie zer dla wszystkich kolumn KB_PORT=0b00001111; result= KB_PIN; //odczyt wierszy KB_DIR =0b00001111; //wymuszenie zer dla wszystkich wierszy KB_PORT=0b11110000; result = result KB_PIN; //uzyskanie kodu skanowania switch( result) { case 0b11101110 : return 12; case 0b11011110 : return 14; case 0b10111110 : return 16; case 0b01111110 : return 18; case 0b11101101 : return 11; case 0b11011101 : return 13; case 0b10111101 : return 15; case 0b01111101 : return 17; case 0b11101011 : return 4; case 0b11011011 : return 6; case 0b10111011 : return 8; case 0b01111011 : return 10; case 0b11100111 : return 3; case 0b11010111 : return 5; case 0b10110111 : return 7; case 0b01110111 : return 9; default: case 0b11111111 : return 0; Wydruk 2. Funkcja skanująca klawiaturę matrycową 4x4 według metody 2 5
#include <avr/io.h> #define F_CPU 8000000UL #include <util/delay.h> char KbScan(void); //deklaracja funkcji skanującej //... int main(void) { //konfiguracja pomocniczego portu do wyświetlania wyniku skanowania DDRB=0xFF; //port testowy -wyniku skanowania for (;;) PORTB =KbScan(); return 0; Wydruk 3. Funkcja main() - testowanie funkcji skanujących klawiaturę matrycową W praktyce, w zaleŝności od wymagań aplikacji, obsługa klawiatury matrycowej powinna uwzględniać dodatkowe czynniki, takie jak: częstotliwość przeglądania przycisków, drgania styków, czas naciśnięcia i ewentualnego powtarzania znaku, wykorzystanie przerwań od układu czasowego mikrokontrolera do realizacji poszczególnych etapów skanowania, buforowanie kodów przycisków. 6
3. Przykłady zadań do zrealizowania: 1. Napisać procedurę, która korzystając z przedstawionej funkcji skanowania, będzie wykrywała zmianę stanu klawiatury, zwracając np. numer przycisku jednokrotnie po jego naciśnięciu. 2. Realizacja odczytu klawiatury matrycowej pod przerwaniami od układu czasowego. Wykrywanie naciśnięcia-zwolnienia przycisku z uwzględnieniem drgań styku. 3. Napisać procedurę kodującą numery przycisków na kody ASCII, zgodnie z załoŝoną interpretacją przycisków, np. klawiatura telefoniczna, klawiatura numeryczna itp. 4. Napisać program sterowania zamkiem elektromagnetycznym, otwierającym drzwi po wprowadzeniu wybranego kodu dostępu do pomieszczenia. 4. Pytania 1. Jaka jest minimalna liczba przycisków klawiatury matrycowej, przy której liczba wymaganych portów do jej obsługi będzie mniejsza niŝ w przypadku ich oddzielnego podłączenia do mikrokontrolera? 2. Czy w mikrokontrolerze Atmega16 jest moŝliwy odczyt stanu 2 (lub więcej) przycisków z wykorzystaniem jednego pinu portu mikrokontrolera? 3. Jak zmodyfikować schemat podłączenia klawiatury (wykorzystując diody przełączające), aby wyeliminować konieczność zmiany kierunków portu? 4. Porównaj wady i zalety przedstawionych funkcji skanujących. 5. Literatura 1. Jerzy Szczesiul, AVR-GCC: kompilator C dla mikrokontrolerów AVR, Elektronika Praktyczna, Kurs od 3 /2005 do 4/2006 2. Andrzej Witkowski, Mikrokontrolery AVR programowanie w języku C przykłady zastosowań, Gliwice 2006 3. www.atmel.com/dyn/resources/prod_documents/8154s.pdf dokumentacja atmega16 4. www.nongnu.org/avr-libc/user-manual/ podręcznik uŝytkownika biblioteki avr-libc 5. www.kamami.com/dl/zl10avr_en.pdf dokumentacja techniczna: ZL10AVR- uniwersalny zestaw uruchomieniowy dla mikrokontrolerów AVR 7