- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Normally there are delayed timer double check circuit and state machine circuit used as debouncer.
You will find spending a while on google.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Kofinator,
Please post your reference design when you're done if you don't mind sharing.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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; ==========================================- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page