按键消抖模块设计实现

    本文主要阐述在FPGA中如何针对按键的抖动进行按键消抖模块的设计。

 (基于Altera EP4CE10 征途Pro开发板)

一.按键的原理

  按键是最为常见的电子元器件之一,在电子设计中应用广泛。在FPGA的实验工程中,我们可以使用其作为系统复位信号或者控制信号的外部输入。开发板上使用的机械按键也是按键的一种,特点是:接触电阻小 ,手感好,按键按下或弹起时有“滴答”清脆声;但由于其构造和原理,在按键闭合及断开的瞬间均伴随有一连串的抖动。如下图所示,按键按下时候会存在抖动:

  按键消抖的方法有硬件消抖与软件消抖。此处描述软件消抖的方法。即检测出按键闭合后执行一个延时程序,根据抖动的时间为5ms~10ms,我们产生一个20ms的延时,让前沿抖动消失后再一次检测键的状态,如果仍保持闭合状态电平,则确认为真正有键按下。

  本节采用实现按键控制LED灯的方式设计按键消抖模块并实现按键控制LED灯的亮灭。

二. 模块框图

  按键消抖模块名称key_filter. 输入信号key_in, 时钟信号sys_clk,复位信号sys_rst_n,以及输出信号key_flag.

        

三. 程序设计

  已知抖动的时间是小于10 ms的,而当有20ms的时间内都没有抖动就说明按键已经处于稳定状态了。因此我们只需要找到最后一次抖动的时间,并开启20ms的计数,如果低电平持续保持20ms,那么既可以视为按键按下。

  Verilog代码如下:

module  key_filter
(
    input   wire    sys_clk     ,   
    input   wire    sys_rst_n   ,   
    input   wire    key_in      ,   

    output  reg     key_flag        
                                    
);

parameter CNT_MAX = 20'd999_999 	;

reg     [19:0]  cnt_20ms    		;   

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_20ms <= 20'b0;
    else    if(key_in == 1'b1)
        cnt_20ms <= 20'b0;
    else    if(cnt_20ms == CNT_MAX && key_in == 1'b0)
        cnt_20ms <= cnt_20ms;
    else
        cnt_20ms <= cnt_20ms + 1'b1;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        key_flag <= 1'b1;
    else    if(cnt_20ms == CNT_MAX - 1'b1)
        key_flag <= ~key_flag;
    else
        key_flag <= 1'b1 ;

endmodule

  key_flag信号初始为高电平,当检测到按键按下(即最后一次抖动之后低电平持续维持20ms),将key_flag信号取反,即生成一个时钟周期的低电平信号,表明按键按下。

四. 按键控制LED灯亮灭状态的转换

 1. 模块设计

  该工程包含顶层模块led_key和底层模块key_filter。

  RTL视图如下:

 2. Verilog代码实现

 顶层模块led_key中只需例化按键消抖模块并且描述一个带有使能信号的触发器即可。

module led_key
(

	input 	wire 		sys_clk		,
	input	wire		sys_rst_n	,
	
	input 	wire		key_in		,
	output	reg 		led_out


);

key_filter key_filter_U0
(
    .sys_clk     (sys_clk     ),   
    .sys_rst_n   (sys_rst_n   ),   
    .key_in      (key_in      ),   
                 
    .key_flag    (key_flag    )    
                                    
);

always@( posedge sys_clk or negedge sys_rst_n )
	if( sys_rst_n == 1'b0 )
		led_out <= 1'b1 ;
	else if( key_flag == 1'b0 )
		led_out <= ~ led_out ;
	else 
		led_out <= led_out ;

endmodule

3. 程序运行烧录结果

  按键控制LED灯的亮灭,初始状态LED灯灭,按下按键LED灯亮起,再次按下熄灭。

   

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

是既白呀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值