[AVR] Klawiatura matrycowa
Masz problem? Zapytaj na forum elektroda.pl
From: Mateusz Majchrzycki <spam_at_nospam_spam.spam>
Subject: [AVR] Klawiatura matrycowa
Date: Mon, 31 Jan 2005 11:44:21 +0000 (UTC)
Walcze właśnie z obsługą klawiatury matrycowej 8x8 z możliwością
wciśnięcia jednego lub dwóch klawiszy na raz. Klawiatura podpięta jest
bezpośrednio do portów uC ATmega128.
Wszystkie wiersze klawiatury to wejścia nie podciągnięte (stan Z).
Zawsze tylko jeden z wierszy jest wyjsciem w stanie L, i to ten wiersz
skanujemy czy wciśnięto w nim jakiś klawisz. Później skanowany wiersz
wprowadzamy w stan Z, i przechodzimy do kolejnego.
Poniżej jest procedura odczytująca stan kalwiatury:
main:
ldi XL,LOW(klawisze) ;klawisze to adres w pamieci RAM, gdzie
przechowywane będą kody klawiszy
ldi XH,HIGH(klawisze)
ldi ddreg,0x01
ldi maska,0x01
clr licznik ;licznik to r20
petla1:
out key_out,ddreg ;key_out to inaczej ddra
nop
nop
petla2:
in ior,key_in ;wczytujemy key_in, czyli pinf
and ior,maska ;ior, to r16
cp ior,maska
;idea trzech powyzszych instrukcji jest taka. Sprawdzamy czy wcisnieto
np. (dla wiersza np. 1) klawisz w kolumnie 1. W tym celu maska=0x01.
Gdy wciśnięto ten klawisz, to wczytana wartość z key_in bedzie
11111110, a maska 00000001. Po wykonaniu and otrzymamy 0, czyli
skanowany klawisz jest wciśnięty. Gdyby maska była np. 01000000, to
otrzymalibyśmy 01000000 (czyli maskę) i to by znaczyło że dany klawisz
nie jest wciśnięty.
breq no_key ;jeśli maska jest równa (key_in and maska) to znaczy ze nie
wciśnięto pożądanego klawisza
st X+,cnt ;a jeśli wciśnięto to zapisujemy kod klawisza (klawisze mają
kody-od górnego lewego rogu klawiatury 0,1,2,3 itd.
sbr rflag,(1<<fKEY) ;ustawiamy flagę że naciśnięto jakis klawisz
clr ior ;czyścimy rejestr roboczy
no_key:
inc cnt ;zwiększamy licznik (czyli numer kodu klawisza)
lsl maska ;przesuwamy maskę (na kolejny klawisz w kolumnie)
cpi maska,0x00
breq nastepny_rzad ;jesli maska jest zero to znaczy ze koniec tej linii
jmp petla2 ;jesli nie to dalej z ta linia
nastepny_rzad: ;przejscie do nastepnej linii
ldi maska,0x01 ;maske na bit 0
lsl ddreg ;przesuwamy ddreg
cpi ddreg,0 ;jesli ddreg=0 to znaczy ze to byla ostatnia kolumna
breq testuj ;i do testow kalwiszy (czyli interpretacja tego co
odczytalismy)
jmp petla1 ;a jesli nie to do skanu kolejnego wiersza
No i wszystko ładnie, pięknie. W symulatorze AVRStudio działa
doskoanle. Jednakże już po zaprogramowaniu procka, okazuje sie że dla
dwóch wciśniętych klawiszy, pierwsza komórka zawiera kod pierwszego
klawisza, druga ZAWSZE ZAWIERA 8 (!!!), a dopiero w trzeciej jest kod
drugiego klawisza :/ Nie wiem gdzie popełniam błąd, czy to jakaś
specyfika ATmegi, czy wykonania jakiejś instrukcji? Już trzeci dzień to
męczę i nic :(
Jeżeli ktoś jest w stanie mi pomóc będę niezmiernie wdzięczny :)
--
+-----Pozdrawiam------+------------------------+
\ Mateusz Majchrzycki \ W życiu liczą się \
\ MateoM[at]poczta.fm \ drobne przyjemności... \
+------GG#897890------+------------------------+