Ćwiczenie nr 4 Cel ćwiczenia: Celem ćwiczenia jest zapoznanie z obsługą klawiatury sekwencyjnej i matrycowej w systemie DSM-51. Wiadomości wstępne: Klawiatura sekwencyjna zawiera tylko sześć klawiszy. Wyświetlacze i klawiatura sekwencyjna korzystają z tego samego RESESTRU WYBORU. O ile rejestr ten w przypadku wyświetlacza wskazuje wyświetlacze, które będą wyświetlać zawartość bufora danych, to w przypadku klawiatury wyznacza nam numer klawisza, którego stan możemy odczytać z linii (P3.5) Jeśli P3.5 jest równy 1 to klawisz jest wciśnięty, jeśli jest równy 0 to klawisz jest zwolniony. Rys 1. Sposób podłączenie klawiatury sekwencyjnej i matrycowej w systemie DSM-51. PRZYKŁAD_1 KEY_COD EQU 00001001B ;wybrane klawisze - 1i4 MOV R0,#30H ;adres wyboru klawisza MOV A,#KEY_COD MOVX @R0,A ;wpisz wybrane klawisze LOOP: MOV C,KEY ;czytaj stan klawiszy CPL C ;neguj MOV LED,C ;zapal diodę TEST gdy klawisz jest naciśnięty SJMP LOOP 1
PRZYKŁAD_2 KEY_COD EQU 00001001B ;wybrane klawisze - 1i4 MOV R0,#30 ;adres wyboru klawisza MOV A,#KEY_COD MOVX @R0,A ;wpisz wybrane klawisze JNB KEY,LOOP_NO ;czekaj na naciśnięcie klawisza CPL LED ;neguj stan diody TEST przy naciśnięciu klaw. JB KEY,LOOP_YES ;czekaj na zwolnienie klawisza PRZYKŁAD_3 SJMP LOOP_NO ;powrót do pętli czekania na klawisz KEY_COD EQU 00001001B ;wybrane klawisze-1 i 4 MOV R0,#30H ;adres wyboru klawisza MOV A,#KEY_COD MOVX @R0,A ;wpisz wybrane klawisze JNB KEY,LOOP_NO ;czekaj na naciśnięcie klawisza MOV A,#10 ;eliminacja drgań styków JNB KEY,LOOP_NO ;czy nadal naciśnięty CPL LED ;neguj stan diody TEST przy naciśnięciu klaw. JB KEY,LOOP_YES ;czekaj na zwolnienie klawisza MOV A,#10 ;eliminacja drgań styków JB KEY,LOOP_YES ;czy klawisz zwolniony SJMP LOOP_NO ;powrót do pętli czekania na klawisz PRZYKŁAD_4 SEG_ON EQU P1.6 ;włączenie wyświetlacza 7-segm. ;Pamięć wewnętrzna RAM DISPLAY EQU 30H KEY_LAST EQU DISPLAY+6 2
CLR A MOV DISPLAY,A ;wpisz 0 do pamięci MOV DISPLAY+1,A ;danych wszystkich MOV DISPLAY+2,A ;wskaźników MOV DISPLAY+3,A MOV DISPLAY+4,A MOV DISPLAY+5,A MOV DISPLAY+6,A LOOP_DISP: ;ustaw dane do wyśw. ;na wskaźniku 1 MOV R0,#DISPLAY ;adres pobierania kodów MOV R2,#7 ;licznik - liczba wskaź. MOV R3,#00000001B ;wybór wskaźnika - kod 1 z 8 LOOP: SEG: LEDS: SETB SEG_ON ;włącz poprzedni wskaźnik MOV R1,#30H ;adres wyboru wskaźnika MOV A,R3 ;nr wskaźnika (1z8) MOVX @R1,A ;wpisz wybrany wskaźnik MOV R1,#38H ;adres danych wskaźnika MOV A,@R0 ;dane wskaźnika CJNE R3,#01000000B,SEG ;czy 7 wskaźnik SJMP LEDS ;tak-diody świecące ;nie ma zamiany na kod LCALL GET_COD7 ;zamiana cyfry na kod MOVX @R1,A ;wpisanie kodu zapalanych ;segmentów do buforu ;danych wskaźnika CLR SEG_ON ;włączenie wskaźnika MOV C,KEY ;wstępny odczyt klawisza MOV A,#1 ;odczekanie 1ms-świecenie ;jednego wskaźnika JC KEY_ON ;kontrola jednoznacznoci JB KEY,KEY_END ;odczytu klawisza KEY_OFF: MOV A,R3 ;klawisz zwolniony ANL KEY_LAST,A ;zeruj odpowiedni bit SJMP KEY_END KEY_ON: JNB KEY,KEY_END MOV A,R3 ;klawisz naciśnięty ANL A,KEY_LAST JNZ KEY_END ;klawisz był naciśniety bez reakcji MOV A,R3 ;klawisz był zwolniony ORL KEY_LAST,A ;ustaw odpowiedni bit INC @R0 ;zwiększ licznik ;naciśnięć - liczbę na ;odpowiednim wskaźniku KEY_END: MOV A,R3 RL A ;numeru następnego MOV R3,A ;wskaźnika (kod 1 z 8) INC R0 ;adres danych następnego ;wskaźnika DJNZ R2,LOOP ;kolejne świecenie 3
;siedmiu wskaźników SJMP LOOP_DISP ;zacznij od wskaźnika 1 ;************************************** ;Podprogram zamienia cyfrę na kod 7-segmentowy GET_COD7: ANL A,#0FH ;tabela kodów 0..15 INC A MOVC A,@A+PC ;pobierz kod RET COD_7SEG: DB 03FH ;kod znaku 0 DB 006H ;kod znaku 1 DB 05BH ;kod znaku 2 DB 04FH ;kod znaku 3 DB 066H ;kod znaku 4 DB 06DH ;kod znaku 5 DB 07DH ;kod znaku 6 DB 007H ;kod znaku 7 DB 07FH ;kod znaku 8 DB 06FH ;kod znaku 9 DB 077H ;kod znaku A DB 07CH ;kod znaku b DB 039H ;kod znaku C DB 05EH ;kod znaku d DB 079H ;kod znaku E DB 071H ;kod znaku F Zadanie_1 Zlicz ile razy naciśnieto klawisz Enter z klawiatury sekwencyjnej, co piąte wciśniecie zapalaj diodę na 1s. Zadanie_2 Niech wciśniecie Enter'a z klawiatury sekwencyjnej włącza diodę, natomiast naciśniecie Esc gasi ją. Zadanie_3 Klawiszami kursora wybieramy aktywny wyświetlacz (w lewo lub prawo). Strzałkami w górę/dół wybieramy liczbę jaka ma się na nim wyświetlić (0-F). Klawiatura matrycowa złożona z 16 przycisków. Są one zorganizowane w 2 rzędy po 8 klawiszy. Pierwszy rząd zawiera klawisze o numerach 0-7, drugi: 8-15. Klawisze nr 0 i nr 8 tworzą parę. Takie same pary klawiszy to: (1,9),... (7,Ent). Każda para klawiszy jest połączona jedna linia z odpowiednia linia wpisu równoległego do BUFORA KLAWIATURY MATRYCOWEJ. Wciśnięty przełącznik zwiera jedną z linii adresowych (A1 lub A0) z linia wpisu równoległego do BUFORA. Stan linii adresowej jest zapisywany w BUFORZE. Odczytanie bufora klawiatury to nic innego jak odczyt komórek z pamięci XRAM o adresach 21H lub 22H.(wiersz I lub wiersz II). Tylko na jednej z linii A0 i A1 może być poziom "0". Tylko wciśniecie klawisza zwierającego linie wyzerowana może wprowadzić "0" do BUFORA. Odczytując stan bufora szukamy w nim "0" na dowolnej pozycji. PRZYKŁAD_1 SEG_ON EQU P1.6 ;włączenie wyśw. 7-segmentowego DISPLAY EQU 01010101B ;wskaźniki - 1,3,5,7 MOV R1,#30H ;adres wyboru wskaźnika MOV A,#DISPLAY MOVX @R1,A ;wpisz wybrane wskaźniki MOV R1,#38 ;adres danych wskaźnika 4
CLR SEG_ON ;włącz wyświetlacz 7-segm LOOP: ;przepisuj stan klawiszy ;na wyświetlacz 7-segm. MOVX A,@R0 ;odczytanie klawiszy ;bit=0 - klaw. naciśnięty ;zmiana 0<->1 MOVX @R1,A ;zapalenie segmentów odpowiadających naciśniętym klawiszom SJMP LOOP PRZYKŁAD_2 LCALL LCD_CLR JZ LOOP_NO ;czy klawisz naciśnięty MOV R2,#0FFH LOOP_NR: ;przekoduj nr klawisza ;kod 1z8 na cyfr 0..7 ;pętla będzie wykonana 1-8 razy INC R2 ;więc R2 osiągnie wartość 0..7 RRC A ;obrót akumulatora przez C ;aż odczytana 1 wsunie się do C JNC LOOP_NR MOV A,R2 ;przekoduj nr klawisza ADD A,#30H ;na kody znaków wyśw. LCD LCALL WRITE_DATA ;wypisz kod klawisza JNZ LOOP_YES ;czy klawisz zwolniony SJMP LOOP_NO ;powrót do oczekiwania na ;naciśnięcie klawisza PRZYKŁAD_3 ;Odczyt klawiatury LCALL LCD_CLR MOV DPTR,#KEY_CODE ;adres tablicy kodów JNZ KEY_YES ;czy klawisz naciśnięty INC R0 ;adres klawiszy 8.. MOVX A,@R0 JZ LOOP_NO ;czy klawisz naciśnięty KEY_YES: ;eliminacja drgań styków MOV R2,A ;zapamiętaj stan klawiszy MOV A,#10 5
XRL A,R2 ;porównaj z zapamiętanym JNZ LOOP_NO ;czy stan stabilny - ;klawisz nadal naciśnięty MOV A,R2 ;stan klawiszy do A ;ustaw wstępną wartość R2 zależnie od zestawu klawiszy MOV R2,#07H ;klawisze 8.. CJNE R0,#21H,LOOP_NR MOV R2,#0FFH ;klawisze 0..7 LOOP_NR: ;przekodowanie klawisza INC R2 ;kod 1z8 na numer 0..15 RRC A JNC LOOP_NR MOV A,R2 ;przekodowanie klawisza MOVC A,@A+DPTR ;na kody znaków wyśw. LCD ;za pomocą tablicy kodów LCALL WRITE_DATA ;wypisz kod klawisza JNZ LOOP_YES ;czy klawisz zwolniony INC R0 ;adres klawiszy 8.. JNZ LOOP_YES ;czy klawisz zwolniony SJMP LOOP_NO ;powrót do oczekiwania ;na naciśnięcie klawisza ;************************************** ;Tablica kodów znaków LCD dla klawiszy KEY_CODE: DB 30H,31H,32H ;0,1,2 DB 33H,34H,35H ;3,4,5 DB 36H,37H,38H ;6,7,8 DB 39H,3CH,3EH ;9,<,> DB 5EH,76H,7FH ;^,v,esc DB 0AEH ;Enter Zadanie_1 Czekaj na naciśniecie klawisza "0". Gdy to nastąpi zapal diodę. Gaszenie diody odbywa się poprzez wciśniecie klawisza "Esc". Zadanie_2 Zliczaj ile razy naciśnieto klawisz "1" podczas działania programu. Wynik wyświetlaj na wyświetlaczu 7-segmentowym. 6