FPGA|CPLD|ASIC论坛
登录
直播中
张玉兰
7年用户
1341经验值
私信
关注
[经验]
FPGA如何实现按键除抖
FPGA
按键消抖
`
假设你将一个机械按键开关与
FPGA
相连,你可能会遇上一些麻烦。
下图是一个按键开关按下10次的结果。
【问题所在】
要想将开关与FPGA相连,你的连接方式可能是这样的:
但机械开关最大的问题就在于它们会抖动!
当按下按键时,要是幸运的话结果会如图:
这是比较罕见的,比较常见的应该如下图:
【FPGA计数器】
假设你在FPGA中加入了一个计数器,让后将其显示出来。如下图:
按下10次得到的结果可能和本文开头的图片一样。
【解决办法】
解决办法之一就是加入一个R/C硬件滤波器,然后给FPGA加入一个施密特触发器,但其实还有一个更简单的办法。
FPGA滤波器
FPGA在简单算法上使用起来相当顺手。我们用FPGA的计数器来看按键按下与松开的时间有多长。只有当该计数器超值时,我们才决定该按键改变了状态。
该图中PB是按键信号(图中为低电平有效)。这样的设计可能会有一些毛刺,因为它没有与任何时钟同步。所以目前还是无法使用的。
我们要将PB与一个时钟同步(本例中使用20MHz),然后创建三个按键输出,全部都是无毛刺且与时钟同步的。每个输出都是高电平有效,且表示按键的三个不同状态(按键状态,刚按下状态,刚松开状态)。
module PushButton_Debouncer(
input clk,
input PB,
output reg PB_state,
output PB_down,
output PB_up
);
reg PB_sync_0; always @(posedge clk) PB_sync_0 <= ~PB; // invert PB to make PB_sync_0 ac
ti
ve high
reg PB_sync_1; always @(posedge clk) PB_sync_1 <= PB_sync_0;
reg [15:0] PB_cnt;
wire PB_idle = (PB_state==PB_sync_1);
wire PB_cnt_max = &PB_cnt; // true when all bits of PB_cnt are 1's
always @(posedge clk)
if(PB_idle)
PB_cnt <= 0; // nothing's going on
else
begin
PB_cnt <= PB_cnt + 16'd1;
if(PB_cnt_max) PB_state <= ~PB_state;
end
assign PB_down = ~PB_idle & PB_cnt_max & ~PB_state;
assign PB_up = ~PB_idle & PB_cnt_max & PB_state;
endmodule
我们用了一个16位计数器,在20MHz的系统时钟下,只要3ms就可以超值。在用户的眼中看来,3ms几乎是不可察觉了。但好在毛刺没了。按键有多少毛刺以及系统时钟速度,都决定了你如何调整计数器的位宽。
`
更多回帖
rotate(-90deg);
回复
相关帖子
FPGA
按键消抖
FPGA
内
实现
按键
消
抖
的方法
1109
如何在
FPGA
中
实现
按键
消
抖
757
FPGA
按键
消
抖
的方法
74
STM单片机中的
按键
消
抖
和
FPGA
消
抖
2445
fpga
按键
去
抖
2939
基于
FPGA
的
按键
消
抖
电路设计
224
基于
FPGA
的
按键
消
抖
电路设计
62
按键
消
抖
怎么
实现
?
7288
【
FPGA
设计实例】用
FPGA
实现
开关
按键
去
抖
8651
FPGA
按键
消
抖
的方法
8055
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
首页
论坛版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分