Komunikace mezi AT klavesnici urcenou pro PC probiha po dvou dratech. Jedna se o seriovou komunikaci, kde na vodici nazvanem DATA (pin 2) jsou data a vodici nazvanem CLOCK (pin 1) jsou hodiny. Pin 5 je napajeni klavesnice 5V, pin 4 je zem a pin 3 je RESET, coz je pozustatek z XT klavesnic. Rychlost hodinoveho signalu je v rozsahu cca 10 az 20 kHz.
Kdyz je stisknuta klavesa, klavesnice vysle do pocitace kod klavesy. Po uvolneni klavesy je vyslan ridici znak oznamujici uvolneni klavesy a kod uvolnene klavesy.
Signal CLOCK je vzdy ridici a ridi ho sama klavesnice (tyka se modu vysilani znaku z klavesnice i pri prijmu znaku do klavesnice). Prijem znaku z klavesnice probiha pri stisku klavesy a vysilani znaku progiha pri vzniku pozadavku zaslani ridiciho znaku do klavesnice. Na signalu DATA jsou vzdy pri vzestupne hrane platna data. Zmena dat se tedy musi provadet pri sestupne hrane. Pri vyslani znaku z klavesnice ridi signal DATA klavesnice, pri vysilani znaku do klavesnice ridi signal DATA pocitac. Pri komunikaci se prenasi vzdy jedno 8 bitove slovo, 1 start bit, 1 paritni bit (licha parita) a 1 stop bit.
Poznámka redakce HW serveru : (22.04.2000)
Z ohlasů našich čtenářů vyplývá, že pokud se jedná o přenos dat z klavesnice do PC, některé klávesnice generují platná DATA nikoli při vzestupné hraně CLK, ale při sestupné hraně CLK. Hodnota se potom samozřejmě mění při hodnotě L signálu CLK.
Pravděpodobně je důvodem nekompatibility nerozličování reakce na hranu, nebo na úroveň. Pokud vám tedy nebude fungovat zařízení, hledejte chybu zde.
s--DATA--PS
s = start bit
DATA = prvni bit (LSB bit-nejnizzsi bit)
P = paritni bit - licha parita
S = stop bit
Jako priklad si uvedeme klavesu "A" (0x1C):
paritni bit
|
start bit |
| |
00011100001
|
stop bit
V pripade pozadavku na vyslani ridiciho znaku do klavesnice je nutne signal DATA stahnout na uroven logicke nuly a klavesnice si sama zacne generovat hodinove pulsy na signalu CLOCK. Potom staci tento ridici signal CLOCK
sledovat a poslat mu data jako pri prijmu (1 start bit, 8 bitove slovo a 1 paritni bit (licha parita).
Odskok na popis připojení klávesnice k jednočipu..
Ridici kody vyslane z PC do klavesnice :
----------------------------------------
(vsechny ridici kody jsou v hexadecimalnim formatu)
0xFF - reset klavesnice - spusti se power-on test
0xFE - zadost o zaslani posledniho zaslaneho scan kodu klavesy
0xFA - potvrzeni - ACK
0xF6 - obnoveni implicitniho nastaveni klavesnice
0xF5 - implicitni zablokovani klavesnice - provede reset klavesnice,
vraci kod ACK (0xFA), provede preruseni scanovani klavesnice
a ceka na dalsi prikaz, nema zadny vliv na LED indikator
0xF4 - odblokovani klavesnice - nuluje vystupni buffer, odblokuje
klavesnici a vraci kod (0xFA)
0xEE - echo - klavesnice odpovi zpet take 0xEE jako echo - pro test
0xF2 - cteni ID klavesnice - klavensice odpovi ACK se dvemi ID byty
(0x83,0xAB) a pokracuje ve scanovani po predchazejicim
zablokovani klavesnice
0xED - zapnuti nebo vypnuti LED indikatoru klavesnice
b0 - Scrollock - 1 zapnuto/0 vypnuto
b1 - Numlock - 1 zapnuto/0 vypnuto
b2 - Capslock - 1 zapnuto/0 vypnuto
b3..b7 - 0
Ridici kody vyslane z klavesnice do PC :
----------------------------------------
(vsechny ridici kody jsou v hexadecimalnim formatu)
0xFF - preteceni bufferum klavesnice detekuje chybu
0xFE - zadost o zaslani posledniho zaslaneho znaku, spatne prijaty
prikaz, parita apod.
0xFA - potvrzeni - ACK
0xF0 k - uvolneni klavesy - k -> kod uvolnene klavesy
0xAA - uspesny power-on test
0xEE - echo - klavesnice odpovi zpet take 0xEE jako echo - pro test
0x00 - preteceni bufferum klavesnice detekuje chybu
Scanovaci kody
==============
-----------------------------------------------------------------------
*** Standardni 101 tlacitkovaklavesnice a jeji kody a sekvence ***
** Hlavni klavesnice **
-----------------------------------------------------------------------
Klavesa Vyslany kod pri stisku Vyslany kod pri uvolneni
-----------------------------------------------------------------------
` 0x0E 0xF0 0x0E
1 0x16 0xF0 0x16
2 0x1E 0xF0 0x1E
3 0x26 0xF0 0x26
4 0x25 0xF0 0x25
5 0x2E 0xF0 0x2E
6 0x36 0xF0 0x36
7 0x3D 0xF0 0x3D
8 0x3E 0xF0 0x3E
9 0x46 0xF0 0x46
0 0x45 0xF0 0x45
- 0x4E 0xF0 0x4E
= 0x55 0xF0 0x55
Backspace 0x66 0xF0 0x66
Tabelator 0x0D 0xF0 0x0D
Q 0x15 0xF0 0x15
W 0x1D 0xF0 0x1D
E 0x24 0xF0 0x24
R 0x2D 0xF0 0x2D
T 0x2C 0xF0 0x2C
Y 0x35 0xF0 0x35
U 0x3C 0xF0 0x3C
I 0x43 0xF0 0x43
O 0x44 0xF0 0x44
P 0x4D 0xF0 0x4D
[ 0x54 0xF0 0x54
] 0x5B 0xF0 0x5B
0x5D 0xF0 0x5D
Caps Lock 0x58 0xF0 0x58
A 0x1C 0xF0 0x1C
S 0x1B 0xF0 0x1B
D 0x23 0xF0 0x23
F 0x2B 0xF0 0x2B
G 0x34 0xF0 0x34
H 0x33 0xF0 0x33
J 0x3B 0xF0 0x3B
K 0x42 0xF0 0x42
L 0x4B 0xF0 0x4B
; 0x4C 0xF0 0x4C
" 0x52 0xF0 0x52
Enter 0x5A 0xF0 0x5A
Levy Shift 0x12 0xF0 0x12
Z 0x1A 0xF0 0x1A
X 0x22 0xF0 0x22
C 0x21 0xF0 0x21
V 0x2A 0xF0 0x2A
B 0x32 0xF0 0x32
N 0x31 0xF0 0x31
M 0x3A 0xF0 0x3A
, 0x41 0xF0 0x41
. 0x49 0xF0 0x49
/ 0x4A 0xF0 0x4A
Pravy Shift 0x59 0xF0 0x59
Levy Ctrl 0x14 0xF0 0x14
Levy Alt 0x11 0xF0 0x11
Mezera 0x29 0xF0 0x29
Pravy Alt 0xE0 0x11 0xE0 0xF0 0x11
Pravy Ctrl 0xE0 0x14 0xE0 0xF0 0x14
ESC 0x76 0xF0 0x76
-----------------------------------------------------------------------
** Funkcni klavesy **
-----------------------------------------------------------------------
Klavesa Vyslany kod pri stisku Vyslany kod pri uvolneni
-----------------------------------------------------------------------
F1 0x05 0xF0 0x05
F2 0x06 0xF0 0x06
F3 0x04 0xF0 0x04
F4 0x0C 0xF0 0x0C
F5 0x03 0xF0 0x03
F6 0x0B 0xF0 0x0B
F7 0x83 0xF0 0x83
F8 0x0A 0xF0 0x0A
F9 0x01 0xF0 0x01
F10 0x09 0xF0 0x09
F11 0x78 0xF0 0x78
F12 0x07 0xF0 0x07
-----------------------------------------------------------------------
** Numericka cast **
-----------------------------------------------------------------------
Klavesa Vyslany kod pri stisku Vyslany kod pri uvolneni
-----------------------------------------------------------------------
NumLok 0x77 0xF0 0x77
- 0x7B 0xF0 0x7B
/ 0xE0 0x4A 0xE0 0xF0 0x4A Pozn.1,2
. 0x71 0xF0 0x71
* 0x7C 0xF0 0x7C
+ 0x79 0xF0 0x79
Enter 0xE0 0x5A 0xE0 0xF0 0x5A
0 0x70 0xF0 0x70
1 0x69 0xF0 0x69
2 0x72 0xF0 0x72
3 0x7A 0xF0 0x7A
4 0x6B 0xF0 0x6B
5 0x73 0xF0 0x73
6 0x74 0xF0 0x74
7 0x6C 0xF0 0x6C
8 0x75 0xF0 0x75
9 0x7D 0xF0 0x7D
-----------------------------------------------------------------------
** Pomocna cast **
-----------------------------------------------------------------------
Klavesa Vyslany kod pri stisku Vyslany kod pri uvolneni
-----------------------------------------------------------------------
Ins 0xE0 0x70 0xE0 0xF0 0x70 Pozn.1,2,3
Home 0xE0 0x6C 0xE0 0xF0 0x6C Pozn.1,2,3
Pg Up 0xE0 0x7D 0xE0 0xF0 0x7D Pozn.1,2,3
Del 0xE0 0x71 0xE0 0xF0 0x71 Pozn.1,2,3
End 0xE0 0x69 0xE0 0xF0 0x69 Pozn.1,2,3
Pg Dn 0xE0 0x7A 0xE0 0xF0 0x7A Pozn.1,2,3
Sipka nahoru 0xE0 0x75 0xE0 0xF0 0x75 Pozn.1,2,3
Sipka doleva 0xE0 0x6B 0xE0 0xF0 0x6B Pozn.1,2,3
Sipka doprava 0xE0 0x74 0xE0 0xF0 0x74 Pozn.1,2,3
Sipka dolu 0xE0 0x72 0xE0 0xF0 0x72 Pozn.1,2,3
PrtSc 0xE0 0x12 0xE0 0x7C 0xE0 0xF0 0x7C 0xE0 0xF0 0x12
Ctl-PrtSc 0xE0 0x7C 0xE0 0xF0 0x7C
Alt-PrtSc 0x84 0xE0 0x84
ScrLk 0x7E 0xF0 0x7E
Ctrl-Break 0xE0 0x7E 0xE0 0xF0 0x7E nic
-----------------------------------------------------------------------
** Poznamky **
-----------------------------------------------------------------------
Poznamka 1
Pri stiknutem levem shiftu :
Vyslany kod pri stisku - 0xE0 0xF0 0x12 0x** 0x**
Vyslany kod pri uvolneni - 0x** 0x** 0x** 0xE0 0x12
Poznamka 2
Pri stiknutem pravem shiftu :
Vyslany kod pri stisku - 0xE0 0xF0 0x59 0x** 0x**
Vyslany kod pri uvolneni - 0x** 0x** 0x** 0xE0 0x59
Poznamka 3
Pri stiknutem Num Locku :
Vyslany kod pri stisku - 0xE0 0x12 0x** 0x**
Vyslany kod pri uvolneni - 0x** 0x** 0x** 0xE0 0xF0 0x12
"0x** 0x**" - normalne vysilane sekvence pri stiknute klavese
"0x** 0x** 0x**" - normalne vysilane sekvence pri uvolneni klavesy
Strucny popis pripojeni klavesnice typu AT k jednocipovym procesorum
Na zaklade predchazejicihi popisu jsem pocitacovou klavesnici typu AT pripojil k procesoru rady "51 SIEMENS 80C537. Ridici signal CLOCK jsem pripojil na externi preruseni tak, aby prislo preruseni pri vzestupne hrane, kdy jsou platna data. Druhy vodic DATA jsem pripojil na libovolny I/O pin procesoru. V prerusovaci procedure si pri prvnim preruseni vynuluji pocet prijatych bitu, ktery pri kazdem dalsim preruseni inkrementuji. Pokud se jedna o bity 1 az 8 (0 byl start bit) prectu stav datovoho vodice do jednoho znaku, dalsi 9 bit prectu jako paritni bit, ktery zkontroluji a 10 bit je stop bit. Pokud jsou spravne prijaty vsechny bity s souhlasi parita provadim dekodovani prijateho znaku. Prijate znaky si pripadne bufferuji tak, abych mohl dekodovat prislusne sekvence. Toto reseni s vyuzitim preruseni se da pouzit pro jakeko-li jednocipove procesory a jeho velikou vyhodou je minimalni rezie, kterou si klavesnice z celeho systemu zabere.
Pro programatory v jazyce C prikladam prevodni tabulky pro shiftovanou nebo neshiftovanou klavesnici.
const unsigned char code unshift_table[256] = {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
/* 0x */ 0x00,0xF9,0x00,0xF5,0xF3,0xF1,0xF2,0xFC,0x00,0xFA,0xF8,0xF6,0xF4,0x09,"`" ,0x00,
/* 1x */ 0x00,0x00,0x00,0x00,0x00,"q" ,"l" ,0x00,0x00,0x00,"z" ,"s" ,"a" ,"w" ,"2" ,0x00,
/* 2x */ 0x00,"c" ,"x" ,"d" ,"e" ,"4" ,"3" ,0x00,0x00," " ,"v" ,"f" ,"t" ,"r" ,"5" ,0x00,
/* 3x */ 0x00,"n" ,"b" ,"h" ,"g" ,"y" ,"6" ,0x00,0x00,0x00,"m" ,"j" ,"u" ,"7" ,"8" ,0x00,
/* 4x */ 0x00,"," ,"k" ,"i" ,"o" ,"0" ,"9" ,0x00,0x00,"." ,"/" ,"l" ,";" ,"p" ,"-" ,0x00,
/* 5x */ 0x00,"," ,0x00,0x00,"[" ,"=" ,0x00,0x00,0x00,0x00,0x0D,"]" ,0x00,0x5C,0x00,0x00,
/* 6x */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* 7x */ 0x00,0x7F,0x00,0x00,0x00,0x1B,0x00,0x00,0xFB,"+" ,0x00,"-" ,"*" ,0x00,0x00,0x00,
/* 8x */ 0x00,0x00,0x00,0xF7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* 9x */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Ax */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Bx */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Cx */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Dx */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Ex */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Fx */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
const unsigned char code shift_table[256] = {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
/* 0x */ 0x00,0xF9,0x00,0xF5,0xF3,0xF1,0xF2,0xFC,0x00,0xFA,0xF8,0xF6,0xF4,0x09,"~" ,0x00,
/* 1x */ 0x00,0x00,0x00,0x00,0x00,"Q" ,"!" ,0x00,0x00,0x00,"Z" ,"S" ,"A" ,"W" ,"@" ,0x00,
/* 2x */ 0x00,"C" ,"X" ,"D" ,"E" ,"$" ,"#" ,0x00,0x00," " ,"V" ,"F" ,"T" ,"R" ,"%" ,0x00,
/* 3x */ 0x00,"N" ,"B" ,"H" ,"G" ,"Y" ,"^" ,0x00,0x00,0x00,"M" ,"J" ,"U" ,"&" ,"*" ,0x00,
/* 4x */ 0x00,"<" ,"K" ,"I" ,"O" ,")" ,"(" ,0x00,0x00,">" ,"?" ,"L" ,":" ,"P" ,"_" ,0x00,
/* 5x */ 0x00,""" ,0x00,0x00,"{" ,"+" ,0x00,0x00,0x00,0x00,0x0D,"}" ,0x00,"|" ,0x00,0x00,
/* 6x */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,"1" ,0x00,"4" ,"7" ,0x00,0x00,0x00,
/* 7x */ "0" ,"." ,"2" ,"5" ,"6" ,"8" ,0x1B,0x00,0xFB,"+" ,"3" ,"-" ,0x00,"9" ,0x00,0x00,
/* 8x */ 0x00,0x00,0x00,0xF7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* 9x */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Ax */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Bx */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Cx */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Dx */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Ex */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* Fx */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
Starší článek o této problematice : Popis komunikace mezi PC klavesnici typu AT a PC - Petr Simandl