Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20706 Discussions

DE2 Quartus debounced circuit

Altera_Forum
Honored Contributor II
3,657 Views

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.
0 Kudos
15 Replies
Altera_Forum
Honored Contributor II
2,069 Views

Normally there are delayed timer double check circuit and state machine circuit used as debouncer. 

You will find spending a while on google.
0 Kudos
Altera_Forum
Honored Contributor II
2,069 Views

Actually, I believe DE2 switches are debounced with a 74HC245. You should not see multiple inputs for a single button depression. Remember that the switches (or 'key's) are active high. When you push the button it will be low for the period of time that you have it depressed (which even if you push it very quickly will be many thousands of clock cycles). But you will not see it oscillate between a one and a zero after it is depressed (you can prove this to yourself by building a simple SignalTap file and analyzing the operation in hardware). In order to ensure your circuit operates appropriately I would suggest that you watch for the switch (or key) to go from a low to a high (the switches are a logic 1 when not depressed). This will ensure that a single button press results in your code executing only once. If you post your code snippet, then I will have a look...

0 Kudos
Altera_Forum
Honored Contributor II
2,069 Views

Hi, I'm actually using pushbuttons on an external circuit and not the pushbuttons on the DE2. I'm going to build debounced circuitry in Quartus to fix it. Thanks for the reply.

0 Kudos
Altera_Forum
Honored Contributor II
2,069 Views

Kofinator, 

 

Please post your reference design when you're done if you don't mind sharing.
0 Kudos
Altera_Forum
Honored Contributor II
2,069 Views

am working on a design project and have a DE2-70 board.I want to control on board LEDS 

from my PC. 

How can I make dialogue based application using NIOS II IDE.
0 Kudos
Altera_Forum
Honored Contributor II
2,069 Views

In case it's useful, this is a general purpose filter I use for IO pins. Debouncing is a special case. The logic is very tight and fast. You'll need to adjust the freq, limit, and N to suit your needs. 

module filter(input clock, input in, output reg out, // out a filtered version of in output reg strobe); // true for one cycle synchronous with a change parameter freq = 25_000_000; // 25MHz parameter limit = 50_000; // 50kHz parameter dur = freq / limit; parameter N = 14; // INV: 2**N > dur; reg countdown; // Filter out any meta stability reg in_, in__; always @(posedge clock) begin strobe <= 0; in_ <= in; in__ <= in_; if (in__ == out) countdown <= dur - 1; // Note, we depend on countdown being reset here. else if (~countdown) countdown <= countdown - 1; else begin out <= ~out; strobe <= 1; end end endmodule
0 Kudos
Altera_Forum
Honored Contributor II
2,069 Views

Oops. I used the wrong version. 

 

Please change "if (in__ == out)" to "if (in__ != out)". 

 

Also, rather than "out <= ~out;" using the equivalent "out <= in__;" may be more readable. 

 

Tommy
0 Kudos
Altera_Forum
Honored Contributor II
2,069 Views

Hi, 

 

Everytime I see code with parameters, some manual action has to be done for setting the bit-width of a register (counter).  

 

There is a nice trick with a 'constant-function' to prevednt this action :  

 

change this :  

 

parameter N = CLogB2(dur);  

 

and add :  

 

//ceil of the log base 2 function integer CLogB2; input Depth; integer i; begin i = Depth; for(CLogB2 = 0; i > 0; CLogB2 = CLogB2 + 1) i = i >> 1; end endfunction
0 Kudos
Altera_Forum
Honored Contributor II
2,069 Views

Thanks. There were two reasons I didn't use such a function: it would have distracted from the main point, and my simulator doesn't (didn't?) support functions.

0 Kudos
Altera_Forum
Honored Contributor II
2,069 Views

Try www.veritak.com. It's really worth its 50$

0 Kudos
Altera_Forum
Honored Contributor II
2,068 Views

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; 

==========================================
0 Kudos
Altera_Forum
Honored Contributor II
2,069 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
2,069 Views

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!
0 Kudos
Altera_Forum
Honored Contributor II
2,069 Views

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.

0 Kudos
Altera_Forum
Honored Contributor II
2,069 Views

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;
0 Kudos
Reply