Forum Discussion
Altera_Forum
Honored Contributor
19 years agoDE2 Quartus debounced circuit
Hello,
I am working on a senior design project and have a DE2 board connected to external circuitry. There are pushbuttons on the external circuit which control leds also on that circuit board. My design requires that I press the pushbutton and the led lights up and I press it a second time and the led goes off. It turns out that those pushbuttons which are single-pole-double-throw (SPDT) are not debounced and give multiple outputs when I want a clean signal. I would like to know if there is a reference design so I can build debounced circuitry for the buttons in Quartus. If not, how do I build debouncers in Quartus for SPDT pushbuttons? Thanks. Kofi.15 Replies
- Altera_Forum
Honored Contributor
Hello,
I made a simplest program for hex counter it supposed to count push-button clicks. It present the result on a single 7seg display and 4 LEDs, unfortunately I've got a bouncing problem. I'm using a Altera Cyclone II BAIXUN ASK2CB dev. board it has on board push-button Can you please suggest how can i debounce it, so the bits go one by one? Here is my code: ======================================== library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity test is port (Y : out std_logic_vector (6 downto 0); -- 7 seg digit B : out std_logic; pb : in std_logic; count : out std_logic_vector(3 downto 0); reset :in std_logic ); end entity test; architecture Behavioral of test is signal c: std_logic_vector(3 downto 0) :=(others => '0'); --initializing count to zero. begin counting: process(pb,reset) is begin if rising_edge (pb) then if(c = "1111") then -- when count reaches its maximum(that is 15) reset it to 0 c <="0000"; end if; c <= c+'1'; --increment count at every positive edge of clk. end if; if(reset='0') then --when reset equal to '0' make count equal to 0. c <=(others => '0'); -- c ="0000" end if; case c is when "0000"=>Y<="1000000";-- 0 when "0001"=>Y<="1111001";-- 1 when "0010"=>Y<="0100100";-- 2 when "0011"=>Y<="0110000";-- 3 when "0100"=>Y<="0011001";-- 4 when "0101"=>Y<="0010010";-- 5 when "0110"=>Y<="0000010";-- 6 when "0111"=>Y<="1111000";-- 7 when "1000"=>Y<="0000000";-- 8 when "1001"=>Y<="0010000";-- 9 when "1010"=>Y<="0001000";-- A when "1011"=>Y<="0000011";-- b when "1100"=>Y<="1000110";-- C when "1101"=>Y<="0100001";-- d when "1110"=>Y<="0000110";-- E when "1111"=>Y<="0001110";-- F when others=>Y<="1111111";-- in other cases balnk end case; end process counting; B<='0'; count<=c; end architecture Behavioral; ========================================== - Altera_Forum
Honored Contributor
you shouldn't use the push button as clock input, it isvery unreliable and sensitive to bounces, as you discovered.
Instead, use a regular clock (I'm sure the board has an oscillator you can use) and monitor the pb signal on each clock cycle. You can detect a change on the button status by comparing the current value of pb with the previous one. You will also probably need to implement a delay for proper debouncing. - Altera_Forum
Honored Contributor
Thank you Daixiwen!
I see, anyway i tried to make a delay but nothing seem to work yet, still trying. I'm a beginner, so i'll will be really glad if you can help me with solving upon my code, to understand it better! If its not to much to ask! - Altera_Forum
Honored Contributor
How did you implement the delai? I can for example have a counter increasing from the last time you detected a rising edge, ad you don't take into account a new rising edge before this counter reaches a predetermined value.
- Altera_Forum
Honored Contributor
Hi Daixiwen and thanks,
Sorry for a long time no answer. Finally solved the problem. using the following code: library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity debounce is generic( counter_size : INTEGER := 19); --counter size (19 bits gives 10.5ms with 50MHz clock) port( Digit : out std_logic_vector (6 downto 0); -- 7 seg digit hex_count : out std_logic_vector(3 downto 0); -- Hexadecimal result clk, reset, button : in std_logic; --input signals Digit_en : out std_logic); -- 7 seg digit enable end debounce; architecture logic of debounce is signal counter : std_logic_vector(3 downto 0) :=(others => '0'); --initializing count to zero. signal flipflops : std_logic_vector(1 downto 0); --input flip flops signal counter_out : std_logic_vector(counter_size downto 0) := (others => '0'); --counter output signal counter_set : std_logic; --sync reset to zero signal result : std_logic; --debouncer result begin counter_set <= flipflops(0) xor flipflops(1); --determine when to start/reset counter process(clk) begin if(clk'event and clk = '1') then flipflops(0) <= button; flipflops(1) <= flipflops(0); if(counter_set = '1') then --reset counter because input is changing counter_out <= (others => '0'); elsif(counter_out(counter_size) = '0') then --stable input time is not yet met counter_out <= counter_out + 1; else --stable input time is met result <= not flipflops(1); end if; end if; end process; process(result) begin if(reset='0') then --when reset equal to '0' make count equal to 0. counter <=(others => '0'); -- c ="0000" elsif(result'event and result = '1') then if(counter = "1111") then -- when count reaches its maximum(that is 15) reset it to 0 counter <="0000"; end if; counter <= counter+'1'; --increment count at every positive edge of clk. end if; case counter is when "0000"=>Digit<="1000000";-- 0 when "0001"=>Digit<="1111001";-- 1 when "0010"=>Digit<="0100100";-- 2 when "0011"=>Digit<="0110000";-- 3 when "0100"=>Digit<="0011001";-- 4 when "0101"=>Digit<="0010010";-- 5 when "0110"=>Digit<="0000010";-- 6 when "0111"=>Digit<="1111000";-- 7 when "1000"=>Digit<="0000000";-- 8 when "1001"=>Digit<="0010000";-- 9 when "1010"=>Digit<="0001000";-- A when "1011"=>Digit<="0000011";-- b when "1100"=>Digit<="1000110";-- C when "1101"=>Digit<="0100001";-- d when "1110"=>Digit<="0000110";-- E when "1111"=>Digit<="0001110";-- F when others=>Digit<="1111111";-- in other cases balnk end case; end process; Digit_en<='0'; hex_count<=counter; end;