【FPGA】人人都能看懂简化按键消抖方式

按键原理

图1.1(按键电路简化图)

        我们可以看到图1.1中的电路包含四个按键,四个按键的电路结构完全相同,我们拿其中一个进行分析。以KYE1为例,在按键KEY1按下前,KEY1部分电路输出的电压约为电源电压,即输出高电平,但是当按键KEY1按下后,电源和接地GND串联,此时KEY1输出的电压接近接地,即输出低电平。总结来说,就是按键按下前按键的输出口输出高电平,按键按下后按键的输出口输出低电平(部分芯片设计会和该电路相反,按下输出高电平)。

消抖原理

图2.1(按键按下时输出电平的变化)

  • 抖动的产生 :通常的按键所用的开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因此在按键按下和松开时按键的输出电平会有一段时间的抖动,但是在按下和松开之间会保持一段时间的低电平,即会出现类似图2.1的电平变化。

  • 消除抖动的措施:在按键按下的时刻,会出现波形的抖动,在之后的一段时间内,才会出现平稳的波形。在通常情况下,我们按一下按键,输出电平会有20ms以上的稳定低电平,所以,如果我们可以检测到一段时间持续20ms及以上的低电平,便可以说明按键被按下了。那么我们现在只需要用代码完成了该监控即可。

代码实现

单一按键消抖

        我们以时钟为25MHz的开发板为例,那么检测20ms便可转化为检测500_000个时钟上升沿,为此我们可以建立一个寄存器clkn,那么我们如何检测持续的电平呢。其实很简单,我们先给clkn赋初值为0,然后一直检测按键的电平输出,如果检测到低电平,那么我们便让clkn加一,但是一旦检测到高电平,我们就让clkn归零,那么clkn想加到500_000,就要持续接收到500_000低电平,其中不可以出现一次高电平,那么当clkn加到500_000后呢,当clkn加到500_000后,如果我们还检测到低电平,我们便让clkn一直保持500_001,但是如果有高电平,便让clkn归零。这样当按键输出一个20ms以上的稳定低电平时,clkn便会在一个时钟周期内输出一次500_000,所以我们检测到clkn==500_000时,即按键真正被按下。具体代码如下:

module debounce(clk,key,key_state);

input  clk;//时钟输入
input  key;//按键信号输入
output wire key_state;//按键状态输出

 reg [18:0] clkn=19'd0;//20ms计时寄存器

 always@(posedge clk)begin
   if(!key)begin//检测到低电平
      if(clkn>=19'd500_001)begin//clkn已经记到了500_000
	     clkn<=clkn;//让clkn一直保持500_001
	  end else begin//clkn还未记到500_000
         clkn<=clkn+19'd1;//让clkn加一
	  end
   end else begin//按键输出为低电平
      clkn<=19'd0;//将clkn归零
   end
 end
 
assign key_state=(clkn==19'd500_000);//实时检测clkn是否等于500_000,若等于便真正被按下,输出1


endmodule

多个按键同时消抖 

       其实多个按键的消抖和单个按键的完全相同,我们可以在图1.1中看出 ,在四个按键都为按下时,四个输出都为高电平,即1111,但是但其中一个按键被按下时,输出便不为1111了,那么我们将1111视为高电平,其余状态都视为低电平,那么便和单个按键完全相同了。但是我们要多一道工序,即在clkn==500_000时特别检测一下四个按键的输出,将其视为按键是否被按下。代码如下:

module debounce(clk,key,key_state);

input  clk;//时钟
input  [3:0] key;//四个按键状态输入
output wire [3:0] key_state;//四个按键状态,为1被按下

 reg [18:0] clkn=19'd0;

 always@(posedge clk)begin//逻辑和上一部分代码相同
  if(key!=4'b1111)begin//按键状态不为1111,说明有按键处于按下状态
    if(clkn>=19'd500_001)begin
	   clkn<=clkn;
	 end else begin
      clkn<=clkn+19'd1;
	 end
  end else begin
    clkn<=19'd0;
  end
 end
 
assign key_state=(clkn==500_000)*(~key);
//当clkn==500_000时检测一下按键,看看是哪个按键被按下了,因为低电平为按下状态,所以我们对key取非 


endmodule

小结

希望可以帮到一些正在学习消抖的人。

  • 30
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欲翾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值