您的位置:首页 > 其它

FPGA 实现PS/2键盘控制LED

2016-11-12 17:20 302 查看
今天发现开发板上有PS/2接口,所以就打算试试是不是好的。

在这里简单说一下PS/2的基本知识,增加了解。


如图即为PS/2接口的公头,是一种6针的接口。包括数据(1脚)、时钟(5脚)、电源(+5V)(4脚)、地(3脚),以及预留了2个针脚。

它名字的来历是最早出现在IBM的PS/2的机子上,故之。它是一种鼠标和键盘的专用接口,输速率比COM接口稍快一些,而且是ATX主板的标准接口,是目前应用最为广泛的键盘接口之一。

键盘和鼠标都可以使用PS/2接口,但是按照PC’99颜色规范,鼠标通常占用浅绿色接口,键盘占用紫色接口。尽管键盘鼠标对于的ps/2针脚一样,但是这两个接口还是不能混插,这是由它们在电脑内部不同的信号定义所决定的。

接下来说说键盘编码,普通计算机都是采用编码键盘,编码方式分为第一套、第二套、第三套编码,民用都是第二套。具体编码细则可以自行百度。在这里我用到了Z键、Y键和Ctrl键,他们对于的编码分别是0x1A、0x35、0x14。

然后是PS/2的时序,具体如下:起始位、数据0、数据1、数据2、数据3。。。。数据7、校验位、停止位。(这和串口很相似),在PS/2时钟下降沿采集数据。

接下来直接上代码

module ps2

(

/*系统信号[b]*******[/b]/

input clk,

input rst_n,

/[b]**ps2信号************[/b]/

input data_in,

input clk_in,

/*测试信号[b]*******[/b]/

output reg done_flag,

output reg[3:0] led

);

/[b]************************[/b]/

reg r1,r2;

reg[7:0] ps2_data;

reg[4:0] i;//状态

wire ps2_clk_n;

/[b]************************[/b]/

//clk_in下降沿检测

/[b]*************************[/b]/

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

begin

r1 <= 1’b0;

r2 <= 1’b0;

end
else

begin

r1 <= clk_in;

r2 <= r1;

end
end
assign ps2_clk_n = r2&(!r1);

/[b]***************************[/b]/

//获取ps2键值

/[b]***************************[/b]/

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

begin

i<= ‘d0;

done_flag <= 1’b0;

ps2_data <= 8’b0;

end
else case(i)

‘d0:

begin

if(ps2_clk_n)

i <= i + 1’b1;

else i <= i;

end
‘d1,’d2,’d3,’d4,’d5,’d6,’d7,’d8:

begin

if(ps2_clk_n)

begin

i <= i + 1’b1;

ps2_data[i-1] <= data_in;

end
else i <= i;

end
‘d9,’d10:

begin

if(ps2_clk_n)

i <= i + 1’b1;

else

i <= i;

end
‘d11://判断通断码,为F0则是断码

begin

if(ps2_data==8’hF0)

i <= ‘d12;

else

i <= ‘d23;

end
‘d12,’d13,’d14,’d15,’d16,’d17,’d18,’d19,’d20,’d21,’d22:

begin

if(ps2_clk_n)

i <= i + 1’b1;

else

i <= i;

end
‘d23:

begin

i <= i + 1’b1;

done_flag <= 1’b1;

end
‘d24:

begin

i <= ‘d0;

done_flag <= 1’b0;

end
default:i <= ‘d0;

endcase

end


/[b]*****************************[/b]/

//输出控制led,Z键左移;Y键右移;CTRL切换

/[b]****************************[/b]/

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

led <= 4’b1110;

else if(done_flag)

case(ps2_data)

8’h1a://字母z

begin

led <= {led[2:0],led[3]};//左移

end
8’h35://字母y

begin

led <= {led[0],led[3:1]};//右移

end
8’h14:

begin

led <= {led[0],led[1],led[2],led[3]};

end
default:;

endcase

end
endmodule

首先进行PS/2时钟下降沿检测,然后接受键盘过来的键值(即按键的编码,比如Z键接收到的就是0x1A),通过对按键编码的判断来控制LED的左右移动和切换。

这是最简单的PS/2操作,如果要做更复杂处理,同样可以按照这个思路扩展,以支持不同操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  FPGA PS-2 LED控制