Podlaczenie klawiatury PC do AT Nieznany

background image

http://www.easy-soft.tsnet.pl/

Podłączenie klawiatury PC do

mikrokontrolera

AT89S8252.

Do jednego z projektowanych urządzeń potrzebowałem klawiatury afanumerycznej. Mój wybór

padł na zwykłą klawiaturę do komputera PC z dwóch prostych powodów: dostępność i cena. Do

pełni zadowolenia wystarczyło dołączyć klawiaturę do mojego urządzenia i po prostu używać. I

to pojawił się pewien kłopot...

Chciałem skorzystać z jakiejś gotowej aplikacji, jednak 2 kompletne które udało mi się znaleźć

były zupełnie bezużyteczne. Obie ze względu na użyty język programowania: Bascom i

mikrokontroler 8051 to nie najlepszy moim zdaniem pomysł a i o zmianie mikrokontrolera na

PIC nie mogło być mowy. Postanowiłem, wzorując się na obu rozwiązaniach, napisać program

w języku C, dla mikrokontrolera AT89S8252. Powstał w ten sposób driver opisywany w

niniejszym artykule.

Po skompilowaniu program zajmuje około 1,5kB pamięci ROM. Część procedur jest napisana w

języku asemblera, część w języku C. Oczywiście można wszystko napisać w C, jednak wiąże

się to z pewnymi (być może) utrudnieniami. Na przykład rozkazy przesunięć w języku C są

wykonywane w sposób zależny od typu użytej zmiennej. Odczyt danych z pinu procesora nie

był by więc tak prosty i szybki, jak w asemblerze. Oczywiście można całość napisać w C, ale

skoro w asemblerze można to zrobić wszystko nieco łatwiej a moduły w asemblerze można bez

problemu łączyć z językiem C, to dlaczego nie skorzystać z tej możliwości?

W języku C jest „załatwiane” są przede wszystkim operacje, których implementacja zajmuje

mnóstwo czasu w asemblerze, czyli porównanie i rozpoznanie kodów, konwersja na ASCII i

tym podobne. W C wykonałem również driver do obsługi wyświetlacza LCD 4 linie x 20 znaków

w trybie 4 bity.

Większość materiałów, które posłużyły do napisania programu, pochodzi ze strony Adama

Chapweske. Strona dostępna jest pod adresem:

http://govschl.ndsu.nodak.edu/~achapwes/

.

Interfejs elektryczny. Protokół komunikacyjny.

Napięcie zasilające zapewniane jest przez urządzenie, do którego dołączona jest klawiatura.

Większość klawiatur nie pobiera więcej, niż 100 mA prądu przy napięciu zasilającym 5V.

Ogólna tendencja zmierza w kierunku obniżania poboru prądu przez klawiaturę.

Klawiatura posiada dwie dwukierunkowe linie służące do transmisji danych. Obie linie

interfejsu są typu otwarty kolektor lub otwarty dren. W związku z tym, patrząc od strony

urządzenia, do którego dołączona jest klawiatura, linia jest albo zwierana przez wyjściowy

tranzystor do masy, albo przechodzi w stan wysokiej impedancji. W związku z tym, dla

zachowania poprawności stanów logicznych, konieczne jest użycie po stronie urządzenia

rezystorów zasilających (tzw. pull-up) o wartości od 1 do 10kΩ.

Dane przesyłane są dwukierunkowo, do i z klawiatury, w rytm zmian sygnału zegarowego CLK.

Przed każdym opadającym zboczem sygnału zegarowego ustalony musi być stan linii danych.

Linia zegara służy również do swego rodzaju arbitrażu. Klawiatura (identyczny rodzaj

interfejsu posiada myszka!) po ustawieniu stanu wysokiego sprawdza, czy stan linii zegara nie

zmienia się na niski przez czas 50 mikrosekund. Jesli nie, to przesyłane są dane. Jeśli tak,

- strona 1/14 -

background image

http://www.easy-soft.tsnet.pl/

kontroler klawiatury oczekuje na zakończenie transmisji. W związku z tym host może w

dowolnym momencie zablokować lub wstrzymać transmisję utrzymując stan niski linii zegara

przez czas co najmniej 100 mikrosekund.

Częstotliwość sygnału zegarowego waha się w granicach od 10 do 16,7kHz. Czas pomiędzy

ustaleniem się danych a opadającym zboczem sygnału zegarowego powinien być nie mniejszy,

niż 5 mikrosekund.

Na rysunku 1 przedstawiono wygląd ramki transmisji. Jako pierwszy przesyłany jest bit startu,

który zawsze jest równy 0. Za nim następuje 8 bitów danych oraz 1 bit parzystości (ustawiony,

gdy liczba 1 w słowie jest parzysta, parzystość typu odd), 1 bit stopu (zawsze równy 1) i bit

potwierdzenia odbioru.

Rysunek 1. Ramka transmisji danych przesyłanych z klawiatury

Sygnał zegarowy zawsze generowany jest przez klawiaturę. Nie stwarza to żadnego problemu,

jeśli to klawiatura przesyła dane. Jednak na początku tego tekstu wspomniałem, że obie linie

są dwukierunkowe, przez co można wysnuć wniosek, że również klawiatura może odbierać

dane od urządzenia hosta. W jaki sposób?

Jeśli urządzenie host chce przesłać dane, to wysyła specjalną sekwencję nazwaną Request to

Send. Wygląda ona następująco:

host utrzymuje stan niski linii zegarowej przez czas co najmniej 100 mikrosekund,

wysyła polecenie Request to Send ustawiając stan niski linii danych i zmieniając stan linii
zegara na wysoki.

Po odebraniu żądania przesłania danych, klawiatura utrzymując stan wysoki linii danych,

generuje sygnał zegarowy. W tak zmian tego sygnału, ustawiając właściwy stan linii danych,

gdy linia zegarowa ma stan niski, host przesyła dane do klawiatury. Po odebraniu bitu stopu

kontroler klawiatury potwierdza fakt odbioru słowa danych ustawiając stan niski linii danych.

Rysunek 2. Ramka transmisji danych przesyłanych do klawiatury

- strona 2/14 -

background image

http://www.easy-soft.tsnet.pl/

Rysunek 3. Szczegóły transmisji danych z hosta do klawiatury (również myszki)

Skoro klawiatura odbiera dane, jakie rozkazy mogą być realizowane? Oczywiście oprócz

oczywistych, to jest zaświecania diod sygnalizacyjnych Num Lock, Caps Lock i Scroll Lock.

0xFF (Reset) – Klawiatura odpowiada kodem "ACK" (0xFA), a następnie realizuje polecenie
restartu ustawiając nastawy domyślne i zerując bufor.

0xFE (Resend) – Klawiatura odpowiada kodem ostatnio przesłanego znaku.

0xFD (Set Key Type Make*) - Wyłącza przesyłania kodów break.

0xFC (Set Key Type Make/Break*) - Zbliżona w działaniu do poprzedniej komendy, jednak
wyłączane jest automatyczne powtarzanie wciśniętego klawisza.

0xFB (Set Key Type Typematic*) - Wyłącza wyłącznie kod Break.

0xFA (Set All Keys Typematic/Make/Break*) – Klawiatura odpowiada za pomocą ACK
ustawiając domyślne wartości nastaw dla make, break i automatycznego powtarzania

klawisza.

0xF9 (Set All Keys Make*) - Klawiatura odpowiada wysyłając ACK. Działanie zbliżone do
0xFD z tym, że nastawa dotyczy wszystkich klawiszy.

0xF8 (Set All Keys Make/Break*) - Działanie zbliżone do 0xFC z uwagami j.w.

0xF7 (Set All Keys Typematic*) - Działanie zbliżone do 0xFB z uwagami j.w.

0xF6 (Set Default) – Przywrócenie nastaw domyślnych (10.9cps / 500ms, make/break),
zestaw scan code numer 2.

0xF5 (Disable) – Kontroler klawiatury przerywa przeglądanie klawiszy, ładuje nastawy
domyślne i oczekuje na następne polecenia.

0xF4 (Enable) – Przywraca normalne funkcjonowanie klawiatury po 0xF5.

0xF3 (Set Typematic Rate/Delay) – Nastawa czasu powtarzania i opóźnienia.

0xF2 (Read ID*) – Odczyt ID klawiatury; oryginalna klawiatura PS2 wysyła liczby 0xAB,
0x83.

0xF0 (Set Scan Code Set*) - Nastawa zestawu kodów skanowania.

0xEE (Echo) – Klawiatura odpowiada wysyłając 0xEE.

0xED (Set/Reset LEDs) – Zaświecenie, gaszenie diod LED. Można znaleźć w przykładowym
programie z tego artykułu.

Każdy klawisz generuje dwa kody. Jeden z nich nazywany jest kodem make i wysyłany jest

przez klawiaturę po wciśnięciu klawisza, poprzedzając właściwy numer klawisza. Drugi

nazywany jest break i wysyłany jest po zwolnieniu klawisza. Po nim ponownie wysyłany jest

- strona 3/14 -

background image

http://www.easy-soft.tsnet.pl/

numer klawisza. W tabeli 1, 2 i 3 zebrano kody wysyłane przez nowoczesne klawiatury

mutlimedialne. Starsze modele klawiatur różnią się tym, że nie przesyłają kodów

rozszerzonych – podstawowe zostają takie same.

Implementacja. Wykonanie układu.

Na rysunku 4 znajduje się układ połączeń konieczny do przetestowania aplikacji z tego

artykułu. Całość zmontowana była z użyciem płytki testowej (opisywanej na stronie),

wyświetlacza LCD 4x20 i dwóch rezystorów zasilających. Używałem klawiatury ze złączem PS2.

Rysunek 4. Schemat aplikacji z artykułu.

Zadaniem aplikacji jest wyświetlenie odebranych kodów i zamiana ich na znaki ASCII. Jest to

prosty przykład programowania, który można wykorzystać we własnej aplikacji w dowolny,

ograniczony praktycznie tylko inwencją, sposób. Program zawiera liczne komentarze tak, że

uzbrojony w podstawy wiedzy Czytelnik nie powinien mieć problemu z analizą.

Po skompilowaniu program zajmuje około 1,5kB w pamięci. W związku z tym bez trudu

pomieści go również malutki AT89C2051. Nie bez znaczenia jest również fakt, że do jego

kompilacji można użyć wersji demonstracyjnej pakietu Raisonance, której kompilator języka C

generuje kod do 4kB.

Jacek Bogusz

jacek.bogusz@easy-soft.tsnet.pl

- strona 4/14 -

background image

http://www.easy-soft.tsnet.pl/

KLA-

WISZ

WCIŚ-
NIĘTY

ZWOL-

NIONY

---

KLA-

WISZ

WCIŚ-
NIĘTY

ZWOL-

NIONY

---

KLA-

WISZ

WCIŚ-
NIĘTY

ZWOL-

NIONY

A

1C

F0,1C

9

46

F0,46

[

54

FO,54

B

32

F0,32

`

0E

F0,0E

INSERT

E0,70

E0,F0,70

C

21

F0,21

-

4E

F0,4E

HOME

E0,6C

E0,F0,6C

D

23

F0,23

=

55

FO,55

PG UP

E0,7D

E0,F0,7D

E

24

F0,24

\

5D

F0,5D

DELETE

E0,71

E0,F0,71

F

2B

F0,2B

BKSP

66

F0,66

END

E0,69

E0,F0,69

G

34

F0,34

SPACE

29

F0,29

PG DN

E0,7A

E0,F0,7A

H

33

F0,33

TAB

0D

F0,0D

U ARROW

E0,75

E0,F0,75

I

43

F0,43

CAPS

58

F0,58

L ARROW

E0,6B

E0,F0,6B

J

3B

F0,3B

L SHFT

12

FO,12

D ARROW

E0,72

E0,F0,72

K

42

F0,42

L CTRL

14

FO,14

R ARROW

E0,74

E0,F0,74

L

4B

F0,4B

L GUI

E0,1F

E0,F0,1F

NUM

77

F0,77

M

3A

F0,3A

L ALT

11

F0,11

KP /

E0,4A

E0,F0,4A

N

31

F0,31

R SHFT

59

F0,59

KP *

7C

F0,7C

O

44

F0,44

R CTRL

E0,14

E0,F0,14

KP -

7B

F0,7B

P

4D

F0,4D

R GUI

E0,27

E0,F0,27

KP +

79

F0,79

Q

15

F0,15

R ALT

E0,11

E0,F0,11

KP EN

E0,5A

E0,F0,5A

R

2D

F0,2D

APPS

E0,2F

E0,F0,2F

KP .

71

F0,71

S

1B

F0,1B

ENTER

5A

F0,5A

KP 0

70

F0,70

T

2C

F0,2C

ESC

76

F0,76

KP 1

69

F0,69

U

3C

F0,3C

F1

05

F0,05

KP 2

72

F0,72

V

2A

F0,2A

F2

06

F0,06

KP 3

7A

F0,7A

W

1D

F0,1D

F3

04

F0,04

KP 4

6B

F0,6B

X

22

F0,22

F4

0C

F0,0C

KP 5

73

F0,73

Y

35

F0,35

F5

03

F0,03

KP 6

74

F0,74

Z

1A

F0,1A

F6

0B

F0,0B

KP 7

6C

F0,6C

0

45

F0,45

F7

83

F0,83

KP 8

75

F0,75

1

16

F0,16

F8

0A

F0,0A

KP 9

7D

F0,7D

2

1E

F0,1E

F9

01

F0,01

]

5B

F0,5B

3

26

F0,26

F10

09

F0,09

;

4C

F0,4C

4

25

F0,25

F11

78

F0,78

'

52

F0,52

5

2E

F0,2E

F12

07

F0,07

,

41

F0,41

6

36

F0,36

PRNT

SCRN

E0,12,

E0,7C

E0,F0,

7C,E0,

F0,12

.

49

F0,49

7

3D

F0,3D

SCROLL

7E

F0,7E

/

4A

F0,4A

8

3E

F0,3E

PAUSE

E1,14,7,

E1,F0,1,

F0,77

-NONE-

Tabela 1. Wykaz kodów generowanych przez klawiaturę. Tabela zawiera liczby szesnastkowe. Jak łatwo

zauważyć, wciśnięcie niektórych klawiszy powoduje wysłanie nawet do 8 liczb!

- strona 5/14 -

background image

http://www.easy-soft.tsnet.pl/

Key

Make Code

Break Code

Power

E0, 37

E0, F0, 37

Sleep

E0, 3F

E0, F0, 3F

Wake

E0, 5E

E0, F0, 5E

Tabela 2. Kody generowane dla systemu zarządzania zasilaniem komputera PC.

Key

Make Code

Break Code

Next Track

E0, 4D

E0, F0, 4D

Previous Track

E0, 15

E0, F0, 15

Stop

E0, 3B

E0, F0, 3B

Play/Pause

E0, 34

E0, F0, 34

Mute

E0, 23

E0, F0, 23

Volume Up

E0, 32

E0, F0, 32

Volume Down

E0, 21

E0, F0, 21

Media Select

E0, 50

E0, F0, 50

E-Mail

E0, 48

E0, F0, 48

Calculator

E0, 2B

E0, F0, 2B

My Computer

E0, 40

E0, F0, 40

WWW Search

E0, 10

E0, F0, 10

WWW Home

E0, 3A

E0, F0, 3A

WWW Back

E0, 38

E0, F0, 38

WWW Forward

E0, 30

E0, F0, 30

WWW Stop

E0, 28

E0, F0, 28

WWW Refresh

E0, 20

E0, F0, 20

WWW Favorites

E0, 18

E0, F0, 18

Tabela 3. Kody generowane dla aplikacji multimedialnych.

- strona 6/14 -

background image

http://www.easy-soft.tsnet.pl/

/***********************************
Odczyt klawiatury PC
(C) easy-soft 04/2002
***********************************
RAISONANCE RC-51
***********************************/

#pragma

SMALL

#include

<reg51.h>

//port wy wietlacza LCD

ś

#define

PORT P2

//bity steruj ce LCD

ą

sbit LcdEnable = PORT^0;
sbit LcdRead = PORT^3;
sbit LcdReg = PORT^1;

//definicje znaków specjalnych dla wyœwietlacza LCD

char

code CGRom[65] = {

0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,

// "kratka" 0x00

0xC0,0xC0,0xFF,0xF1,0xF1,0xF1,0xFF,0xC0,

// pusty kwadrat 0x01

0xC0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,

// kwadrat zacz.0x02

0xE0,0xFF,0xFF,0xFF,0xE0,0xE0,0xE0,0xE0,

// linia 0x03

0xFF,0xFF,0xF9,0xF3,0xE7,0xF3,0xF9,0xFF,

// znak w lewo 0x04

0xFF,0xFF,0xF3,0xF9,0xFC,0xF9,0xF3,0xFF,

// znak w prawo 0x05

0xFF,0xFF,0xFB,0xF1,0xE4,0xEE,0xFF,0xFF,

// znak w górê 0x06

0xFF,0xFF,0xFF,0xEE,0xE4,0xF1,0xFB,0xFF,

// znak w dó 0x07

ł

0x00};

//bity statusu

bit Alt, Caps, Ctrl, CapsLock, Extended, Pause;

//status.0 = Scroll Lock, status.1=NumLock, status.2=CapsLock

char

status = 0x02;

//linie danych klawiatury

sbit KbdData = P0^1;
sbit KbdClock = P0^0;

//bufor wci ni tego klawisza

ś

ę

char

key;

//zmienne przeznaczone do ró nych operacji

ż

char

temp, temp1;

//funkcje zewn trzne w j zyku asembler

ę

ę

//wys anie bajtu do klawiatury

ł

extern

void

TX_byte(

char

x);

//odbiór bajtu z klawiatury

extern

char

RX_byte(

void

);

//opó nienie oko o 1 milisekundy dla 7,3728MHz

ź

ł

void

Delay (

unsigned

int

k)

{

unsigned

int

i,j;

for

(j = 0; j < k; j++)

for

(i = 0; i <= 296; i++);

}

void

WriteByteToLcd(

char

X)

{

char

temp = X;

//przy wej ciu do procedury temp przyjmuje warto

param.X

ś

ść

P2 |= 0xF0;

//ustawienie górnej po³ówki portu P2 na "1"

P2 &= (temp | 0x0F);

//"bezkolizyjny" zapis 1-szej po³ówki bajtu

//(przez funkcj logiczn )

ę

ą

LcdEnable = 0;

//zapis do wy wietlacza (opadaj ce zbocze sygna u E)

ś

ą

ł

LcdEnable = 1;

//zapis 2-giej po ówki bajtu

ł

- strona 7/14 -

background image

http://www.easy-soft.tsnet.pl/

temp <<= 4;

//przesuni cie 4x w lewo

ę

temp |= 0x0F;

//maskowanie 4 m³odszych bitów

P2 |= 0xF0;

//ustawienie górnej po ówki portu P2 na "1"

ł

P2 &= temp;

//zapis 2-giej po ówki bajtu

ł

LcdEnable = 0;

//opadaj ce zbocze E - zapis do LCD

ą

Delay(1);

}

// zapis bajtu do rejestru kontrolnego LCD

void

WriteToLcdCtrlRegister(

char

X)

{

LcdReg = 0;

//ustawienie sygna ów steruj cych

ł

ą

LcdRead = 0;
LcdEnable = 1;
WriteByteToLcd(X);

}

// write a unsigned character to lcd screen

void

LcdWrite(

char

X)

{

LcdReg = 1;
LcdRead = 0;
LcdEnable = 1;
WriteByteToLcd(X);

}

//czyszczenie ekranu LCD

void

LcdClrScr(

void

)

{

WriteToLcdCtrlRegister(0x01);

}

//inicjalizacja wy wietlacza LCD w trybie 4 bity

ś

void

LcdInitialize(

void

)

{

char

i;

Delay(15);
P0 = 0x0F;

//wyzerowanie linii LcdReg,LcdRead,LcdEnable

for

(i = 0; i<3; i++)

{

LcdEnable = 1;

//impuls na E

PORT &= 0x3F;

//ustawienie wart.inicjuj cej

ą

LcdEnable = 0;
Delay(5);

}
LcdEnable = 1;

//wpisanie warto ci 2 do rej.kontr.

ś

PORT &= 0x2F;

//tylko "górne" 4 bity

LcdEnable = 0;
Delay(1);
WriteToLcdCtrlRegister(0x28);

//interfejs 4 bity,znaki 5x7

WriteToLcdCtrlRegister(0x08);

//wy

czenie LCD

łą

WriteToLcdCtrlRegister(0x01);

//kasowanie ekranu,powrót do home

WriteToLcdCtrlRegister(0x06);

//przesuwanie kursora z inkrement.

WriteToLcdCtrlRegister(0x0C);

//za

czenie wyœwietlacza

łą

}

//ustawia kursor na wspó rz dnych x,y

ł

ę

void

GotoXY(

char

x,

char

y)

{

switch

(y)

//obliczenie o ile nale y zwi kszy x w

ż

ę

ć

//zale no ci od warto ci y

ż

ś

ś

{

case

0:

- strona 8/14 -

background image

http://www.easy-soft.tsnet.pl/

x += 0x80;

//x = x + 0x80

break

;

case

1:

x += 0xC0;

//x = x + 0xC0

break

;

case

2:

x += 0x94;

//x = x + 0x94

break

;

case

3:

x += 0xD4;

//x = x + 0xD4

break

;

}
WriteToLcdCtrlRegister(x);

}

//wy wietla tekst na wspó rz dnych x, y

ś

ł

ę

void

WriteTextXY(

char

x,

char

y,

char

*S)

{

while

(*S)

//p tla dzia a dot d,a napotkany zostanie znak

ż

ę

ł

ą

//ko ca a cucha (/0)

ń

ł ń

{

GotoXY(x, y);

//wyliczenie adresu dla znaku

LcdWrite(*S);

//wy wietlenie pojedynczego znaku

ś

x++;

//nast pna pozycja x na ekranie

ę

S++;

//nast pna pozycja wska nika,tzn.nast pny znak

ę

ź

ę

//napisu

if

(x > 19)

// je li x>19 to nast pna linia

ś

ę

{

x = 0;
y++;

}

}

}

//wy wietla tekst na wspó rz dnych x, y

ś

ł

ę

void

WriteText(

char

*S)

{

while

(*S)

//p tla dzia a dot d,a napotkany zostanie znak

ż

ę

ł

ą

//ko ca a cucha (/0)

ń

ł ń

{

LcdWrite(*S);

// wy wietlenie pojedynczego znaku

ś

S++;

}

}

//definiowanie znaków z tablicy CGRom

void

DefineSpecialCharacters(

void

)

{

char

*ptr = &CGRom;

//ptr wskazuje na tablic CGRom

ę

WriteToLcdCtrlRegister(0x40);

//ustawienie trybu definicji

while

(*ptr != 0)

//p tla wykonywana do napotkania znaku ko ca tablicy

ę

ń

{

LcdWrite(*ptr);

//zapis znaku do lcd cgram

ptr++;

//nast pna pozycja tablicy (wska nika)

ę

ź

}
WriteToLcdCtrlRegister(0x80);

//prze

czenie do trybu wy wietlania

łą

ś

}

//ustawienie statusu klawiatury
//x.0-scroll lock, x.1-num lock, x.2-caps lock

void

Kbd_status(

char

x)

{

TX_byte(0xED);

- strona 9/14 -

background image

http://www.easy-soft.tsnet.pl/

RX_byte();
TX_byte(x);
RX_byte();

}

//konwersja bajtu na warto

hex,wy wietlenie na LCD

ść

ś

//przyk ad procedury do interpratacji znaków odebranych z klawiatury

ł

char

Hex2Ascii(

char

x)

{

if

(x < 10) x += 0x30;

else

x += 0x37;

return

(x);

}

//wy wietlenie szesnastkowego kodu klawisza

ś

void

WriteKeyCode(

char

x)

{

if

(x != 0)

{

WriteTextXY(0,1,"k.code:");

if

(Extended) WriteText("0xE0,");

WriteText("0x");
LcdWrite(Hex2Ascii(x / 16));
LcdWrite(Hex2Ascii(x % 16));
GotoXY(0,2);

if

(Caps) WriteText("Shift ");

if

(Ctrl) WriteText("Ctrl ");

if

(Alt) WriteText("Alt");

if

(Pause) WriteTextXY(0,3,"Paused ");

else

WriteTextXY(0,3," ");

}

else

{

WriteTextXY(7,1," ");
WriteTextXY(0,2," ");

}

}

//program g ówny

ł

void

main(

void

)

{

Delay(250);
LcdInitialize();
DefineSpecialCharacters();
LcdClrScr();

//reset klawiatury; klawiatura odpowiada wysy aj c 2 kody

ł

ą

TX_byte(0xFF);

//pierwszy z nich to 0xFA, drugi 0xAA

while

(!(RX_byte() == 0xFA && RX_byte() == 0xAA));

//napis oznaczaj cy, e inicjacja klawiatury by a pomy lna

ż

ą

ł

ś

WriteTextXY(0,0,"Init OK! Welcome...");
WriteTextXY(0,1,"k.code:");

Kbd_status(status);

//za

czenie num lock

łą

while

(1)

//g ówna p tla (niesko czona) programu

ł

ę

ń

{

key = RX_byte();

if

(key == 0xE0)

//kody rozszerzone

{

//---------- 0xE0 ----------------------

key = RX_byte();

switch

(key)

{

case

0x14:

//R-Ctrl

- strona 10/14 -

background image

http://www.easy-soft.tsnet.pl/

Ctrl = 1;
key = 0;

break

;

case

0x11:

//R-Alt

Alt = 1;
key = 0;

break

;

case

0x1F:

//L-GUI

case

0x27:

//R-GUI

case

0x2F:

//Apps.

case

0x70:

//Insert

case

0x6C:

//Home

case

0x7D:

//PgUp

case

0x71:

//Delete

case

0x69:

//End

case

0x7A:

//PgDn

case

0x75:

//Arrow Up

case

0x6B:

//Arrow Left

case

0x72:

//Arrow Down

case

0x74:

//Arrow Right

case

0x5A:

//Keypad-ENTER

case

0x4A:

//Keypad-divide /

case

0x37:

//Power

case

0x3F:

//Sleep

case

0x5E:

//Wake up

Extended = 1;

break

;

case

0xF0:

//odebrano BREAK "rozszerzonego" klawisza

key = RX_byte();

//odbiór bajtu

if

(key == 0x11) Alt = 0;

//R-Alt

else

if

(key == 0x14) Ctrl = 0;

//R-Ctrl

key = 0;
Extended = 0;

break

;

}

//switch

}

//if (key == 0xE0)

//---------- default -------------------

else

if

(key != 0xE0 && key != 0xF0 && key != 0xE1)

{

Extended = 0;

switch

(key)

{

case

0x12:

//L-Shift

case

0x59:

//R-Shift

Caps = 1;
key = 0;

break

;

case

0x58:

//Caps Lock

CapsLock = !CapsLock;
status ^= 0x04;
Kbd_status(status);
key = 0;

break

;

case

0x14:

//L-Ctrl

Ctrl = 1;
key = 0;

break

;

case

0x11:

//L-Alt

Alt = 1;
key = 0;

break

;

case

0x77:

//Num Lock

- strona 11/14 -

background image

http://www.easy-soft.tsnet.pl/

status ^= 0x02;
Kbd_status(status);
key = 0;

break

;

case

0x7E:

//Scroll Lock

status ^= 0x01;
Kbd_status(status);
key = 0;

break

;

}

//switch

}

//else

//---------- pause ---------------------

else

if

(key == 0xE1)

//klawisz Pause ma bardzo d ug sekwencj

ł

ą

ę

//i nie ma kodu BREAK

{

//0xE1 0x14 0x77 0xE1 0xF0 0x14 0xF0 0x77

RX_byte();
RX_byte();
RX_byte();
RX_byte();
RX_byte();
RX_byte();
RX_byte();
key = 0x77;
Pause = !Pause;

}

//---------- break ---------------------

if

(key == 0xF0)

//odebrano BREAK "standardowego" klawisza

{

//wystarczy odebra i kod zwolnionego klawisza

ć

key = RX_byte();

switch

(key)

{

case

0x12:

//L-Shift

case

0x59:

//R-Shift

Caps = 0;

break

;

case

0x14:

//L-Ctrl

Ctrl = 0;

break

;

case

0x11:

//L-Alt

Alt = 0;

break

;

}
key = 0;

}

//if (key == 0xF0)

WriteKeyCode(key);

}

//while (1)

}

- strona 12/14 -

background image

http://www.easy-soft.tsnet.pl/

;---------------------------------
; modu asemblera do pckeyb.c

ł

; odczyt/zapis klawiatury
;---------------------------------
; kompilator:RA-51 Raisonance
;---------------------------------

EQU

KbdData

P0.1

EQU

KbdClock

P0.0

pc_keyboard SEGMENT CODE
EXTRN DATA
(temp)

;komórka "bufora" danych

EXTRN DATA (temp1)

; - / / -

EXTRN CODE (_Delay)
PUBLIC _TX_byte

;zapis bajtu do klawiatury

PUBLIC RX_byte

;odbiór bajtu

;--------------------------------
; program g ówny

ł

;--------------------------------
;

RSEG pc_keyboard
Low2High:

JNB

KbdClock,$

JB

KbdClock,$

RET

;wys anie bajtu do klawiatury, bajt przekazywany przez j zyk C w R7

ł

ę

_TX_byte:

MOV

B,#8

;liczba bitów do wys ania

ł

MOV

temp,R7

;zapami tanie parametru wywo ania

ę

ł

CLR

KbdClock

MOV

R7,#2

;opó nienie 2 ms

ź

MOV

R6,#0

CALL

_Delay

CLR

KbdData

;Request To Send

SETB

KbdClock

ACALL

Low2High

;oczekiwanie na potw.bit startu

MOV

A,temp

;odtworzenie zawarto ci A (tzn.znak do wysy ki)

ś

ł

TX_Loop:

RRC

A

;wys anie 8 bitów

ł

MOV

KbdData,C

ACALL

Low2High

DJNZ

B,TX_Loop

MOV

A,temp

;wys anie bitu parzysto ci

ł

ś

MOV

C,PSW.0

;(flaga PARITY)

CPL

C

MOV

KbdData,C

ACALL

Low2High

SETB

KbdData

;Stop Bit

ACALL

Low2High

ACALL

Low2High

;Keyboard Ack.

CLR

KbdClock

RET

;odczyt bajtu z klawiatury,bajt zwracany w R7

RX_byte:

SETB

KbdClock

JB

KbdClock,$

JNB

KbdData,RX_byte_Cont

SJMP

RX_byte_Error

RX_byte_Cont:

MOV

B,#8

;licznik odebranych bitów

RX_byte_Loop:

ACALL

Low2High

;odbiór 8 bitów

MOV

C,KbdData

RRC

A

DJNZ

B,RX_byte_Loop

MOV

temp,A

;zapami tanie odebranego znaku

ę

ACALL

Low2High

- strona 13/14 -

background image

http://www.easy-soft.tsnet.pl/

MOV

C,KbdData

;Parity Bit

RLC

A

ACALL

Low2High

MOV

C,KbdData

;Stop Bit

RLC

A

MOV

temp1,A

;zapami tanie bitu stopu i parzysto ci

ę

ś

ANL

A,#1

;sprawdzenie bitu stopu

JZ

RX_byte_Error

MOV

A,temp

;sprawdzenie parzysto ci (w temp odcz.liczba)

ś

MOV

C,PSW.0

;czy odczytana liczba ma parzyst liczb 1?

ą

ę

RLC

A

ANL

A,#1

;maskowanie niepotrzebnych bitów

XCH

A,temp1

;zamiana miejscami odczytanego i wyliczonego
;bitu parz.

ANL

A,#2

;maskowanie bitów

RR

A

;dopasowanie pozycji bitów

XRL

A,temp1

;porównanie bitów parzysto ci

ś

JZ

RX_byte_Error

SJMP

RX_byte_End

RX_byte_Error:

MOV

R7,#1

MOV

R6,#0

ACALL

_Delay

MOV

temp,#0

RX_byte_End:

MOV

R7,temp

CLR

KbdClock

RET

END

- strona 14/14 -


Wyszukiwarka

Podobne podstrony:
4 Zalozenia wyjsciowe do wyceny Nieznany (2)
2 przesylanie argumentow do met Nieznany
cwiczenia praktyczne do Windows Nieznany
Od kultury wizualnej do teologi Nieznany
nom kol 2 odpowiedzi do pytan i Nieznany
08 wprowadzenie do programowani Nieznany
Przebicie LT wersja do druku i Nieznany
Konstytucyjne prawo do informac Nieznany
christmas zestaw cwiczen do ma Nieznany
20130908093258 sylabus do wykla Nieznany (2)
Opis podlaczenia modulow S500 do sterownikow Siemensa
Dodatki i domieszki do betonu i Nieznany
EKON Zas Mat Przyg do spr 1 Nieznany
94 ROZ rzeczoznawcy do spraw Nieznany (2)
Instrukcja obslugi Stojak do be Nieznany
9 4 Lista kontrolna do ustalani Nieznany
80 Nw 09 Suszarka do bielizny i Nieznany

więcej podobnych podstron