1.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;
else
count<=count+1;
end if;
end if; -
if count=8 then
a<=’0‘;
else
a<=’1‘;
end if;
end process;
output<=a;
end one;
2.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;
3.vhdl按键消抖程序三:计数器型消抖电路(一)
计数器型消抖电路是设置一个模值为(N+1)的控制计数器,clk在上升沿时,如果按键开关key_in=‘1’,计数器加1,key_in=‘0’时,计数器清零。当计数器值为2时,key_out输出才为1,其他值为0时。计数器值为N时处于保持状态。因此按键key_in持续时间大于N 个clk时钟周期时,计数器输出一个单脉冲,否则没有脉冲输出。如果按键开关抖动产生的毛刺宽度小于N个时钟周期,因而毛刺作用不可能使计数器有输出,防抖动目的得以实现。clk的时钟周期与N的值可以根据按键抖动时间由设计者自行设定。
主要程序结构如下:
if(clk’event and clk=’1’)then
if(key_in=’1’)then
if count=N then
count<=count;
else count<=count+1;
end if;
end if;
else count<=0;
end if;
4.vhdl按键消抖程序四:计数器型消抖电路(二)
计数器型消抖电路(二)是控制计数器工作一个循环周期(N+1个状态),且仅在计数器为0时输出为“1”。电路设计了连锁控制设施。在计数器处于状态0时,此时若有按键操作,则计数器进入状态1,同时输出单脉冲(其宽度等于时钟周期)。计数器处于其他状态,都没有单脉冲输出。计数器处于状态N时,控制en=‘0’,导致计数器退出状态N,进入状态0。计数器能否保持状态0,取决于人工按键操作,若按键key_in=‘1’,控制en=‘1’(计数器能正常工作),key_in=‘0’,计数器状态保持。显见计数器处于状态0,人工不按键,则计数器保持状态0。
主要程序结构如下:
if count=N then
count<=0;
else count<=count+1;
end if;
if count=0 then
key_out<=’0’;
end if;
end if
end process;
B:process(clk)
begin
if(clk’event and clk=’1’)then
if count if key_in=’1’ then en<=’1’; else en<=en; end if; end if; end process; 5.vhdl按键消抖程序五:D触发器型消抖电路 D触发器型消抖电路设计了三个D触发器与一个三输入与门。三个D触发器串行连接,其Q输出端分别与三输入与门的输入端连接. 主要程序结构如下: key_out<=d1 or d2 or d3; process(clock) begin if(clk’event and clk=’1’)then d1<=key_in; d2<=d1; d3<=d2; end if; end process; 补充:改进型D触发器(正负双输出端,本次实验被多次引用) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity qdd is port(key,clk:in std_logic; up:out std_logic); end qdd; architecture a of qdd is signal q0,q1:std_logic; begin process(clk) begin if (clk'event and clk='1')then q0<=key; q1<=q0; end if; end process; up<=(q1 and (not q0)); end a; 6.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输出低电平。 主要程序结构如下: if clk’event and clk=’1’ then case sta is when s0=>key_out<=’0’; if key_in=’1’then s<=s1; else s<=s0;end if; when s2=> if key_in=’1’then key_out<=’1’;s<=s2; else s<=s0;end if; when s2=> if key_in=’1’ then key_out<=’1’;s<=s2; else key_out<=’0’;s<=s0; end if; end case; end if; 7.vhdl按键消抖程序七 end程序中所用的方法是不断检测按键值。每当Count[17]上升沿到来,就进行检测输入信号。其中dout1,dout2,dout3分别为当前、上个Count[17]上升沿、上上个Count [17]上升沿输入数值。正常情况下为1,假如连续三次为0,三个信号作或运算,使得key_done信号为0,出现下降沿,这样就认为是有按键。 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;