2014年9月5日 星期五

Push button Debounce and Synchronization

Referecce : Design Examples ELEC 418 Advanced Digital Systems Dr. Ron Hayne


由於數位電路的動作速度非常快(常以 ns 為計算單位),所以若在電路中使用機械式
的開關(switch)時,就必須考慮開關的彈跳(bounce)問題,因為機械式的開關在轉換狀態(
某一接點投擲至另一接點)的瞬間,會產生多次的彈跳現象,造成電路的錯誤輸出。如圖
6-19 所示的電路,當開關的位置由 A 點投擲至 B (開關內部的金屬簧片撞擊 B 點的金屬
接點)時,雖然投擲後開關內部有彈簧的慣性支撐,但是在硬碰硬(金屬碰金屬)的情況下,
仍會產生多次的彈跳現象,此一過度的現象雖只有幾個毫秒(ms)而已,但對數位電路而
言,如同輸入多個脈波(pulse)的情況,所以當機械式開關的訊號要輸入數位電路時,通常
都會先經過『防彈跳(debounce)』的作用,以確保數位電路能正確獲得輸入訊號;而常見
的防彈跳方法有兩種,一為軟體方式----以延遲讀取的方法,來取得正確的輸入資料,
常用於眾多輸入按鍵的地方,例如電腦鍵盤的資料(掃描碼)讀取,另一則為硬體方式----
以防彈跳電路,來取得正確的輸入資料



將輸入的訊號延遲到下一個register,順便synchronize,在將已經沒有毛刺的訊號合成一個pulse送入電路

testbench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
library UNISIM;
use UNISIM.VComponents.all;

ENTITY PB_DEBOUNCE_SYNC_TB IS
END PB_DEBOUNCE_SYNC_TB;

ARCHITECTURE behavior OF PB_DEBOUNCE_SYNC_TB IS

-- Component Declaration for the Unit Under Test (UUT)

COMPONENT PB_DEBOUNCE_SYNC
PORT(
clk : IN std_logic;
pb_in : IN std_logic;
pb_out : OUT std_logic
);
END COMPONENT;



--Inputs
signal clk : std_logic := '0';
signal pb_in : std_logic := '0';


--Outputs
signal pb_out : std_logic;


-- Clock period definitions
constant clk_period : time := 100 ns;

BEGIN

-- Instantiate the Unit Under Test (UUT)
uut: PB_DEBOUNCE_SYNC PORT MAP (
clk => clk,
pb_in => pb_in,
pb_out => pb_out
);


-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;



-- Stimulus process
stim_proc: process
begin
wait for 48 ns;
pb_in <= '1'; wait for 1 ns;
pb_in <= '0'; wait for 1 ns;
pb_in <= '1'; wait for 1 ns;
pb_in <= '0'; wait for 1 ns;
pb_in <= '1'; wait for 1 ns;
pb_in <= '0'; wait for 1 ns;
pb_in <= '1'; wait for 1 ns;
pb_in <= '0'; wait for 1 ns;
pb_in <= '1'; wait for 1 ns;
pb_in <= '0'; wait for 1 ns;
pb_in <= '1'; wait for 1 ns;
pb_in <= '0'; wait for 1 ns;
pb_in <= '1'; wait for 485 ns;
pb_in <= '0'; wait for 1 ns;
pb_in <= '1'; wait for 1 ns;
pb_in <= '0'; wait for 1 ns;
pb_in <= '1'; wait for 1 ns;
pb_in <= '0'; wait for 1 ns;
pb_in <= '1'; wait for 1 ns;
pb_in <= '0'; wait for 1 ns;
pb_in <= '1'; wait for 1 ns;
pb_in <= '0'; wait for 1 ns;
pb_in <= '1'; wait for 1 ns;
pb_in <= '0';
wait;
end process;


END;



debounce上面還有看到很多不同的寫法,有的可以自己決定要延長多久時間才取突波,這邊也可以把sync加大延遲,然後取另外一種邏輯方式來決定pulse

沒有留言:

張貼留言