回归!
简报
键盘和鼠标是现在绝大部分人使用电脑的标配物件。它们有发光的,有花花绿绿的,有长尾巴的,有带电池的。但又有谁人记得,曾经那六孔的插口?作为本专栏的第一篇文章,就让笔者带领大家来认识计算机与键盘、鼠标进行通信的这一远古协议——SP/2。
简介
1987年,大家熟知的IBM公司推出了一款用于键盘与主机进行通信的接口标准——SP2。PS2接口一共有六根引脚,但其中只有四根引脚是有意义的:Clock(时钟),Data(数据),电源,接地。值得注意的是,其中的Clock与Data是双向的引脚。因此,PS/2协议是一种双向同步串行通信协议。它的工作方式是:通信的两端通过Clock同步,并通过Data交换数据。当任何一方试图抑制另外一方的通信时,只需要时钟引脚拉低即可。由此可见,PS/2协议适合于在两个设备之间进行通信。但是通过一定的方式对其进行变形,亦可以适应在多个设备之间进行通信。这种例子笔者将会在遥远的将来为大家进行呈现(手动狗头)。大多数PS/2设备工作在10~20kHz之间。
数据帧
PS/2的每一个数据帧都包含11~12位。说明如下:
这是数据帧:ABCDEFGHIJKL
- A:数据起始位,总是逻辑0(低电平);
- B~I:数据位(共八位),低位在前;
- J:奇偶校验位,校验方式为奇校验;
- K:停止位,总是逻辑1(高电平);
- L:应答位,仅用于主机对设备进行通信的场合中。
设备产生时钟信号,主机则是通过该信号来对设备数据进行读取。
代码
module PS2 (
input clk,
input rst,
input PS2D,
input PS2C,
output [15:0] key
);
reg ps2c; //clock transfer to slave
reg ps2d; //data ready to slave
reg [7:0] ps2c_fliter;
reg [7:0] ps2d_fliter;
reg [10:0] shift1;
reg [10:0] shift2;
assign key = { shift2[8:1], shift1[8:1] };
always@( posedge clk or posedge rst )
begin
if( rst )
begin
ps2c <= 1;
ps2d <= 1;
ps2c_fliter <= 0;
ps2d_fliter <= 0;
end
else begin
ps2c_fliter[7] <= PS2C;
ps2d_fliter[7] <= PS2D;
ps2c_fliter[6:0]<= ps2c_fliter[7:1];
ps2d_fliter[6:0]<= ps2d_fliter[7:1];
if( ps2c_fliter == 8'b11111111 )
ps2c <= 1;
else if( ps2c_fliter == 8'b00000000 )
ps2c <= 0;
else
ps2c <= ps2c;
if( ps2d_fliter == 8'b11111111 )
ps2d <= 1;
else if( ps2d_fliter == 8'b00000000 )
ps2d <= 0;
else
ps2d <= ps2d;
end
end
always@( negedge ps2c or posedge rst )
begin
if ( rst )
begin
shift1 <= 0;
shift2 <= 0;
end
else
begin
shift1 <= { ps2d, shift1[10:1] };
shift2 <= { shift1[0, shift2[10:1]] };
end
end
endmodule
仿真
module PS2_SIM();
reg clk;
reg rst;
reg PS2D;
reg PS2C;
wire [15:0] key;
PS2 U1(clk, rst, PS2D, PS2C, key);
initial begin
clk = 0;
rst = 1;
PS2D = 0;
PS2C = 0;
#500;
PS2D = 0;
rst = 0;
#1000;
PS2D = 1;
#1000;
PS2D = 0;
#1000;
PS2D = 1;
#1000;
PS2D = 1;
#1000;
PS2D = 0;
#1000;
PS2D = 1;
#1000;
PS2D = 1;
#1000;
PS2D = 1;
#1000;
PS2D = 0;
#1000;
PS2D = 1;
end
always #25 clk = ~clk; //system clock
always #500 PS2C = ~PS2C; //device's clock
endmodule
根据波形我们可以看出,代码可以正常进行通信,实现PS/2通信协议功能。
总结
半年未见,自己曾经写过的几篇小文章竟受到不少人的喜爱,这是我所没有想到的。作为一个真心希望能够将自己的知识开源给大家的大学生,当看到自己复刻硬件的代码出乎意料的被人收藏之后,坚持下去的决心更加坚定。所以开出这一专栏,为资源的共享提供一份力量。