打印

FPGA按键防抖动,最精简的写法只有10行

[复制链接]
楼主: lxAPP
手机看帖
扫描二维码
随时随地手机跟帖
61
Chash| | 2016-9-20 14:21 | 只看该作者 回帖奖励 |倒序浏览
h20030711 发表于 2012-10-13 23:12
楼主的写法我个人觉得有如下问题
     1、key_reg1这信号有可以出现亚稳态
     2、有可能把一个小脉冲的抖 ...

说的很好啊

使用特权

评论回复
62
dan_xb| | 2016-9-22 14:42 | 只看该作者
本帖最后由 dan_xb 于 2016-9-22 14:43 编辑

这个是我一直应用的防抖代码,很稳定:

module key (
    input   clk_50,     //50MHz
    input   key_in,     //Key High input
    output trig_out    //Paulse output
    );

    reg [19:0] counter; //20ms@50MHz = 1000000 cycle = 0xF4240

    always @(posedge clk_50)
    begin
        if(key_in == 0)
            counter <= 0;
        else if(counter < 20'hF5000)
            counter <= counter + 1;
    end

    assign trig_out = (counter == 20'hF4240 )? 1 : 0;

endmodule


解释一下,计数器计数时间为20ms
当Key=0时,计数器复位
当Key=1时,计数器开始计数
当计数到20ms时,计数停止,脉冲发出
只有当Key=0时,计数器才回复位,这是为了防止一直按着连发脉冲
如果计数中途Key掉下去,那么计数器复位,重新开始计数,防抖

使用特权

评论回复
63
avkmonkey| | 2016-9-28 08:53 | 只看该作者
本帖最后由 avkmonkey 于 2016-9-28 09:09 编辑
count2<=count2+1;
    if(count2==500000)

这两句一看就是浓浓的C语言味儿啊。Verilog语言是硬件描述语言,不适合那么写
我按照楼主的思路改写一下(思路不变,代码结构修改,更适合综合)
reg key_reg1,key_reg2;
wire key_out;
reg [17:0]count2;
wire clk_100;//通过计数器衍生出的100Hz时钟(楼主本来的代码是每隔10ms读一次按键的)(其实不到一点点,大约是95.36Hz)
always   @   (posedge clk)//clk 50M
count2<=count2+1'b1;
assign clk_10=count2[17];
always   @   (posedge clk_100)//clk 95Hz
begin
key_reg1<=key1;
key_reg2<=key_reg1;
end
assign key_out=key_reg2&(!key_reg1);



  

使用特权

评论回复
64
avkmonkey| | 2016-9-28 09:10 | 只看该作者
本帖最后由 avkmonkey 于 2016-9-28 09:16 编辑
<span id="kM0.8008464885405466">@</span>

  求救 代码模式每次输入 @ 就出现如上文字,求如何输入一个纯文本的@

使用特权

评论回复
65
elevent| | 2016-9-28 13:20 | 只看该作者
实验了之后 ,效果怎么样?

使用特权

评论回复
66
DreadBoy| | 2016-11-7 14:21 | 只看该作者
hawksabre 发表于 2012-10-15 18:07
其实使用软件延时消抖的思想本质上就是滤波   将由于人手按键造成的短暂接触产生的电流滤除掉   最可靠的方 ...

FPGA写出来的代码难倒不是硬件吗?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则