vhdl按键消抖程序(七种方式实现按键消抖)

来源:电子发烧友整理 作者:2018年01月29日 16:04

按键消抖通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖。

vhdl按键消抖程序一:延时性消抖

在本例子中,input是按键的输入,output是消抖之后的按键输出

是clk经历8个上升沿之后就让output输出一个CLK周期的高电平!

本程序实例测试好用

library ieee;

use ieee.std_logic_1164.all;

enTIty PWlock is

port(clk: in std_logic;

input: in std_logic;

output: out std_logic

);

end PWlock;

architecture one of PWlock is

signal a:std_logic;

signal count:integer range 0 to 9;

begin

process(clk)

begin

if input=‘0’ then

count<=0;

elsif (clk‘event and clk=’1‘) then

if count=9 then

count<=count; --like while(1) in the C program

else

count<=count+1;

end if;

end if; --for elsif

if count=8 then

a<=’0‘;

else

a<=’1‘;

end if;

end process;

output<=a;

end one;

vhdl按键消抖程序二

一般按键延时在20ms左右,根据时钟频率决定你的计数范围。程序非常简单,但经常用到,对于FPGA初学者要好好学习这部分。

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

enTIty reseter is

port(clk,reset_in:in std_logic; --按键按下时为0

reset_out:out std_logic:=‘0’);

end reseter;

architecture behav of reseter is

begin

PROCESS(clk,reset_in)

VARIABLE COUNT1 :INTEGER RANGE 0 TO 100000;

BEGIN

IF reset_in=‘0’ THEN

IF RISING_EDGE(clk) THEN

IF COUNT1<10000 THEN COUNT1:=COUNT1+1;

ELSE COUNT1:=COUNT1; END IF;

IF COUNT1<=9999 THEN reset_out<=‘1’;

ELSE reset_out<=‘0’; END IF;

END IF;

ELSE COUNT1:=0;

reset_out<=‘1’;

END IF;

END PROCESS ;

end behav;```

vhdl按键消抖程序三:计数器型消抖电路(一)

计数器型消抖电路是设置一个模值为(N+1)的控制计数器,clk在上升沿时,如果按键开关key_in=‘1’,计数器加1,key_in=‘0’时,计数器清零。当计数器值为2时,key_out输出才为1,其他值为0时。计数器值为N时处于保持状态。因此按键key_in持续时间大于N个clk时钟周期时,计数器输出一个单脉冲,否则没有脉冲输出。如果按键开关抖动产生的毛刺宽度小于N个时钟周期,因而毛刺作用不可能使计数器有输出,防抖动目的得以实现。clk的时钟周期与N的值可以根据按键抖动时间由设计者自行设定。

vhdl按键消抖程序(七种方式实现按键消抖)

图1是N为3的波形仿真图,当按键持续时间大于3个时钟周期,计数器输出一个单脉冲,其宽度为1个时钟周期,小于3个时钟周期的窄脉冲用作模拟抖动干扰,从图1可以看出,抖动不能干扰正常的单脉冲输出。

vhdl按键消抖程序(七种方式实现按键消抖)

该方案的特点是能很好消除按键抖动产生的窄脉冲,还可以滤去干扰、噪音等其他尖峰波,但遇到脉宽大于N个Tclk时钟周期的干扰、噪音等时会有输出从而产生误操作,而对于按键操作要求按键时间必须大于N个Tclk时钟周期,否则按键操作也没有输出。

vhdl按键消抖程序四:计数器型消抖电路(二)

计数器型消抖电路(二)是控制计数器工作一个循环周期(N+1个状态),且仅在计数器为0时输出为“1”。电路设计了连锁控制设施。在计数器处于状态0时,此时若有按键操作,则计数器进入状态1,同时输出单脉冲(其宽度等于时钟周期)。计数器处于其他状态,都没有单脉冲输出。计数器处于状态N时,控制en=‘0’,导致计数器退出状态N,进入状态0。计数器能否保持状态0,取决于人工按键操作,若按键key_in=‘1’,控制en=‘1’(计数器能正常工作),key_in=‘0’,计数器状态保持。显见计数器处于状态0,人工不按键,则计数器保持状态0。

主要程序结构如下:

vhdl按键消抖程序(七种方式实现按键消抖)

图2是N为7的波形仿真图。在计数器状态为0时,key_in有按键操作,计数器开始连续计数直到计数器状态为0;计数器状态为1-7时,key_in任何操作对计数器工作无影响,计数器在状态为1时,输出一个单脉冲,脉冲宽度为1个时钟周期。

vhdl按键消抖程序(七种方式实现按键消抖)

该设计方案的特点是能很好消除按键抖动产生的连续脉冲,对按键时间没有要求,缺点是在计数器状态为0时,遇到干扰、噪音等时会有输出,从而产生误操作。

vhdl按键消抖程序五:D触发器型消抖电路

D触发器型消抖电路设计了三个D触发器与一个三输入与门。三个D触发器串行连接,其Q输出端分别与三输入与门的输入端连接,D触发器型消抖电路RTL电路如图3所示。

vhdl按键消抖程序(七种方式实现按键消抖)

主要程序结构如下:

vhdl按键消抖程序(七种方式实现按键消抖)

图4为D触发器型消抖电路波形仿真图,由图可见,当按键操作时间大于或等于clk时钟周期的3倍时,输出一个正脉冲,正脉冲的宽度比key_in少2个clk时钟周期。

vhdl按键消抖程序(七种方式实现按键消抖)

D触发器型消抖电路与计数器型消抖电路(一)相似,计数器型消抖电路(一)输出脉冲宽度是固定的,D触发器型消抖电路输出脉冲宽度随着按键操作时间长短变化。

vhdl按键消抖程序六:状态机型消抖电路

状态机型消抖电路采用有限状态机的设计方法来描述与实现,状态机有S0,S1,S2三种状态,在S0状态下key_out输出为低电平,并以clk时钟信号的频率采样按键输入信号,如果key_in=‘0’,则保持在S0状态,并继续采样按键输入信号的状态,如果key_in=‘1’,则转入S1状态;在S1状态下key_out输出仍为低电平,继续采样按键输入信号的状态,如果key_in=‘1’,则转入S2状态,如果key_in=‘0’则转入S0状态;在S2状态下继续采样按键输入信号的状态,如果key_in=‘1’,则保持在S2状态,key_out输出正脉冲,如果key_in=‘0’,则转入S0状态,key_out输出低电平。

主要程序结构如下:

vhdl按键消抖程序(七种方式实现按键消抖)

图5为状态机型消抖电路波形仿真图,由图可见,该状态机型消抖电路与D触发器型消抖电路仿真结果一致。

vhdl按键消抖程序(七种方式实现按键消抖)

vhdl按键消抖程序七

assign key_done = (dout1 | dout2 | dout3); //按键消抖输出

always @(posedge count[17])

begin

dout1 <= key_in;

dout2 <= dout1;

dout3 <= dout2;

end

always @(negedge key_done[0])

begin

keyen = ~keyen; //将琴键开关转换为乒乓开关

end程序中所用的方法是不断检测按键值。每当Count[17]上升沿到来,就进行检测输入信号。其中dout1,dout2,dout3分别为当前、上个Count[17]上升沿、上上个Count[17]上升沿输入数值。正常情况下为1,假如连续三次为0,三个信号作或运算,使得key_done信号为0,出现下降沿,这样就认为是有按键。

关注电子发烧友微信

有趣有料的资讯及技术干货

下载发烧友APP

打造属于您的人脉电子圈

关注发烧友课堂

锁定最新课程活动及技术直播
声明:电子发烧友网转载作品均尽可能注明出处,该作品所有人的一切权利均不因本站而转移。
作者如不同意转载,既请通知本站予以删除或改正。转载的作品可能在标题或内容上或许有所改动。
收藏 人收藏
分享:

相关阅读

发表评论

elecfans网友

分享到:

用户评论(0