EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
优秀滤波算法应用 5 i) N* u5 K* ~: `9 a& P
$ O4 D4 ? V* P2 v0 B3 y1 g+ v
我们平常所用的按键为机械弹性开关,由于触点的弹性作用,按键在闭合时不会马上稳定的接通,而是有一段时间的抖动,在断开时也不会立即断开。抖动时间由按键的机械特性所决定,一般为5ms~10ms。所以我们在做按键检测时都要加一个消抖的过程。按键消抖主要有两种方案:一是硬件消抖;二是软件消抖。下面结合一个例程来看看老外是如何实现软件消抖的。 entity top is3 I; } o, h+ ?' h8 ~3 k: v3 ^
Port ( btn_0 : in STD_LOGIC;
3 x$ F* j4 i' @( ^, c% X0 m, s clk : in STD_LOGIC;( `& d/ N F1 P" C5 Q8 d
led : out STD_LOGIC);
! k% q. k. X8 b& U$ |. j oend top; architecture Behavioral of top is6 i5 a: h5 m8 i0 E
constant CNTR_MAX : std_logic_vector(15 downto 0) := (others => '1');9 F2 s* \' j: i" l- H7 B
signal btn0_cntr : std_logic_vector(15 downto 0) := (others => '0');9 L3 S6 `+ T. R4 d/ f5 ^ g
signal led_r : std_logic := '0';4 B( c. u8 b' _8 F1 c/ ~$ c! r3 @
signal btn0_reg : std_logic := '0';
6 K9 g2 d9 S, Vbegin
L# E, ]4 W/ C: B+ F1 a4 e. t2 Xbtn0_debounce_process : process (CLK)* N' x! r9 x G9 N+ o5 f! V
begin
$ K8 ~/ U' \' F6 w0 R( F! c2 J if (rising_edge(CLK)) then
( X. @" s! L [ if (btn0_cntr = CNTR_MAX) then
% L( O5 s* S+ U btn0_reg <= not(btn0_reg);4 m! F' n3 ]2 F. S7 ~
end if; ]; t6 d0 }- ]8 J4 B% E
end if;0 T' }/ z# y2 U' @
end process;, i1 D% C( F9 g
btn0_counter_process : process (CLK). y8 s- B7 N; M6 ?; V
begin
, z5 k" v! Z# G8 n e if (rising_edge(CLK)) then
$ M, I* W j2 [8 v; _ if ((btn0_reg = '1') xor (btn_0 = '1')) then
$ c2 o& P }9 R# _3 y5 w if (btn0_cntr = CNTR_MAX) then* C0 u$ N% b3 s, W
btn0_cntr <= (others => '0');
0 w. d( |, m. ?0 a else
; k3 k3 O" c/ B7 s btn0_cntr <= btn0_cntr + 1;
. Z, C# Z' ?0 k, E% h* } end if;
8 g @3 Z5 l' b3 u+ C! k9 ?8 H else
5 O! _+ l' P1 E- O, Q4 U btn0_cntr <= (others => '0');1 R/ r( W" ?: _8 h
end if;
, P1 J6 R* R6 ?* e end if;
* ^, d: r( `5 G: dend process;& K" E) U% ^# [$ ]& {: G1 G+ X
process(btn0_reg)
' M. r* N0 p/ s( c3 pbegin/ z+ [ U h1 ^% i0 ^( {% e
if rising_edge(btn0_reg) then1 D! f$ [2 r% b4 V u7 o; n
led_r <= not (led_r);+ H# N' T1 o W: k( M
end if;' ^& d" | o* ]7 R
end process;: [! _' P/ ~! ?" U' E- V- q
led <= led_r;1 C' @. H! {6 t0 T
end Behavioral;
6 [ }# I9 k; q- p& \( g% y8 g. q 一般人的做法是:当第一次检测到按键被按下后,执行一个延时程序,产生一个5ms~10ms的延时程序,然后再一次检测按键的状态,如果仍保持按键闭合状态电平,则认为确实有按键按下。这种办法不失为一种不错的解决方案,但是不同按键的机械特性不同,就算是同一型号按键机械特性或多或少也会有所不同,这样一来,延时时间不好确定。而上面的这段代码很好的解决了这一问题,下面我们来具体分析一下。当有按键按下: u, h6 s* V2 @7 T$ n. ^
即btn_0 = '1',计数器启动开始计数,并且不断检测按键的状态。如果是抖动,计数器会被清零;如果按键闭合状态时的电平保持一段时间不发生变化,我们就认为当前有按键按下。同理,按键释放时也会执行类似的过程。按上述分析,我们会得到如下结论:btn0_reg出现上升沿代表有按键按下。上述例程的实验现象是:随着按键的按下LED交替点亮熄灭。* ]1 B A- o! S' L$ H% k7 K
|