PS2键盘接口协议
一.電氣特性
| 1 | DATA | Key Data |
| 2 | n/c | Not connected |
| 3 | GND | Gnd |
| 4 | VCC | Power , +5 VDC |
| 5 | CLK | Clock |
| 6 | n/c | Not connected |
二.數(shù)據(jù)格式
| 1個起始位 | 總是邏輯0 |
| 8個數(shù)據(jù)位 | (LSB)低位在前 |
| 1個奇偶校驗(yàn)位 | 奇校驗(yàn) |
| 1個停止位 | 總是邏輯1 |
| 1個應(yīng)答位 | 僅用在主機(jī)對設(shè)備的通訊中 |
表中,如果數(shù)據(jù)位中1的個數(shù)為偶數(shù),校驗(yàn)位就為1;如果數(shù)據(jù)位中1的個數(shù)為奇數(shù),校驗(yàn)位就為0;總之,數(shù)據(jù)位中1的個數(shù)加上校驗(yàn)位中1的個數(shù)總為奇數(shù),因此總進(jìn)行奇校驗(yàn)。
ps2設(shè)備的clock和data都是集電極開路的,平時都是高電平。當(dāng)ps2設(shè)備等待發(fā)送數(shù)據(jù)時,它首先檢查clock是否為高。如果為低,則認(rèn)為PC抑制了通訊,此時它緩沖數(shù)據(jù)直到獲得總線的控制權(quán)。如果clock為高電平,ps2則開始向PC發(fā)送數(shù)據(jù)。
一般都是由ps2設(shè)備產(chǎn)生時鐘信號。發(fā)送按幀格式。數(shù)據(jù)位在clock為高電平時準(zhǔn)備好,在clock下降沿被PC讀入。
數(shù)據(jù)從鍵盤/鼠標(biāo)發(fā)送到主機(jī)或從主機(jī)發(fā)送到鍵盤/鼠標(biāo),時鐘都是PS2設(shè)備產(chǎn)生.主機(jī)對時鐘控制有優(yōu)先權(quán),即主機(jī)想發(fā)送控制指令給PS2設(shè)備時,可以拉低時鐘線至少100μS,然后再下拉數(shù)據(jù)線,最后釋放時鐘線為高。PS2設(shè)備的時鐘線和數(shù)據(jù)線都是集電極開路的,容易實(shí)現(xiàn)拉低電平。
PC在時鐘的下降沿讀取數(shù)據(jù).
PS: ps2協(xié)議是現(xiàn)在大多數(shù)鼠標(biāo),鍵盤與PC通訊的標(biāo)準(zhǔn)協(xié)議,鼠標(biāo)的通訊更為簡單些,只是傳送的數(shù)據(jù)內(nèi)容不一樣而已。
三.數(shù)據(jù)發(fā)送時序
鍵盤接口時序(a) 鍵盤發(fā)送時序;(b) 鍵盤接收時序
??? 從PS/2向PC機(jī)發(fā)送一個字節(jié)可按照下面的步驟進(jìn)行:
????????? (1)檢測時鐘線電平,如果時鐘線為低,則延時50μs;
????????? (2)檢測判斷時鐘信號是否為高,為高,則向下執(zhí)行,為低,則轉(zhuǎn)到(1);
????????? (3)檢測數(shù)據(jù)線是否為高,如果為高則繼續(xù)執(zhí)行,如果為低,則放棄發(fā)送(此時PC機(jī)在向 PS/2設(shè)備發(fā)送數(shù)據(jù),所以PS/2設(shè)備要轉(zhuǎn)移到接收程序處接收數(shù)據(jù));
????????? (4)延時20μs(如果此時正在發(fā)送起始位,則應(yīng)延時40μs);
???????? (5)輸出起始位(0)到數(shù)據(jù)線上。這里要注意的是:在送出每一位后都要檢測時鐘線,以確保PC機(jī)沒有抑制PS/2設(shè)備,如果有則中止發(fā)送;
????????? (6)輸出8個數(shù)據(jù)位到數(shù)據(jù)線上;
?????????? (7)輸出校驗(yàn)位;
?????????? (8)輸出停止位(1);
?????????? (9)延時30μs(如果在發(fā)送停止位時釋放時鐘信號則應(yīng)延時50μs);
?? 通過以下步驟可發(fā)送單個位:
?????????? (1)準(zhǔn)備數(shù)據(jù)位(將需要發(fā)送的數(shù)據(jù)位放到數(shù)據(jù)線上);
?????????? (2)延時20μs;
?????????? (3)把時鐘線拉低;
?????????? (4)延時40μs;
?????????? (5)釋放時鐘線;
?????????? (6)延時20μs。
??? PS/2設(shè)備從PC機(jī)接收一個字節(jié)
由于PS/2設(shè)備能提供串行同步時鐘,因此,如果PC機(jī)發(fā)送數(shù)據(jù),則PC機(jī)要先把時鐘線和數(shù)據(jù)線置為請求發(fā)送的狀態(tài)。PC機(jī)通過下拉時鐘線大于100μs來抑制通訊,并且通過下拉數(shù)據(jù)線發(fā)出請求發(fā)送數(shù)據(jù)的信號,然后釋放時鐘。當(dāng)PS/2設(shè)備檢測到需要接收的數(shù)據(jù)時,它會產(chǎn)生時鐘信號并記錄下面8個數(shù)據(jù)位和一個停止位。主機(jī)此時在時鐘線變?yōu)榈蜁r準(zhǔn)備數(shù)據(jù)到數(shù)據(jù)線,并在時鐘上升沿鎖存數(shù)據(jù)。而PS/2設(shè)備則要配合PC機(jī)才能讀到準(zhǔn)確的數(shù)據(jù)。具體連接步驟如下:
?? (1)等待時鐘線為高電平。
????????? (2)判斷數(shù)據(jù)線是否為低,為高則錯誤退出,否則繼續(xù)執(zhí)行。
????????? (3)讀地址線上的數(shù)據(jù)內(nèi)容,共8個bit,每讀完一個位,都應(yīng)檢測時鐘線是否被PC機(jī)拉低,如果被拉低則要中止接收。
????????? (4)讀地址線上的校驗(yàn)位內(nèi)容,1個bit。
????????? (5)讀停止位。
????????? (6)如果數(shù)據(jù)線上為0(即還是低電平),PS/2設(shè)備繼續(xù)產(chǎn)生時鐘,直到接收到1且產(chǎn)生出錯信號為止(因?yàn)橥V刮皇?#xff11;,如果PS/2設(shè)備沒有讀到停止位,則表明此次傳輸出錯)。??????????
????????? (7 輸出應(yīng)答位。
????????? (8) 檢測奇偶校驗(yàn)位,如果校驗(yàn)失敗,則產(chǎn)生錯誤信號以表明此次傳輸出現(xiàn)錯誤。
????????? (9)延時45 μs,以便PC機(jī)進(jìn)行下一次傳輸。
讀數(shù)據(jù)線的步驟如下:
?? (1)延時20μs;
????????? (2)把時鐘線拉低
????????? (3)延時40μs
????????? (4)釋放時鐘線
????????? (5)延時20μs
????????? (6)讀數(shù)據(jù)線。
下面的步驟可用于發(fā)出應(yīng)答位;
(1)延時15μs; (2)把數(shù)據(jù)線拉低;(3)延時5μs;(4)把時鐘線拉低;(5)延時40μs;(6)釋放時鐘線;(7)延時5μs; (8)釋放數(shù)據(jù)線。
四.鍵盤返回值介紹:
鍵盤的處理器如果發(fā)現(xiàn)有鍵被按下或釋放將發(fā)送掃描碼的信息包到計算機(jī)。掃描碼有兩種不同的類型:通碼和斷碼。當(dāng)一個鍵被按下就發(fā)送通碼,當(dāng)一個鍵被釋放就發(fā)送斷碼。每個按鍵被分配了唯一的通碼和斷碼。這樣主機(jī)通過查找唯一的掃描碼就可以測定是哪個按鍵。每個鍵一整套的通斷碼組成了掃描碼集。有三套標(biāo)準(zhǔn)的掃描碼集:分別是第一套,第二套和第三套。所有現(xiàn)代的鍵盤默認(rèn)使用第二套掃描碼。
?????? 雖然多數(shù)第二套通碼都只有一個字節(jié)寬,但也有少數(shù)擴(kuò)展按鍵的通碼是兩字節(jié)或四字節(jié)寬。這類的通碼第一個字節(jié)總是為E0。
?????? 正如鍵按下通碼就被發(fā)往計算機(jī)一樣,只要鍵一釋放斷碼就會被發(fā)送。每個鍵都有它自己唯一的通碼和斷碼。幸運(yùn)的是你不用總是通過查表來找出按鍵的斷碼。在通碼和斷碼之間存在著必然的聯(lián)系。多數(shù)第二套斷碼有兩字節(jié)長。它們的第一個字節(jié)是F0 ,第二個字節(jié)是這個鍵的通碼。擴(kuò)展按鍵的斷碼通常有三個字節(jié),它們前兩個字節(jié)是E0h,F0h ,最后一個字節(jié)是這個按鍵通碼的最后一個字節(jié)。下面列出了幾個按鍵的第二套通碼和斷碼:
| 1 | "A" | 1C | F0 1C |
| 2 | "5" | 2E | F0 2E |
| 3 | "F10" | 09 | F0 09 |
| 4 | Right Arrow | E0 74 | E0 F0 74 |
| 5 | Right "Ctrl" | E0 14 | E0 F0 14 |
一個鍵盤發(fā)送值的例子:
????? 通碼和斷碼是以什么樣的序列發(fā)送到你的計算機(jī)從而使得字符G 出現(xiàn)在你的字處理軟件里的呢?因?yàn)檫@是一個大寫字母,需要發(fā)生這樣的事件次序:按下Shift 鍵-按下G鍵-釋放G 鍵-釋放Shift 鍵。與這些時間相關(guān)的掃描碼如下:Shift 鍵的通碼12h,G 鍵的通碼34h ,G 鍵的斷碼F0h 34h ,Shift 鍵的斷碼F0h 12h 。因此發(fā)送到你的計算機(jī)的數(shù)據(jù)應(yīng)該是:
12h 34h F0h 34h F0h 12h
五:第二套掃描碼:
101 102 和104 鍵的鍵盤:
| ? | KEY | 通碼 | 斷碼 | ? | KEY | 通碼 | 斷碼 | |||
| A | 1C | F0 1C | ? | 9 | 46 | F0 46 | ? | [ | 54 | F0 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 | F0 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 | F0 12 | ? | D ARROW | E0 72 | E0 F0 72 |
| K | 42 | F0 42 | ? | L CTRL | 14 | F0 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 | ? | ] | 58 | F0 58 |
| 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 77 E1 F0 14 F0 77 | -NONE- | ? | ? | ? | ? |
ACPI 掃描碼:
| Power | E0, 37 | E0, F0, 37 |
| Sleep | E0, 3F | E0, F0, 3F |
| Wake | E0, 5E | E0, F0, 5E |
Windows 多媒體掃描碼:
| 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 |
| 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, 20 |
| WWW Stop | E0, 28 | E0, F0, 28 |
| WWW Refresh | E0, 20 | E0, F0, 20 |
| WWW Favorites | E0, 18 | E0, F0, 18 |
void Decode(unsigned char ScanCode) //
{
unsigned char TempCyc,Val;
if (!Key_UP)??????????????????????? //當(dāng)鍵盤按下時
?{
?switch (ScanCode)
???{
???case 0xF0 :???????????? // 當(dāng)收到0xF0,Key_UP置1表示斷碼開始
????Key_UP = 1;
????break;
???case 0x12 :???????????? // 左 SHIFT
????Shift = 1;
????break;
???case 0x59 :???????????? // 右 SHIFT
????Shift = 1;
????break;
???default:
????if(!Shift)????????? //如果SHIFT沒按下
?????{
?????for (TempCyc = 0;(UnShifted[TempCyc][0]!=ScanCode)&&(TempCyc<59); TempCyc++); //查表顯示
?????if (UnShifted[TempCyc][0] == ScanCode)
??????{
?? ??????Val= UnShifted[TempCyc][1];
??????LCD_Write_Char(DisNum%16,DisNum/16,Val);
??????DisNum++;
?? ??????if(DisNum==33)
???? ?????? {
?? ?????? LCD_Clear(); //清屏
?? ?????? DisNum=0;??? //重頭寫數(shù)據(jù)
? ????????? }
?????????? }
???????????????????? }
????else //按下SHIFT
??????????????????? {
?????for(TempCyc = 0; (Shifted[TempCyc][0]!=ScanCode)&&(TempCyc<59); TempCyc++); //查表顯示
?????if (Shifted[TempCyc][0] == ScanCode)
?????????????????????? {
? ??????Val= Shifted[TempCyc][1];
??????????????????????? LCD_Write_Char(DisNum%16,DisNum/16,Val);
??????DisNum++;
?? ??????if(DisNum==33)
???? ?????? {
?? ?????? LCD_Clear(); //清屏
?? ?????? DisNum=0;??? //重頭寫數(shù)據(jù)
? ????????? }
? ??????}
????????????????????? }
?????break;
????}
?}
else
?{
?Key_UP = 0;
?switch (ScanCode) //當(dāng)鍵松開時不處理判碼,如G 34H F0H 34H 那么第二個34H不會被處理
???{
???case 0x12 : // 左 SHIFT
????Shift = 0;
????break;
???case 0x59 : // 右 SHIFT
????Shift = 0;
????break;
???}
?}
BF = 0; //標(biāo)識字符處理完了
}
總結(jié)
- 上一篇: 关于android 在黑屏情况下wifi
- 下一篇: java整理快捷鍵_常用Eclipse快