0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FPGA基础设计_PS2键盘控制及短按、长按

Hx 作者:工程师陈翠 2018-06-26 10:06 次阅读

PS2键盘也是一个经典的实验,可能很多人接触如何对通信协议、时序编程就是从这个实验开始学习的。USB键盘已经很普及,现在市场上还是有一些USB转PS2的转接头,还有一些转换芯片。这个实验虽然简单,不过不知道您有考虑过单按一次输出一个有效脉冲、短按、长按等这些是如何实现的么?这就涉及到一些时钟、边沿检测等设计问题。

PS2协议实现

我们见到的PS2的接口电路应该都是这样的:

FPGA基础设计_PS2键盘控制及短按、长按

一根时钟线、一根数据线完成通信,PS2通信的帧格式如下所示,时钟的下降沿数据有效:

FPGA基础设计_PS2键盘控制及短按、长按

按键在被按下时,会发送一个字节,这个码就是通码;按键在释放时,会发送两个字节,这个码就做断码(当然也有例外)。每一个按键都有唯一的通码和断码,据此进行判断按下的是哪个键,从而执行对应的功能。如一部分按键的通码和断码如下所示:

FPGA基础设计_PS2键盘控制及短按、长按

可以看出断码其实就是在通码前加了一个F0,比如A的通码是1C,则它的断码是F01C。另外一些特殊功能的按键,在通码和断码前都会加个E0。PS2解码的代码如下所示:

//-----------------ps2_clk下降沿捕获--------------------

//clk相当于中间采样点的作用,第一个下降沿到来说明起始位开始

reg ps2_clk0, ps2_clk1, ps2_clk2;//缓冲寄存器

wire ps2_clk_neg; //1表示检测到下降沿

reg ps2_state;

always @ (posedge clk or negedge rst_n)

if (!rst_n)

{ps2_clk0, ps2_clk1, ps2_clk2} 《= 3‘d0;

else

begin

ps2_clk0 《= ps2_clk;

ps2_clk1 《= ps2_clk0;

ps2_clk2 《= ps2_clk1;

end

assign ps2_clk_neg = ~ps2_clk1 & ps2_clk2;

//----------------------数据接收----------------------------

reg [3:0]num; //移位控制

reg [7:0]data_temp;//当前接收的数据

always @ (posedge clk or negedge rst_n)

if (!rst_n)

begin

num 《= 4’d0;

data_temp 《= 8‘d0;

end

else if (ps2_clk_neg)

begin

if (num == 0) num 《= num + 1’b1;//跳过起始位

else if (num 《= 8) //数据位赋值

begin

num 《= num + 1‘b1;

data_temp[num-1] 《= ps2_data;

end

else if (num == 9) num 《= num + 1’b1;//跳过校验位

else num 《= 4‘d0; //清0

end

//--------------------按键按下/松开检测-------------------------

reg ps2_loosen;//1表示按键松开

reg [7:0]ps2_byte;//ps2一个字节数据

always @ (posedge clk or negedge rst_n)

if (!rst_n)

begin

ps2_state 《= 1’b0;

ps2_loosen《= 1‘b0;

end

//每接收完一个数据就进行按键检测

else if (num == 4’d10)

if (data_temp == 8‘hf0) ps2_loosen 《= 1’b1;//断码标识符

else

begin

if (ps2_loosen) //1表示按键松开,下一次接收数据后清0

begin

ps2_state 《= 1‘b0;

ps2_loosen《= 1’b0;

end

else //loosen变0后的下一个数据表示按键被按下

begin

ps2_state 《= 1‘b1;

ps2_byte 《= data_temp; //把读取到的值赋给ps2_out

end

end

由于PS2通信是在PS2时钟的下降沿有效,因此第一个always使用三个寄存器对PS2的CLK做一个下降沿捕获,并输出一个ps2下降沿的有效信号

捕捉到了ps2时钟的下降沿,第二个always便是使用一个计数器在下降沿信号有效时读取并存储数据线上的数据。计数器的值正好对应着一帧中的通信格式,因此在计数器为0时为通信的起始位,1~8为数据位,9为校验位,10为停止位。计数器处于数据位期间内,将数据位依次存储到一个寄存器中。

得到了数据,第三个always进行的便是通信数据的判断,这里进行的是断码的判断。每当完成一帧通信时,即计数器计数到10(停止位)时,便对通信数据做判断,如果是f0,则为断码的第一个码,那么下一次通信来的必然是按键的键值码。因此将收到f0后的下一个通信数据作为按键的键值码存到一个寄存器中,同时将按键有效信号ps2_state置高,表示按下一次按键。

这样便完成了PS2的通信。

PS2按键判断

设想一个问题,假设两个模块,他们的时钟是一样的,模块一用来进行PS2键盘检测,模块二根据按键按下的有效信号来决定是否执行对应的操作。如果模块二采用同步设计,即由时钟来控制(通常也是这么做的),如果模块一输出的按键有效信号不能做到恰好只维持一个时钟的脉冲宽度,那么模块二就会多次检测到按键按下并触发多次对应的控制操作。这也是新手常遇到的问题。

如果模块一的时钟是模块二时钟的两倍呢?如果这个时候模块一输出的按键有效信号仍然只有一个脉冲,那么模块二就会恰好检测不到。因此模块一输出的按键有效信号应该维持两个时钟的脉冲宽度。而这可以用一个计数器来控制。

我这里举一个只输出一个时钟长度的有效信号的例子:

reg ps2state_reg;

wire flag;

always @ (posedge clk)

ps2state_reg 《= ps2_state;

assign flag = (ps2state_reg) & (~ps2_state);

//---------------------根据键盘扫描码输出按键有效信号?--------------------------

always @ (posedge clk or negedge rst_n)

if (!rst_n)

begin left 《= 0; right 《= 0; up 《= 0; down 《= 0; end

else if (flag) //每当松开按键时才进行输出

case (ps2_byte)

8’h1C: begin left 《= 1; end //a

8‘h23: begin right 《= 1; end //d

8’h1D: begin up 《= 1; end //w

8‘h1B: begin down 《= 1; end //s

default: begin left 《= 0; right 《= 0; up 《= 0; down 《= 0; end

endcase

else if (left) left 《= 0; //有按键有效信号输出一个脉冲后马上清零

else if (right) right 《= 0;

else if (up) up 《= 0;

else if (down) down 《= 0;

首先对按键状态ps2_state做一级寄存,然后进行边沿检测,那么在alwasy中检测到边沿有效时则表示按键按下了一次,根据键码将相应的按键有效信号置1。而当检测到有效信号为高时,在下一个时钟马上就拉低,从而实现只输出一个时钟的脉冲宽度。这样就不会引起错误的检测到多次按下的问题。

我们在玩游戏的时候还会碰到这种情况,需要长按一个键几秒钟才会有相应的反应,其实解决了上面的问题后我们对这种短按、长按的控制思路就很清楚了。简而言之,在模块一中使用计数器来控制输出的有效信号的时钟长度,在模块二中使用相同的计数器对这个有效信号的时钟长度进行判断,进而识别这个键到底是短按还是长按,以选择不同的操作。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1598

    文章

    21265

    浏览量

    592747
收藏 人收藏

    评论

    相关推荐

    简单解码PS2键盘

    简单的解码PS2键盘的W/A/S/D四个按键,用来控制H桥,从而控制小车行进的方向
    发表于 07-08 19:02

    PS2键盘时钟与系统时钟

    请问一下,在编写ps2键盘程序时,键盘的时钟和系统时钟是什么关系????
    发表于 07-26 10:22

    小梅哥和你一起深入学习FPGAPS2键盘驱动

    本帖最后由 小梅哥 于 2014-12-25 21:04 编辑 [tr][td]小梅哥和你一起深入学习FPGAPS2键盘驱动 在我们的电子系统中,当需要用到大量的按键输入时,普通的独立按键
    发表于 12-25 20:56

    ps2键盘 协议

    我想请教下ps2协议如果键盘一直不按的话 ps2协议中时钟一直是高电平吗
    发表于 01-27 10:25

    ps2键盘控制问题,完整程序附上

    PS2键盘控制文件3个,在黑金板子上运行,本意是按一下A后4个LED灯亮灭,但是实际情况是按了CAPS LOCK闪烁,右边的SHIFT闪烁,其他按键没反映,请教高手是什么原因,谢谢
    发表于 04-02 11:18

    ps2键盘控制问题,完整程序附上

    PS2键盘控制文件3个,在板子上运行,本意是按一下A后4个LED灯亮灭,但是实际情况是按了CAPS LOCK闪烁,右边的SHIFT闪烁,其他按键没反映,请教高手是什么原因,谢谢
    发表于 04-02 19:42

    【小梅哥FPGA进阶教程】第六章 PS2键盘驱动设计与验证

    的信息。在pc机上,我们经常使用104键的键盘,这种键盘与pc机的接口,可分为USB接口和PS2接口,我们FPGA要实现USB接口比较困难,因为USB的接口线路,不是标准的TTL电平,
    发表于 02-04 23:01

    PS2键盘时钟无按键动作产生问题

    今天学习FPGAPS2键盘,但是发现一个问题就是PS2键盘时钟插在开发板上上电就自己产生时钟,还是在没有按键动作的情况下,这是为啥?
    发表于 10-16 21:33

    使用FPGA驱动采用PS2接口的pc机键盘

    小梅哥和你一起深入学习FPGAPS2键盘驱动 在我们的电子系统中,当需要用到大量的按键输入时,普通的独立按键和矩阵键盘已经无法满足我们的输入需求,这个时候,我们需要使用一种功能更加强
    发表于 04-28 06:06

    USB1口数据线上的PS2键盘有问题该怎么解决

    在A40i核心板的USB1口的数据线上,通过WIT122U芯片实现一个PS2接口。在该PS2接口上接PS2键盘,发现按下键盘不松手的情况下,
    发表于 12-31 06:08

    基于FPGAPS2键盘鼠标控制电子琴

    基于 FPGAPS2键盘鼠标控制电子琴论文
    发表于 10-29 17:18 31次下载

    PS2键盘控制程序

    Xilinx FPGA工程例子源码:PS2键盘控制程序
    发表于 06-07 14:45 16次下载

    PS2键盘转USB键盘源码

    PS2键盘转USB键盘
    发表于 05-04 11:52 11次下载

    MCU驱动PS2键盘

    MCU驱动PS2键盘
    发表于 10-27 14:39 17次下载
    MCU驱动<b class='flag-5'>PS2</b><b class='flag-5'>键盘</b>

    FPGA DIY开发板的PS2键盘控制

    hahaolinux 的PS2键盘控制
    的头像 发表于 06-22 00:29 4067次阅读