按键消抖记录

按键消抖

1.产生原因

根据机械按键的构造和原理,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。所以在按键闭合及断开的瞬间均伴随有一连串的抖动。
按键抖动

2.消抖方法

分为硬件和软件消抖。
由于硬件消抖一般会增加器件,不方便且对电路板的制作有一定影响。这里采取软件消抖的方法。
检测出按键闭合后执行一个延时程序,根据抖动的时间为 5ms~10ms,我们产生一个 20ms 的延时,让前沿抖动消失后再一次检测键的状态,如果仍保持闭合状态电平,则确认为真正有键按下。

3.软件消抖
  1. 设计模块
    要计数过滤掉按键抖动的时间,所以计数器是必不可少的,那么需要时钟,还需要复位信号,以及按键信号。
    模块
  2. 时序图模拟

抖动的时间一般小于10ms,当有20ms 的时间内都没有抖动就说明按键已经处于稳定状态了。所以可以设计一个计数器,计数20ms,这期间没有抖动则此时是什么电平就是什么电平。那么我们需要找到一段20ms没有抖动的区间。当系统检测到按键为低电平时 , 计数器就计数,当检测到按键为高电平时计数器就清零。
时序图
上图注意到按键按下的时间较长时,是让cnt继续保持计数最大值,这样可以避免产生多个输出脉冲。

  1. 代码
module	key_filter
#(
	parameter	CNT_MAX = 20'd999999
)
(
	input	wire	sys_clk,
	input	wire	sys_rst_n,
	input	wire	key_in,
	
	output	reg	key_out
);

reg		[19:0]	cnt;

always@(posedge	sys_clk or negedge	sys_rst_n)
	if (sys_rst_n == 0 || key_in == 1'b1)
		cnt <= 20'd0;
	else	if (cnt == CNT_MAX)
		cnt <= CNT_MAX;
	else	if (key_in == 1'b0)
		cnt <= cnt + 1;

always@(posedge	sys_clk or negedge	sys_rst_n)
	if (sys_rst_n == 0)
		key_out <= 1'b0;
	else	if (cnt == CNT_MAX - 1)
		key_out <= 1'b1;
	else	
		key_out <= 1'b0;	

endmodule
  1. 仿真代码
`timescale	1ns/1ns

module	tb_key_filter();

reg		sys_clk, sys_rst_n, key_in;
wire	key_out;

reg		[7:0]	tb_cnt;		//利用tb_cnt来模拟按键抖动计数器

initial
	begin
		sys_clk = 1'b1;
		sys_rst_n <= 1'b0;
		key_in <= 1'b1;
		#20
		sys_rst_n <= 1'b1;
	end

always #10 sys_clk = ~sys_clk;
//tb_cnt:按键过程计数器,通过该计数器的计数时间来模拟按键的抖动过程
always@(posedge	sys_clk or negedge	sys_rst_n)
	if (sys_rst_n == 0 )
		tb_cnt <= 8'd0;
	else	if (tb_cnt == 8'd249)
		tb_cnt <= 8'd0;
	else
		tb_cnt <= tb_cnt + 1;
//key_in:产生输入随机数,模拟按键的输入情况		
always@(posedge	sys_clk or negedge	sys_rst_n)
	if (sys_rst_n == 0 )
		key_in <= 1'd1;
	else	if ((tb_cnt >= 8'd19 && tb_cnt <= 8'd49) || 
				(tb_cnt >= 8'd169 && tb_cnt <= 8'd199))
//在该计数区间内产生非负随机数 0、1 来模拟 10ms 的前抖动和 10ms 的后抖动
		key_in <= ($random) % 2;	
	else	if (tb_cnt >= 8'd49 && tb_cnt <= 8'd149)	
		key_in <= 1'b0;
	else
		key_in <= 1'b1;

key_filter
#(
	.CNT_MAX(20'd24)
)	
key_filter_inst
(
	.sys_clk	(sys_clk),
	.sys_rst_n	(sys_rst_n),
	.key_in		(key_in),			
	.key_out	(key_out)
); 


endmodule
  1. RTL视图
    在这里插入图片描述

  2. 仿真时序图

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 FreeRTOS 中实现按键消抖,可以通过以下步骤进行: 1. 确定按键的引脚和相关参数:首先,确定用于连接按键的引脚。确保正确配置引脚的输入/输出模式、上拉/下拉电阻等参数。 2. 创建一个任务或使用现有任务:你可以为按键处理创建一个专用任务,或者将按键处理与其他任务结合在一起。在这个任务中,我们将执行按键消抖的逻辑。 3. 实现按键消抖算法:按键消抖是通过软件算法来实现的。常见的按键消抖算法是基于状态机的方法。 a. 定义状态:定义两个状态,例如按下状态和释放状态。 b. 检测按键状态变化:在任务中不断检测按键的输入状态。当按键被按下时,记录下当前时间戳,并将状态设置为按下状态。然后继续检测按键状态,直到按键被释放。 c. 检测时间间隔:当按键被释放后,检测当前时间戳与之前记录的时间戳之间的时间间隔。如果时间间隔小于设定的消抖时间阈值(例如10ms),则可以认为是噪声引起的抖动,忽略该事件。如果时间间隔大于等于设定的时间阈值,说明按键的状态已经稳定,可以进行后续的处理。 d. 处理按键事件:根据按键的状态进行相应的处理,比如触发一个事件、执行某个功能等。 4. 使用延时函数:在任务中,可以使用 FreeRTOS 提供的延时函数来控制按键状态的检测频率。通过调整延时时间,可以适应不同的应用场景和系统性能要求。 需要注意的是,按键消抖算法可能因硬件和应用场景的不同而有所差异。上述步骤仅提供了一种常见的实现方式,具体实现还需根据实际需求进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值