[资料分享] FPGA按键消抖的方法

k331922164   2013-11-26 14:33 楼主
给大家分享一些简单的代码。
很多FPGA初学者,不会做按键消抖,可能他们会写出这样的代码
always(*)
    if(!key)
    begin
    //该按键的功能
    end
意思是把按键当时钟来用,这样即没有消抖,也没有做同步。
我目前用的这个是计数消抖,设置一个计数器来消抖(消抖时间可任意设定),同时,产生一个跟时钟同步的单脉冲。
用计数器消抖很好理解,但是为什么要产生一个跟时钟同步的单脉冲呢?
这就是FPGA设计原则里面的同步原则,意思是每个模块都用同一个时钟(很多时候这个时钟是由PLL产生的),
这样的话,在按键消抖后面紧跟的模块就可以这样来处理这个单脉冲。
always(posedge clk)//clk是全局时钟,这个时钟跟消抖模块的时钟是相同的。
       if(key)    //key是消抖后,出来的单脉冲,高电平有效。
       begin
       //该按键的功能。
       end

这个方法同样适合于单片机的按键消抖。
比如用C51写这样的代码:
     if(!key)
     {
      delayms(10);
          if(!key)
          { //该按键的功能
          }
     }
很多教材都写这样的例子出来,但是它会出现一个问题,就是如果你一直按住这个按键,MCU就会不断地进入这个函数,就是说代码的容错性不好。
uchar key_time=0;            //“键龄”,这是全局变量。
void key_scan(void)
{
        if(!key)
        {
                if(key_time<8)        //这个8是消抖时间,虽然自己设定
                        key_time++;           //捕捉“键龄”
                if(key_time==1)         
                {
                        if(!key)        
                        {
                         //该按键的功能
                        }        
                }
        }
        else        
                key_time=0;        
}
具体的理论可以参考,周航慈的单片机教材。
这样的话,单片机和FPGA就可以触类旁通了。如有问题可以加Q:331922164
PS:附上了参考文献、VHDL和verilog两种代码,使用这些代码之前,要先搞清楚按键按下是高电平还是低电平,出来的单脉冲是高电平还是低电平。
因为quartus9.0不支持中文,所以我写的代码全部都用英文注解。
FPGA开发中按键消抖与单脉冲发生器电路.pdf (208.37 KB)
(下载次数: 122, 2013-11-27 10:27 上传)


键控单脉冲发生器verilog.txt (796 Bytes)
(下载次数: 64, 2013-11-26 14:33 上传)

键控单脉冲发生器VHDL.txt (1.39 KB)
(下载次数: 44, 2013-11-26 14:33 上传)


[ 本帖最后由 k331922164 于 2013-11-27 10:27 编辑 ]

回复评论 (1)

多谢分享。

[ 本帖最后由 lcofjp 于 2013-11-26 15:51 编辑 ]
点赞  2013-11-26 15:46
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复