按鍵消抖通常的按鍵所用開關(guān)為機(jī)械彈性開關(guān),當(dāng)機(jī)械觸點(diǎn)斷開、閉合時(shí),由于機(jī)械觸點(diǎn)的彈性作用,一個(gè)按鍵開關(guān)在閉合時(shí)不會(huì)馬上穩(wěn)定地接通,在斷開時(shí)也不會(huì)一下子斷開。因而在閉合及斷開的瞬間均伴隨有一連串的抖動(dòng),為了不產(chǎn)生這種現(xiàn)象而作的措施就是按鍵消抖。
vhdl按鍵消抖程序一:延時(shí)性消抖
在本例子中,input是按鍵的輸入,output是消抖之后的按鍵輸出
是clk經(jīng)歷8個(gè)上升沿之后就讓output輸出一個(gè)CLK周期的高電平!
本程序?qū)嵗郎y(cè)試好用
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按鍵消抖程序二
一般按鍵延時(shí)在20ms左右,根據(jù)時(shí)鐘頻率決定你的計(jì)數(shù)范圍。程序非常簡(jiǎn)單,但經(jīng)常用到,對(duì)于FPGA初學(xué)者要好好學(xué)習(xí)這部分。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity reseter is
port(clk,reset_in:in std_logic; --按鍵按下時(shí)為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按鍵消抖程序三:計(jì)數(shù)器型消抖電路(一)
計(jì)數(shù)器型消抖電路是設(shè)置一個(gè)模值為(N+1)的控制計(jì)數(shù)器,clk在上升沿時(shí),如果按鍵開關(guān)key_in=‘1’,計(jì)數(shù)器加1,key_in=‘0’時(shí),計(jì)數(shù)器清零。當(dāng)計(jì)數(shù)器值為2時(shí),key_out輸出才為1,其他值為0時(shí)。計(jì)數(shù)器值為N時(shí)處于保持狀態(tài)。因此按鍵key_in持續(xù)時(shí)間大于N個(gè)clk時(shí)鐘周期時(shí),計(jì)數(shù)器輸出一個(gè)單脈沖,否則沒有脈沖輸出。如果按鍵開關(guān)抖動(dòng)產(chǎn)生的毛刺寬度小于N個(gè)時(shí)鐘周期,因而毛刺作用不可能使計(jì)數(shù)器有輸出,防抖動(dòng)目的得以實(shí)現(xiàn)。clk的時(shí)鐘周期與N的值可以根據(jù)按鍵抖動(dòng)時(shí)間由設(shè)計(jì)者自行設(shè)定。
圖1是N為3的波形仿真圖,當(dāng)按鍵持續(xù)時(shí)間大于3個(gè)時(shí)鐘周期,計(jì)數(shù)器輸出一個(gè)單脈沖,其寬度為1個(gè)時(shí)鐘周期,小于3個(gè)時(shí)鐘周期的窄脈沖用作模擬抖動(dòng)干擾,從圖1可以看出,抖動(dòng)不能干擾正常的單脈沖輸出。
該方案的特點(diǎn)是能很好消除按鍵抖動(dòng)產(chǎn)生的窄脈沖,還可以濾去干擾、噪音等其他尖峰波,但遇到脈寬大于N個(gè)Tclk時(shí)鐘周期的干擾、噪音等時(shí)會(huì)有輸出從而產(chǎn)生誤操作,而對(duì)于按鍵操作要求按鍵時(shí)間必須大于N個(gè)Tclk時(shí)鐘周期,否則按鍵操作也沒有輸出。
vhdl按鍵消抖程序四:計(jì)數(shù)器型消抖電路(二)
計(jì)數(shù)器型消抖電路(二)是控制計(jì)數(shù)器工作一個(gè)循環(huán)周期(N+1個(gè)狀態(tài)),且僅在計(jì)數(shù)器為0時(shí)輸出為“1”。電路設(shè)計(jì)了連鎖控制設(shè)施。在計(jì)數(shù)器處于狀態(tài)0時(shí),此時(shí)若有按鍵操作,則計(jì)數(shù)器進(jìn)入狀態(tài)1,同時(shí)輸出單脈沖(其寬度等于時(shí)鐘周期)。計(jì)數(shù)器處于其他狀態(tài),都沒有單脈沖輸出。計(jì)數(shù)器處于狀態(tài)N時(shí),控制en=‘0’,導(dǎo)致計(jì)數(shù)器退出狀態(tài)N,進(jìn)入狀態(tài)0。計(jì)數(shù)器能否保持狀態(tài)0,取決于人工按鍵操作,若按鍵key_in=‘1’,控制en=‘1’(計(jì)數(shù)器能正常工作),key_in=‘0’,計(jì)數(shù)器狀態(tài)保持。顯見計(jì)數(shù)器處于狀態(tài)0,人工不按鍵,則計(jì)數(shù)器保持狀態(tài)0。
主要程序結(jié)構(gòu)如下:
圖2是N為7的波形仿真圖。在計(jì)數(shù)器狀態(tài)為0時(shí),key_in有按鍵操作,計(jì)數(shù)器開始連續(xù)計(jì)數(shù)直到計(jì)數(shù)器狀態(tài)為0;計(jì)數(shù)器狀態(tài)為1-7時(shí),key_in任何操作對(duì)計(jì)數(shù)器工作無影響,計(jì)數(shù)器在狀態(tài)為1時(shí),輸出一個(gè)單脈沖,脈沖寬度為1個(gè)時(shí)鐘周期。
該設(shè)計(jì)方案的特點(diǎn)是能很好消除按鍵抖動(dòng)產(chǎn)生的連續(xù)脈沖,對(duì)按鍵時(shí)間沒有要求,缺點(diǎn)是在計(jì)數(shù)器狀態(tài)為0時(shí),遇到干擾、噪音等時(shí)會(huì)有輸出,從而產(chǎn)生誤操作。
vhdl按鍵消抖程序五:D觸發(fā)器型消抖電路
D觸發(fā)器型消抖電路設(shè)計(jì)了三個(gè)D觸發(fā)器與一個(gè)三輸入與門。三個(gè)D觸發(fā)器串行連接,其Q輸出端分別與三輸入與門的輸入端連接,D觸發(fā)器型消抖電路RTL電路如圖3所示。
主要程序結(jié)構(gòu)如下:
圖4為D觸發(fā)器型消抖電路波形仿真圖,由圖可見,當(dāng)按鍵操作時(shí)間大于或等于clk時(shí)鐘周期的3倍時(shí),輸出一個(gè)正脈沖,正脈沖的寬度比key_in少2個(gè)clk時(shí)鐘周期。
D觸發(fā)器型消抖電路與計(jì)數(shù)器型消抖電路(一)相似,計(jì)數(shù)器型消抖電路(一)輸出脈沖寬度是固定的,D觸發(fā)器型消抖電路輸出脈沖寬度隨著按鍵操作時(shí)間長(zhǎng)短變化。
vhdl按鍵消抖程序六:狀態(tài)機(jī)型消抖電路
狀態(tài)機(jī)型消抖電路采用有限狀態(tài)機(jī)的設(shè)計(jì)方法來描述與實(shí)現(xiàn),狀態(tài)機(jī)有S0,S1,S2三種狀態(tài),在S0狀態(tài)下key_out輸出為低電平,并以clk時(shí)鐘信號(hào)的頻率采樣按鍵輸入信號(hào),如果key_in=‘0’,則保持在S0狀態(tài),并繼續(xù)采樣按鍵輸入信號(hào)的狀態(tài),如果key_in=‘1’,則轉(zhuǎn)入S1狀態(tài);在S1狀態(tài)下key_out輸出仍為低電平,繼續(xù)采樣按鍵輸入信號(hào)的狀態(tài),如果key_in=‘1’,則轉(zhuǎn)入S2狀態(tài),如果key_in=‘0’則轉(zhuǎn)入S0狀態(tài);在S2狀態(tài)下繼續(xù)采樣按鍵輸入信號(hào)的狀態(tài),如果key_in=‘1’,則保持在S2狀態(tài),key_out輸出正脈沖,如果key_in=‘0’,則轉(zhuǎn)入S0狀態(tài),key_out輸出低電平。
主要程序結(jié)構(gòu)如下:
圖5為狀態(tài)機(jī)型消抖電路波形仿真圖,由圖可見,該狀態(tài)機(jī)型消抖電路與D觸發(fā)器型消抖電路仿真結(jié)果一致。
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; //將琴鍵開關(guān)轉(zhuǎn)換為乒乓開關(guān)
end程序中所用的方法是不斷檢測(cè)按鍵值。每當(dāng)Count[17]上升沿到來,就進(jìn)行檢測(cè)輸入信號(hào)。其中dout1,dout2,dout3分別為當(dāng)前、上個(gè)Count[17]上升沿、上上個(gè)Count[17]上升沿輸入數(shù)值。正常情況下為1,假如連續(xù)三次為0,三個(gè)信號(hào)作或運(yùn)算,使得key_done信號(hào)為0,出現(xiàn)下降沿,這樣就認(rèn)為是有按鍵。
評(píng)論
查看更多