EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
优秀滤波算法应用 6 o3 o) T, X; p- _
; t5 z' q5 q- y' t( K
我们平常所用的按键为机械弹性开关,由于触点的弹性作用,按键在闭合时不会马上稳定的接通,而是有一段时间的抖动,在断开时也不会立即断开。抖动时间由按键的机械特性所决定,一般为5ms~10ms。所以我们在做按键检测时都要加一个消抖的过程。按键消抖主要有两种方案:一是硬件消抖;二是软件消抖。下面结合一个例程来看看老外是如何实现软件消抖的。 entity top is, m; u3 ` m5 C9 ^4 U
Port ( btn_0 : in STD_LOGIC;
1 B" r3 q) T/ K1 {, E clk : in STD_LOGIC;
4 k' u2 @: ~! q led : out STD_LOGIC);
: y7 j( [/ \3 i0 Pend top; architecture Behavioral of top is
+ h/ C) ]& G3 uconstant CNTR_MAX : std_logic_vector(15 downto 0) := (others => '1');+ F8 O7 p9 S2 G. r4 Q7 W8 P4 ]0 X
signal btn0_cntr : std_logic_vector(15 downto 0) := (others => '0');1 l( _* p( I& }, o$ x: G
signal led_r : std_logic := '0';' @$ Y4 D1 K4 R/ o0 C. i
signal btn0_reg : std_logic := '0';
% w( `6 f2 _2 u: h: Jbegin: b1 C+ n! f/ S1 m2 _
btn0_debounce_process : process (CLK)# Z. n- }1 U! a) k
begin
) m3 j: N) a. \ if (rising_edge(CLK)) then( m& `8 [ D( f; n6 X8 R
if (btn0_cntr = CNTR_MAX) then
. |' e& h+ T# I+ n. { btn0_reg <= not(btn0_reg);
( B: f3 K$ y- g1 O; l, n/ [ end if;
% F& C* T! v9 `7 z) c end if;
$ ~: |/ \- D0 `% E& Cend process;$ T, o+ H- ~6 M, S( t
btn0_counter_process : process (CLK)8 u. c6 f4 S: {+ F4 R: R2 A
begin
; Y& l$ }9 O+ S0 L if (rising_edge(CLK)) then0 a9 x' y$ t" [ _8 Y8 @+ N
if ((btn0_reg = '1') xor (btn_0 = '1')) then
0 Y+ I( N' U6 J& h5 ?% \ if (btn0_cntr = CNTR_MAX) then
! K* A; I+ j! B; M+ x' [3 h btn0_cntr <= (others => '0');
# r5 r: X" H$ J$ n# R else
0 ? l% Y1 Q/ P3 t$ S+ r- i$ x btn0_cntr <= btn0_cntr + 1; W6 n3 [3 b8 y4 Z" s* }1 F" B# w4 R
end if;
. ]: m1 s, F0 U; c: M% T: F else
. U. y, m: A7 p4 ]$ @' p btn0_cntr <= (others => '0');
: ?8 h- Z4 _% l; E! F end if;
. O9 P( U3 ~% O) }5 I end if;
, H x4 I b& V, b4 }2 ], Tend process;
) T6 @0 I/ a% ? O1 }& @/ B1 ~process(btn0_reg)
* K$ F- S8 R, n/ gbegin4 c0 U: W( f6 |$ c8 [# Z
if rising_edge(btn0_reg) then/ V6 d' C. @0 V3 P2 K8 W) G
led_r <= not (led_r);
' t+ _0 e" @6 {# c4 T end if;3 E- l# X$ w$ f) B& I) `# _
end process;, t- {9 Z1 t( g$ ]# x7 y
led <= led_r;
( e7 G' z5 X: q4 r9 uend Behavioral;
' X' I; \) \5 N0 G$ y/ R 一般人的做法是:当第一次检测到按键被按下后,执行一个延时程序,产生一个5ms~10ms的延时程序,然后再一次检测按键的状态,如果仍保持按键闭合状态电平,则认为确实有按键按下。这种办法不失为一种不错的解决方案,但是不同按键的机械特性不同,就算是同一型号按键机械特性或多或少也会有所不同,这样一来,延时时间不好确定。而上面的这段代码很好的解决了这一问题,下面我们来具体分析一下。当有按键按下
6 E6 Y) [3 S- \$ K0 A' z即btn_0 = '1',计数器启动开始计数,并且不断检测按键的状态。如果是抖动,计数器会被清零;如果按键闭合状态时的电平保持一段时间不发生变化,我们就认为当前有按键按下。同理,按键释放时也会执行类似的过程。按上述分析,我们会得到如下结论:btn0_reg出现上升沿代表有按键按下。上述例程的实验现象是:随着按键的按下LED交替点亮熄灭。
: o; c) x7 J0 B/ P$ f+ N# y7 T2 ~ X2 r |