当前位置:文档之家› 按键去抖动

按键去抖动

LIBRARY ieee ;
USE ieee.std_logic_1164.all ;
USE ieee.std_logic_arith.all ;

------------------------------------------
ENTITY Eliminate_jitter IS
PORT (
clk : IN STD_LOGIC ;
button : IN STD_LOGIC ; -- 数字按键信号输入
pulse : OUT STD_LOGIC -- 消除抖动后的信号
) ;
END Eliminate_jitter ;
-------------------------------------------
ARCHITECTURE Behavior OF Eliminate_jitter IS
SIGNAL reg1 : STD_LOGIC ;
SIGNAL reg2 : STD_LOGIC ;
SIGNAL reg3 : STD_LOGIC ;
SIGNAL reg4 : STD_LOGIC ;
SIGNAL Q1 : STD_LOGIC ;
SIGNAL Q2 : STD_LOGIC ;
SIGNAL reg_pulse : STD_LOGIC ;
BEGIN
Q1 <= reg1 AND reg2 AND reg3 AND reg4 ; -- 消除按键抖动,连续四个高电平有效。
reg_pulse <= Q1 AND NOT(Q2) ; -- 产生一个时钟的脉冲信号。
pulse <= reg_pulse ; -- 脉冲输出

PROCESS( clk )
BEGIN
IF clk'EVENT AND clk='1' THEN
reg1 <= button ; -- 消除按键抖动,时钟移位寄存。自己可以根据需要扩充寄存器个数。
reg2 <= reg1 ;
reg3 <= reg2 ;
reg4 <= reg3 ;
Q2 <= Q1 ;

IF reg_pulse='1' THEN -- 根据脉冲进行操作。
--Here is the action.
END IF ;
END IF ;
END PROCESS ;
END Behavior ;

另一个
请教一个用vhdl编写按键去抖动的问题
普通的cpu中,直接利用sleep之类的语句就可以直接延时去抖动
但是在cpld中,我却碰到了问题,想请教一下各位
问题如下(使用的芯片是altera公司的max7000s系列芯片,芯片型号为7128slc84):
我的程序中,clk3是按键的输入信号
clk2是一个标准的200赫兹输入信号,希望利用这个来计20ms的延时时间

我希望的判断方法:
当接受到第一个clk3=1时,延时20ms,延时以后,再判断此时clk3是否仍为1
如果此时clk3为1,则说明这个脉冲是真脉冲,加counter9
如果此时clk3不为1,则说明这个脉冲只是按键的毛刺,此时延时用的计数器清零,等待下一个clk3=1,再触发延时用的计数器。


关于这部分的程序如下:
……
architecture rtl of clk_div728 is
signal read_key:integer :=0;
signal timer_en:integer :=0 ;
signal counter4:integer:=0;
……
p2: process(clk2)
variable counter25:integer range 0 to 63;

begin
if (clk2'event and clk2='1' and timer_en=1) then
counter4<=counter4+1;
elsif (clk2'event and clk2='1' and timer_en=0) then
counter4<=0;
else
counter4<=counter4;
end if;

end process p2;

-----------------------------------------------------------------
read_key<=1 when counter4=4 else 0;
---------------------------------------------------------------

p3:process(clk3)

begin
if (counter4=4) then
timer_en<=0;
elsif (counter4/=4 and clk3'event and clk3='1') then
timer_

en<=1;
else timer_en<=timer_en;
end if;
end process p3;


---------------------------------------------------------------------


p4: process(read_key)


variable counter9:integer range 0 to 16;

begin
if (read_key'event and read_key=1 and clk3='1')then

if (counter9=8)then
counter9:=1;

else

counter9:=counter9+1;

end if;

end if;


case counter9 is
……
end case;



end process p4;
-----------------------------------------------------------------


程序编译的时候通不过,报的错是“unknown problem”
请假一下各位能否指点一二,不甚感激。

另外想特别问一下
这句:
-----------------------------------------------------------------
read_key<=1 when counter4=4 else 0;
---------------------------------------------------------------
单独在进程外执行可以吗,是不是和别的进程是并行的关系?
如果不能这样使用,应该用什么方法?
方法很多啊
先给你一个
采样型防抖电路
library IEEE;
use ieee.std_logic_1164.all;
entity fd is
port(
clk,key: in std_logic;
dmc: out std_logic
);
end;
architecture rtl of fd is
signal r,s,qr,qs,d1,d2,q1,q2,d3,d4,q3,q4,cp:std_logic;
begin
k1: process(clk)
begin
if(clk'event and clk='1')then
d1<=key;
d2<=d1;
q2<=d2;
d3<=qr;
d4<=d3;
q4<=d4;
end if;
r<=(not d2)and (not q2);
s<=d2 and q2;
qr<=r nor qs;
qs<=s nor qr;
cp<=d4 and (not q4);
dmc<=cp;
end process;
end;
我们可以通过改变设计,破坏毛刺产生的条件,来减少毛刺的发生。例如,在数字电路设计中,常常采用格雷码计数器取代普通的二进制计数器,这是因为格雷码计数器的输
出每次只有一位跳变,消除了竞争冒险的发生条件,避免了毛刺的产生。
毛刺并不是对所有的输入都有危害,例如 D 触发器的 D 输入端,只要毛刺不出现在时钟的上升沿并且满足数据的建立和保持时间,就不会对系统造成危害,我们可以说 D 触发
器的 D 输入端对毛刺不敏感。 根据这个特性,我们应当系统中尽可能采用同步电路,这是因为同步电路信号的变化都发生在时钟沿,只要毛刺不出现在时钟的沿口并且不满足数据的建立和保持时间,就不会对系统造成危害。 (由于毛刺很短,多为几纳秒,基本上都不可能满足数据的建立和保持时间)
去除毛刺的一种常见的方法是利用 D 触发器的 D 输入端对毛刺信号不敏感的特点,在输出信号的保持时间内,用触发器读取组合逻辑的输出信号,这种方法类似于将异步电路转化为同步电路。如前所述,优秀的设计方案,如采用格雷码计数器,同步电路等,可以大大

减少毛刺,但它并不能完全消除毛刺。 毛刺并不是对所有输入都有危害,例如 D触发器的 D输入端,只要毛刺不出现在时钟的上升沿并且满足数据的建立和保持时间,就不会对系统造成危害。
因此我们可以说 D触发器的 D输入端对毛刺不敏感。但对于 D触发器的时钟端,置位端,清零端,则都是对毛刺敏感的输入端,任何一点毛刺就会使系统出错,但只要认真处理,我
们可以把危害降到最低直至消除。

不管是用verilog还是VHDL语言,去毛刺都是很简单的几句程序,例如:在同步电路设计中,有时候可以用同步置位的办法来替代异步清 0。在用硬件描述语言
的设计中可以用如下的方式来描述:
异步清 0 的描述方法:
process(rst,clk)
begin
if rst=’1’ then
count<=(others=>’0’);
elsif clk’event and clk=’1’ then
count<=count+1;
end if;
end process;

同步清 0 的描述方法:
process
begin
wait until clk’event and clk=’1’;
if rst=’1’ then
count<=(others=>’0’);
else
count<=count+1;
end if;
end process;

相关主题
文本预览
相关文档 最新文档