2012年4月25日 星期三

DIY - PIC: PIC18F4550 PS/2 鍵盤中斷程式 (一百二十七)

DIY - PIC PIC18F4550 PS/2 鍵盤中斷程式 (一百二十七)

PS/2 鍵盤 Data Line 接上 RB3 Clock Line 接上 RB2這次使用了 18F4550 PORTB RB2 作為按鍵中斷 I/O,每當鍵盤由 High 變成 Low便會觸發中斷執行程式而程式是會接收 RB3的數據時,會暫時停止 RB2中斷服務,直至將 Data 的數據全部接收並將數據全部顯示在 LCD 屏上。

  PIC18F4550鍵盤中斷程式流程圖
▼主程式
void main(void)
{

    // Set up RB2 Interrupt
    INTCON2bits.RBPU = 0;       // Enable Pull up resistors at PORTB
    INTCON2bits.INTEDG2 = 0;    // Ext INT2 1=Rising Edge,0=Falling Edge
           
    LATBbits.LATB2 = 1;             // Latch 1 to RB2
    LATBbits.LATB3 = 1;             // Latch 0 to RB3
    PS2KeyInit();               // Init PS2 Parameters

    // Set up RB2 Interrupt
    RCONbits.IPEN      = 1;     // Enable INT Priority
    INTCON3bits.INT2IP = 1;     // Set RB2 High INT2 1=High,0=Low
    INTCON3bits.INT2IE = 1;     // Enable RB2 INT2 1=Enable,0=Disable
    INTCONbits.PEIE    = 1;     // Enable Peripheral INT
    INTCONbits.GIE     = 1;     // Enable Global INT

    // Check the PS2 Keyboard BAT After RST~320ms Max=500ms
        for (timeout=0;timeout<50;timeout++){
                Delay10KTCYx(5);        // 10,000x(4 x 0.05us)=2ms*5=10ms
                if(PS2KeyHit()){
                        itoa(timeout,disp_temp);
                        putsXLCD(disp_temp);
                        putrsXLCD(" ");                      
                        PS2Key_Char = PS2KeyGetKey();
                        timeout=254;
                        }     
                }
    // Check the PS2 Keyboard BAT 0xAA/0xFC Code
                if (PS2Key_Char == 0xAA){
                        itoa(PS2Key_Char,disp_temp);
                        putsXLCD(disp_temp);
                        putrsXLCD(" READY");
                } else putrsXLCD(" ERROR");


while(1) {
timeout++;

                if(timeout>150){
                                timeout=0;
                                LcdSetLine2();
                                putrsXLCD("                ");
                                LcdSetLine2();
                }



                if(PS2KeyHit()){
                    PS2Key_Char = PS2KeyGetKey();
                temp=(PS2Key_Char & 0xF0);

                temp=(temp>>4)+48;
                if (temp>57) temp=temp+7;
                disp_temp[0]=temp;disp_temp[1]='\0';
                putsXLCD(disp_temp);

                temp=(PS2Key_Char & 0x0F)+48;
                        if (temp>57) temp=temp+7;
                disp_temp[0]=temp;disp_temp[1]='\0';
                            putsXLCD(disp_temp);
                putrsXLCD("");
                }



                LATAbits.LATA0 = 0;                     // RA0=0 LED=OFF Scope=50ms
                Delay10KTCYx(10);                     // 10,000 x 1 x (4 x 0.05us) = 2ms
                                                       
                LATAbits.LATA0 = 1;                     // RA0=1 LED=ON Scope=1
                Delay10KTCYx(10);                     // 10,000 x 1 x (4 x 0.05us) = 2ms
                                                           // Scope = 2ms
}
       
} // Main End

▼中斷副程式
void low_isr()
{

    INTCON3bits.INT2IE = 0;     // Disable RB2 INT Flag
    INTCON3bits.INT2IF = 0;     // Clear RB2 INT Flag

    PS2KeyIntHandler();         // PS2 Key INT Handler

    INTCON3bits.INT2IE = 1;     // Enable RB2 INT2 1=Enable,0=Disable
    INTCONbits.GIE     = 1;     // Enable All INT

}

PS/2 鍵盤接上控制板

鍵盤執行 BAT,完成後,數據 0xAA = 170
 測試 BWS 按鍵:
  B鍵數據 32 F0 32

W鍵數據 1D F0 1D

S鍵數據 1B F0 1B

2012年4月24日 星期二

DIY - PIC: PIC18F4550 PS/2 鍵盤電路 (一百二十六)

DIY - PIC PIC18F4550 PS/2 鍵盤電路 (一百二十六)

由於 IBM PS/2 鍵盤已經內置微處理器,控制電路及編解碼程式都已經內置鍵盤,祇要提供電源和接收數據,便可操作了!所以 PIC18F4550 PS/2 鍵盤電路的很簡單衹要將 Data LineClock LineVCC GND 連接, Data Line 接上 RB3 Clock Line 接上 RB2

18F4550 PS/2 鍵盤電路
5 Pin 排插
開工! 5 Pin 排插接至按鍵板
mini DIN PS/2 插頭
mini DIN PS/2 頭接至 5 Pin 排插上
接上 PS/2 鍵盤

2012年4月23日 星期一

DIY - PIC: PIC18F4550 PS/2 鍵盤 Commend Set (一百二十五)

DIY - PIC PIC18F4550 PS/2 鍵盤 Commend Set (一百二十五)

鍵盤的微處理器主要時間是用來掃描或監視按鍵矩陣的狀態,如果發現有鍵被按下釋放或按住鍵盤,處理器將發送掃描碼 (scan code) 的資訊到電腦,掃描碼 (scan code) 有兩種不同的類型通碼 (Mark Code) 和斷碼 (Break Code),當一個鍵被按下或按住就發送通碼 (Mark Code),當一個鍵被釋放就發送斷碼 (Break Code),每個按鍵被分配了唯一的通碼和斷碼這樣主機通過查找唯一的掃描碼就可以測定是哪個按鍵每個鍵一整套的通斷碼組成了掃描碼。

 
掃描碼 (Scan Code)
例如按下A,鍵盤就會發送 0x1C 到主機,如繼續按著A,鍵盤就會繼續發送 0x1C 到主機。當鍵盤被釋放,鍵盤會發送 0xF0加鍵碼到主機,告知主機鍵盤哪個鍵被開釋。並不是所有的鍵都只有一個位元組的鍵碼。伸展鍵盤中有一些鍵的鍵碼是雙位元組的,以 E0 開端,比方向左鍵為 E06B。所以鍵盤掃描碼是蠻複雜!

通碼 (Mark Code)
當按鍵被按下, Mark Code 會被鍵盤的編碼器 (Encoder) 送出,每一個鍵的 Mark Code 都不同。

斷碼 (Break Code)
當按鍵被釋放,鍵盤的編碼器 (Encoder) 便會送出 Break Code,一般的 Brak Code是由 2 Byte 組成,第一個通常是 F0,而第二個通常是和 Break Code相同,可以分別出那一個鍵被釋放,而擴展的 Break Code 會由 3 Byte 組成,頭 2 Byte E0 F0,最後會與 Mark Code 相同。

 Key
(Set 2)
Make Code
(Set 2)
Break Code
"A"
1C
F01C
"5"
2E
F02E
"F10"
09
F009
Right Arrow
E074
E0F074
Right "Ctrl"
E014
E0F014

新的 PC PS/2 鍵盤 Comment Set 也有所改動,舊的 XT 鍵盤在新的電腦上是使用不了,PS/2 鍵盤支持 host-to-keboard 及支持 scan code set 2 (一共有 3 scan code)
  • Scan Code 1 掃描碼集1 - 原始的XT掃描碼集,支持現在鍵盤 
  • Scan Code 2 掃描碼集2 - 支持現在鍵盤的掃描代碼集
  • Scan Code 3 掃描代碼集3 - 可支持PS/ 2掃描碼集 - 很少使用
Scan Code 1 掃描碼集1
KEY
MAKE
BREAK
-----
KEY
MAKE
BREAK
-----
KEY
MAKE
BREAK
A
1E
9E

9
0A
8A

[
1A
9A
B
30
B0

`
29
89

INSERT
E0,52
E0,D2
C
2E
AE

-
0C
8C

HOME
E0,47
E0,97
D
20
A0

=
0D
8D

PG UP
E0,49
E0,C9
E
12
92

\
2B
AB

DELETE
E0,53
E0,D3
F
21
A1

BKSP
0E
8E

END
E0,4F
E0,CF
G
22
A2

SPACE
39
B9

PG DN
E0,51
E0,D1
H
23
A3

TAB
0F
8F

U ARROW
E0,48
E0,C8
I
17
97

CAPS
3A
BA

L ARROW
E0,4B
E0,CB
J
24
A4

L SHFT
2A
AA

D ARROW
E0,50
E0,D0
K
25
A5

L CTRL
1D
9D

R ARROW
E0,4D
E0,CD
L
26
A6

L GUI
E0,5B
E0,DB

NUM
45
C5
M
32
B2

L ALT
38
B8

KP /
E0,35
E0,B5
N
31
B1

R SHFT
36
B6

KP *
37
B7
O
18
98

R CTRL
E0,1D
E0,9D

KP -
4A
CA
P
19
99

R GUI
E0,5C
E0,DC

KP +
4E
CE
Q
10
90

R ALT
E0,38
E0,B8

KP EN
E0,1C
E0,9C
R
13
93

APPS
E0,5D
E0,DD

KP .
53
D3
S
1F
9F

ENTER
1C
9C

KP 0
52
D2
T
14
94

ESC
01
81

KP 1
4F
CF
U
16
96

F1
3B
BB

KP 2
50
D0
V
2F
AF

F2
3C
BC

KP 3
51
D1
W
11
91

F3
3D
BD

KP 4
4B
CB
X
2D
AD

F4
3E
BE

KP 5
4C
CC
Y
15
95

F5
3F
BF

KP 6
4D
CD
Z
2C
AC

F6
40
C0

KP 7
47
C7
0
0B
8B

F7
41
C1

KP 8
48
C8
1
02
82

F8
42
C2

KP 9
49
C9
2
03
83

F9
43
C3

]
1B
9B
3
04
84

F10
44
C4

;
27
A7
4
05
85

F11
57
D7

'
28
A8
5
06
86

F12
58
D8

,
33
B3
6
07
87

PRNT
SCRN
E0,2A,
E0,37 
 E0,B7,
E0,AA

.
34
B4
7
08
88

SCROLL
46
C6

/
35
B5
8
09
89

PAUSE
E1,1D,45
E1,9D,C5
-NONE-





Scan Code 2 掃描碼集2
KEY
MAKE
BREAK
-----
KEY
MAKE
BREAK
-----
KEY
MAKE
BREAK
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,77,
E1,F0,14,
F0,77
-NONE-







Scan Code 3 掃描碼集3
KEY
MAKE
BREAK
-----
KEY
MAKE
BREAK
-----
KEY
MAKE
BREAK
A
1C
F0,1C

9
46
F0,46

[
54
F0,54
B
32
F0,32

`
0E
F0,0E

INSERT
67
F0,67
C
21
F0,21

-
4E
F0,4E

HOME
6E
F0,6E
D
23
F0,23

=
55
F0,55

PG UP
6F
F0,6F
E
24
F0,24

\
5C
F0,5C

DELETE
64
F0,64
F
2B
F0,2B

BKSP
66
F0,66

END
65
F0,65
G
34
F0,34

SPACE
29
F0,29

PG DN
6D
F0,6D
H
33
F0,33

TAB
0D
F0,0D

U ARROW
63
F0,63
I
43
F0,48

CAPS
14
F0,14

L ARROW
61
F0,61
J
3B
F0,3B

L SHFT
12
F0,12

D ARROW
60
F0,60
K
42
F0,42

L CTRL
11
F0,11

R ARROW
6A
F0,6A
L
4B
F0,4B

L WIN
8B
F0,8B

NUM
76
F0,76
M
3A
F0,3A

L ALT
19
F0,19

KP /
4A
F0,4A
N
31
F0,31

R SHFT
59
F0,59

KP *
7E
F0,7E
O
44
F0,44

R CTRL
58
F0,58

KP -
4E
F0,4E
P
4D
F0,4D

R WIN
8C
F0,8C

KP +
7C
F0,7C
Q
15
F0,15

R ALT
39
F0,39

KP EN
79
F0,79
R
2D
F0,2D

APPS
8D
F0,8D

KP .
71
F0,71
S
1B
F0,1B

ENTER
5A
F0,5A

KP 0
70
F0,70
T
2C
F0,2C

ESC
08
F0,08

KP 1
69
F0,69
U
3C
F0,3C

F1
07
F0,07

KP 2
72
F0,72
V
2A
F0,2A

F2
0F
F0,0F

KP 3
7A
F0,7A
W
1D
F0,1D

F3
17
F0,17

KP 4
6B
F0,6B
X
22
F0,22

F4
1F
F0,1F

KP 5
73
F0,73
Y
35
F0,35

F5
27
F0,27

KP 6
74
F0,74
Z
1A
F0,1A

F6
2F
F0,2F

KP 7
6C
F0,6C
0
45
F0,45

F7
37
F0,37

KP 8
75
F0,75
1
16
F0,16

F8
3F
F0,3F

KP 9
7D
F0,7D
2
1E
F0,1E

F9
47
F0,47

]
5B
F0,5B
3
26
F0,26

F10
4F
F0,4F

;
4C
F0,4C
4
25
F0,25

F11
56
F0,56

'
52
F0,52
5
2E
F0,2E

F12
5E
F0,5E

,
41
F0,41
6
36
F0,36

PRNT
SCRN
 57
F0,57

.
49
F0,49

3D
F0,3D

SCROLL
5F
F0,5F

/
4A
F0,4A
8
3E
F0,3E

PAUSE
62
F0,62





機打速率 (Typematic)
如果按了一個鍵,這個鍵的通碼被發送到電腦,當按下並按住這個鍵,則這個鍵就變成了機打
(Typematic) ,就意味著鍵盤將一直發送這個鍵的通碼,直到它被釋放或者其他鍵被按下,這裏有兩個重要的機打參數,延時是第一個和第二個a 之間的延遲;機打速率是在機打延時後每秒有多少字元出現你的螢幕上。機打延時的範圍可以從 0.25 秒到 1.00 秒,機打速率的範圍可以從 2.0cps (字元每秒) 30.0cps,但可以用Set Typematic Rate/Delay 0xF3 命令來改變機打速率和延時。

自身基本正確性檢測 (BAT = Basic Assurance Test)
在接上電源或軟體重置 (Reset 0xFF) 命令後,鍵盤會執行自檢診斷叫做 BAT (Basic Assurance Test) ,當進入 BAT 時,鍵盤點亮三個 LED 指示器,並在完成BAT 後關閉,此時BAT 完成,會送出代碼0xAA (BAT 成功) 0xFC (BAT 錯誤) 到主機,BAT會在 500750毫秒上電後必須發送BAT完成代碼,並載入以下的參數。

  • 機打延後 (Typematic Delay) 500 ms
  • 機打速率 (Typematic Rate)10.9 cps
  • *Scan code set 2
  • *Set all keys typematic/make/break