一、 概述
PS2接口主要用到三根线,GROUND,DATA,CLOCK。DATA信号在下降沿的时候有效,CLOCK频率很低,大约10K。PS2一帧是11位:BIT0为开始位,BIT1-BIT8为数据位,BIT9为校验位,BIT10为结束位。一般只需考虑BIT1-BIT8,其余位可忽略。大多数民用编码键盘采用第二套编码方案。键盘编码有通码(按下)和断码(松开)之分。通码为8位数据,断码只是在通码数据前加0XF0。
二、 模块分析
如图所示分为两块:电平检测模块,解码模块。
电平检测模块检测PS2的CLOCK的下降沿,产生一个检测信号高脉冲供解码模块读取。解码模块读取到检测模块的高脉冲后读取PS2的DATA电平,检测完一桢数据产生一个高脉冲并将结果送到ps_data[7:0]。
三、模块代码
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1
module
detect_module
2 (
3 input clk,
4 input rst,
5 input ps_clk_pin_in,
6 output h2l_sig
7 );
8
9 reg h2l_f1;
10 reg h2l_f2;
11 always @ ( posedge clk or negedge rst)
12 if ( ! rst)
13 begin
14 h2l_f1 <= 1 ' b1;
15 h2l_f2 <= 1 ' b1;
16 end
17 else
18 begin
19 h2l_f1 <= ps_clk_pin_in;
20 h2l_f2 <= h2l_f1;
21 end
22
23 assign h2l_sig = h2l_f2 && ( ! h2l_f1);
24 endmodule
2 (
3 input clk,
4 input rst,
5 input ps_clk_pin_in,
6 output h2l_sig
7 );
8
9 reg h2l_f1;
10 reg h2l_f2;
11 always @ ( posedge clk or negedge rst)
12 if ( ! rst)
13 begin
14 h2l_f1 <= 1 ' b1;
15 h2l_f2 <= 1 ' b1;
16 end
17 else
18 begin
19 h2l_f1 <= ps_clk_pin_in;
20 h2l_f2 <= h2l_f1;
21 end
22
23 assign h2l_sig = h2l_f2 && ( ! h2l_f1);
24 endmodule
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1
module
ps_decode_module
2 (
3 input clk,
4 input rst,
5 input h2l_sig,
6 input ps_data_pin_in,
7 output [ 7 : 0 ] ps_data,
8 output ps_done_sig
9 );
10
11 reg [ 7 : 0 ] rdata;
12 reg [ 4 : 0 ] i;
13 reg isdone;
14
15 always @ ( posedge clk or negedge rst)
16 if ( ! rst)
17 begin
18 i <= 5 ' d0;
19 rdata <= 8 ' d0;
20 isdone <= 1 ' b0;
21 end
22 else
23 case (i)
24 5 ' d0 :
25 if (h2l_sig) i <= i + 1 ' b1;
26 5 ' d1,5 ' d2, 5 ' d3,5 ' d4, 5 ' d5,5 ' d6, 5 ' d7,5 ' d8 :
27 if (h2l_sig) begin i <= i + 1 ' b1;rdata[i-1]<=ps_data_pin_in;end
28 5 ' d9,5 ' d10:
29 if (h2l_sig) i <= i + 1 ' b1;
30 5 ' d11:
31 if (rdata == 8 ' hf0) i<=5 ' d12;
32 else i <= 5 ' d23;
33 5 ' d12,5 ' d13, 5 ' d14,5 ' d15, 5 ' d16,5 ' d17, 5 ' d18,5 ' d19, 5 ' d20,5 ' d21, 5 ' d22:
34 if (h2l_sig) i <= i + 1 ' b1;
35 5 ' d23:
36 begin i <= 5 ' d0;isdone<=1 ' b1; end
37 endcase
38
39 assign ps_data = rdata;
40 assign ps_done_sig = isdone;
41 endmodule
2 (
3 input clk,
4 input rst,
5 input h2l_sig,
6 input ps_data_pin_in,
7 output [ 7 : 0 ] ps_data,
8 output ps_done_sig
9 );
10
11 reg [ 7 : 0 ] rdata;
12 reg [ 4 : 0 ] i;
13 reg isdone;
14
15 always @ ( posedge clk or negedge rst)
16 if ( ! rst)
17 begin
18 i <= 5 ' d0;
19 rdata <= 8 ' d0;
20 isdone <= 1 ' b0;
21 end
22 else
23 case (i)
24 5 ' d0 :
25 if (h2l_sig) i <= i + 1 ' b1;
26 5 ' d1,5 ' d2, 5 ' d3,5 ' d4, 5 ' d5,5 ' d6, 5 ' d7,5 ' d8 :
27 if (h2l_sig) begin i <= i + 1 ' b1;rdata[i-1]<=ps_data_pin_in;end
28 5 ' d9,5 ' d10:
29 if (h2l_sig) i <= i + 1 ' b1;
30 5 ' d11:
31 if (rdata == 8 ' hf0) i<=5 ' d12;
32 else i <= 5 ' d23;
33 5 ' d12,5 ' d13, 5 ' d14,5 ' d15, 5 ' d16,5 ' d17, 5 ' d18,5 ' d19, 5 ' d20,5 ' d21, 5 ' d22:
34 if (h2l_sig) i <= i + 1 ' b1;
35 5 ' d23:
36 begin i <= 5 ' d0;isdone<=1 ' b1; end
37 endcase
38
39 assign ps_data = rdata;
40 assign ps_done_sig = isdone;
41 endmodule