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]。
模块代码
- module detect_module
- (
- input clk,
- input rst,
- input ps_clk_pin_in,
- output h2l_sig
- );
-
- reg h2l_f1;
- reg h2l_f2;
- always @ (posedge clk or negedge rst)
- if (!rst)
- begin
- h2l_f1 <=1'b1;
- h2l_f2 <=1'b1;
- end
- else
- begin
- h2l_f1 <= ps_clk_pin_in;
- h2l_f2 <= h2l_f1;
- end
-
- assign h2l_sig = h2l_f2 && (!h2l_f1);
- endmodule
- module ps_decode_module
- (
- input clk,
- input rst,
- input h2l_sig,
- input ps_data_pin_in,
- output [7:0] ps_data,
- output ps_done_sig
- );
-
- reg [7:0] rdata;
- reg [4:0] i;
- reg isdone;
-
- always @ (posedge clk or negedge rst)
- if (!rst)
- begin
- i <= 5'd0;
- rdata <= 8'd0;
- isdone <=1'b0;
- end
- else
- case (i)
- 5'd0 :
- if(h2l_sig) i<=i+1'b1;
- 5'd1,5'd2,5'd3,5'd4,5'd5,5'd6,5'd7,5'd8 :
- if(h2l_sig) begin i<=i+1'b1;rdata[i-1]<=ps_data_pin_in;end
- 5'd9,5'd10:
- if(h2l_sig) i<=i+1'b1;
- 5'd11:
- if (rdata == 8'hf0) i<=5'd12;
- else i<=5'd23;
- 5'd12,5'd13,5'd14,5'd15,5'd16,5'd17,5'd18,5'd19,5'd20,5'd21,5'd22:
- if (h2l_sig) i<=i+1'b1;
- 5'd23:
- begin i<=5'd0;isdone<=1'b1;end
- endcase
-
- assign ps_data =rdata;
- assign ps_done_sig = isdone;
- endmodule