vhdl code for debouncing push button

  • Follow


are there any vhdl codes that are available for free to debounce the
pushbutton on my spartan 3E?

I require the push button to generate only 1 clock for 50mhz only upon
release.

I've gotten some code from the net but aint sure if it does what I
need....

==============================================================

library ieee;
use ieee.std_logic_1164.all;

entity debouncer is
	port (clk,reset: in std_logic; -- clk frequency = 50Mhz
			pb: in std_logic;
			pb_debounced: out std_logic
			);
end entity debouncer;

architecture rtl of debouncer is
	signal count500000 : integer range 0 to 499999;
	signal clk_100Hz: std_logic;
	signal pb_sampled: std_logic;
begin

div_100Hz: process(clk,reset) is
begin
	if reset ='1' then
		clk_100Hz <= '0';
		count500000 <= 0;
	elsif rising_edge(clk) then
		if count500000 = 499999 then
			count500000 <= 0;
			clk_100Hz <='1';
		else
			count500000 <= count500000 + 1;
			clk_100Hz <='0';
		end if;
	end if;
end process div_100Hz;

debounce_pb: process(clk) is
begin
	if rising_edge(clk) then
		if clk_100Hz ='1' then
			if pb = pb_sampled then
				pb_debounced <= pb;
			end if;
			pb_sampled <= pb;
		end if;
	end if;
end process debounce_pb;

end architecture rtl;
==================================================

pls advise
0
Reply Zhane 7/27/2008 1:41:06 PM

I think whether this code works for you depends on the push button.  I
have some tactile switches that initially showed *no* bouncing.  After
just a week or two of use they bounce so badly that it is impossible
to debounce them.

The best switch to debounce is a double throw switch.  The FF stays in
a given state until the other contact is made.  Very simple, but it
requires two inputs and a more complex switch.

Rick


On Jul 27, 9:41 am, Zhane <m...@hotmail.com> wrote:
> are there any vhdl codes that are available for free to debounce the
> pushbutton on my spartan 3E?
>
> I require the push button to generate only 1 clock for 50mhz only upon
> release.
>
> I've gotten some code from the net but aint sure if it does what I
> need....
>
> ==============================================================
>
> library ieee;
> use ieee.std_logic_1164.all;
>
> entity debouncer is
>         port (clk,reset: in std_logic; -- clk frequency = 50Mhz
>                         pb: in std_logic;
>                         pb_debounced: out std_logic
>                         );
> end entity debouncer;
>
> architecture rtl of debouncer is
>         signal count500000 : integer range 0 to 499999;
>         signal clk_100Hz: std_logic;
>         signal pb_sampled: std_logic;
> begin
>
> div_100Hz: process(clk,reset) is
> begin
>         if reset ='1' then
>                 clk_100Hz <= '0';
>                 count500000 <= 0;
>         elsif rising_edge(clk) then
>                 if count500000 = 499999 then
>                         count500000 <= 0;
>                         clk_100Hz <='1';
>                 else
>                         count500000 <= count500000 + 1;
>                         clk_100Hz <='0';
>                 end if;
>         end if;
> end process div_100Hz;
>
> debounce_pb: process(clk) is
> begin
>         if rising_edge(clk) then
>                 if clk_100Hz ='1' then
>                         if pb = pb_sampled then
>                                 pb_debounced <= pb;
>                         end if;
>                         pb_sampled <= pb;
>                 end if;
>         end if;
> end process debounce_pb;
>
> end architecture rtl;
> ==================================================
>
> pls advise

0
Reply rickman 7/27/2008 2:49:08 PM


Zhane wrote:

> debounce_pb: process(clk) is
> begin
> 	if rising_edge(clk) then
> 		if clk_100Hz ='1' then
> 			if pb = pb_sampled then
> 				pb_debounced <= pb;
> 			end if;
> 			pb_sampled <= pb;
> 		end if;
> 	end if;
> end process debounce_pb;

Usually every unsychronized external input should be latched. A switch
doesn't change very often, so the probality to cause problems is very low,
but I would add another signal, something like this:

debounce_pb: process(clk) is
begin
	if rising_edge(clk) then
		if clk_100Hz ='1' then
			if pb_latched = pb_sampled then
				pb_debounced <= pb_latched;
			end if;
			pb_sampled <= pb_latched;
			pb_latched <= pb;
		end if;
	end if;
end process debounce_pb;

The rest of the code looks ok. It filters single spikes, which are shorter
than 20ms and filters any bouncing sequence shorter than 10ms. I would add
a generic parameter for specifying the clock frequency to make the entity
more resuable.

-- 
Frank Buss, fb@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
0
Reply Frank 7/27/2008 3:07:07 PM

rickman wrote:
> I think whether this code works for you depends on the push button.  I
> have some tactile switches that initially showed *no* bouncing.  After
> just a week or two of use they bounce so badly that it is impossible
> to debounce them.
> 
> The best switch to debounce is a double throw switch.  The FF stays in
> a given state until the other contact is made.  Very simple, but it
> requires two inputs and a more complex switch.

Yes, a SPCO switch (classic Micro-switch action) is more complex,
as it has an extra contact, but I cannot see
the 'requires two inputs' in any I have used ?

Wire one end to Vcc, one to GND, and the contact to the Pin,
and enable the Pin-Keep if you like, and you are done.

Did you mean a SET/RESET action, which needs two pins, and two
resistors (can be pin-pulldowns) ?

SPCO switches should be the default on demo-boards, as you can
also clock off them...

-jg

0
Reply Jim 7/27/2008 7:51:29 PM

"Zhane" <me75@hotmail.com> wrote in message 
news:ab0ae7bc-b7a5-47bd-bc2e-33d350f3026a@n33g2000pri.googlegroups.com...
> are there any vhdl codes that are available for free to debounce the
> pushbutton on my spartan 3E?
>
> I require the push button to generate only 1 clock for 50mhz only upon
> release.
>
> I've gotten some code from the net but aint sure if it does what I
> need....
>
> ==============================================================
>
> library ieee;
> use ieee.std_logic_1164.all;
>
> entity debouncer is
> port (clk,reset: in std_logic; -- clk frequency = 50Mhz
> pb: in std_logic;
> pb_debounced: out std_logic
> );
> end entity debouncer;
>
> architecture rtl of debouncer is
> signal count500000 : integer range 0 to 499999;
> signal clk_100Hz: std_logic;
> signal pb_sampled: std_logic;
> begin
>
> div_100Hz: process(clk,reset) is
> begin
> if reset ='1' then
> clk_100Hz <= '0';
> count500000 <= 0;
> elsif rising_edge(clk) then
> if count500000 = 499999 then
> count500000 <= 0;
> clk_100Hz <='1';
> else
> count500000 <= count500000 + 1;
> clk_100Hz <='0';
> end if;
> end if;
> end process div_100Hz;
>
> debounce_pb: process(clk) is
> begin
> if rising_edge(clk) then
> if clk_100Hz ='1' then
> if pb = pb_sampled then
> pb_debounced <= pb;
> end if;
> pb_sampled <= pb;
> end if;
> end if;
> end process debounce_pb;
>
> end architecture rtl;
> ==================================================
>
> pls advise

There are a few methods of debouncing switches.

One way of thinking is what's the minimum period between switch operations, 
then having a timer-counter to ensure that another swich operations can't 
occur during this period.

constant integer max := xxxxx;

if reset then
    timer_count = 0;
    pb_debounced = '0';

else rising_edge(clk) then
    if pb = '0' then
        if timer_count = max then
            pb_debounced <= '1';
            timer_count <= 0;
        else
            timer_count <= 0;
        end if;
    else
        if timer_count = max then
            pb_debounced <= '1';
        else
            timer_count <= timer_count +1;
        end if;
    end if;
end if;

E&OE! 


0
Reply Fred 7/28/2008 12:35:02 AM

On Jul 27, 3:51 pm, Jim Granville <no.s...@designtools.maps.co.nz>
wrote:
> rickman wrote:
> > I think whether this code works for you depends on the push button.  I
> > have some tactile switches that initially showed *no* bouncing.  After
> > just a week or two of use they bounce so badly that it is impossible
> > to debounce them.
>
> > The best switch to debounce is a double throw switch.  The FF stays in
> > a given state until the other contact is made.  Very simple, but it
> > requires two inputs and a more complex switch.
>
> Yes, a SPCO switch (classic Micro-switch action) is more complex,
> as it has an extra contact, but I cannot see
> the 'requires two inputs' in any I have used ?
>
> Wire one end to Vcc, one to GND, and the contact to the Pin,
> and enable the Pin-Keep if you like, and you are done.
>
> Did you mean a SET/RESET action, which needs two pins, and two
> resistors (can be pin-pulldowns) ?
>
> SPCO switches should be the default on demo-boards, as you can
> also clock off them...

If you don't have the "pin-keep" (bus-hold) enabled (or available)
what state is the input in while the switch is in transition?  I would
think the input would be floating which is not a good idea.  In
essence, you are asking the capacitance of the input to perform the
bus-hold function.

To be honest, I had to look up a SPCO switch.  It seems to be a three
position switch.  Why do you need three positions?  Wouldn't a SPDT
with break before make do what you are describing?

Rick
0
Reply rickman 7/28/2008 2:13:23 PM

If you have a single-pole double-throw switch with break before make
(or a three-position switch) just connect the center to a pin,and the
two terminals to Vcc and ground. Then, inside the chip make the input
drive the active, non-inverted output on the same pin. That creates a
latch, that you can force either way, and it will respond within about
a nanosecond, and will ignore all bounce. Use the lowest drive
strength setting.
Brute-force shortening the output amy be unconventional, but works
like a champ.
Peter Alfke

0
Reply Peter 7/28/2008 4:30:08 PM

Peter Alfke wrote:

> If you have a single-pole double-throw switch with break before make
> (or a three-position switch) just connect the center to a pin,and the
> two terminals to Vcc and ground. Then, inside the chip make the input
> drive the active, non-inverted output on the same pin. That creates a
> latch, that you can force either way, and it will respond within about
> a nanosecond, and will ignore all bounce. Use the lowest drive
> strength setting.

I was about to comment on the current surge before it switches,
but I suppose at low drive setting it should be fine.  I might
wonder, though, on outputs with only high drive current.

-- glen

0
Reply glen 7/29/2008 4:24:26 AM

glen herrmannsfeldt wrote:
> Peter Alfke wrote:
> 
>> If you have a single-pole double-throw switch with break before make
>> (or a three-position switch) just connect the center to a pin,and the
>> two terminals to Vcc and ground. Then, inside the chip make the input
>> drive the active, non-inverted output on the same pin. That creates a
>> latch, that you can force either way, and it will respond within about
>> a nanosecond, and will ignore all bounce. Use the lowest drive
>> strength setting.
> 
> 
> I was about to comment on the current surge before it switches,
> but I suppose at low drive setting it should be fine.  I might
> wonder, though, on outputs with only high drive current.

That's not a bug, it's a feature!: It does Contact cleaning!! ;)

-jg

0
Reply Jim 7/29/2008 9:09:58 AM

rickman wrote:
> On Jul 27, 3:51 pm, Jim Granville <no.s...@designtools.maps.co.nz>
> wrote:
> 
>>rickman wrote:
>>
>>>I think whether this code works for you depends on the push button.  I
>>>have some tactile switches that initially showed *no* bouncing.  After
>>>just a week or two of use they bounce so badly that it is impossible
>>>to debounce them.
>>
>>>The best switch to debounce is a double throw switch.  The FF stays in
>>>a given state until the other contact is made.  Very simple, but it
>>>requires two inputs and a more complex switch.
>>
>>Yes, a SPCO switch (classic Micro-switch action) is more complex,
>>as it has an extra contact, but I cannot see
>>the 'requires two inputs' in any I have used ?
>>
>>Wire one end to Vcc, one to GND, and the contact to the Pin,
>>and enable the Pin-Keep if you like, and you are done.
>>
>>Did you mean a SET/RESET action, which needs two pins, and two
>>resistors (can be pin-pulldowns) ?
>>
>>SPCO switches should be the default on demo-boards, as you can
>>also clock off them...
> 
> 
> If you don't have the "pin-keep" (bus-hold) enabled (or available)
> what state is the input in while the switch is in transition?  I would
> think the input would be floating which is not a good idea.  In
> essence, you are asking the capacitance of the input to perform the
> bus-hold function.
> 
> To be honest, I had to look up a SPCO switch.  It seems to be a three
> position switch.  Why do you need three positions?  Wouldn't a SPDT
> with break before make do what you are describing?

Yes, SPCO and SPDT are effectively interchangable
(change Over/Double Throw) - The venerable Microswitch has that,
as does the Digitast buttons. Digikey shows those for 28c+cap

-jg

0
Reply Jim 7/29/2008 11:38:35 AM

"Jim Granville" <no.spam@designtools.maps.co.nz> wrote in message 
news:488f0139$1@clear.net.nz...
>
> Yes, SPCO and SPDT are effectively interchangable
> (change Over/Double Throw) - The venerable Microswitch has that,
> as does the Digitast buttons. Digikey shows those for 28c+cap

Hmm SPDT switches come in two varieties.  Break before make and make before 
break.  There is a danger you'll get one where the switch will momentarily 
connect all 3 terminals together for a short period of time.  It's important 
to check and specify you get the right one for this application.


0
Reply Fred 7/29/2008 2:06:40 PM

Fred wrote:
> "Jim Granville" <no.spam@designtools.maps.co.nz> wrote in message 
> news:488f0139$1@clear.net.nz...
> 
>>Yes, SPCO and SPDT are effectively interchangable
>>(change Over/Double Throw) - The venerable Microswitch has that,
>>as does the Digitast buttons. Digikey shows those for 28c+cap
> 
> 
> Hmm SPDT switches come in two varieties.  Break before make and make before 
> break.  There is a danger you'll get one where the switch will momentarily 
> connect all 3 terminals together for a short period of time.  It's important 
> to check and specify you get the right one for this application.

I have yet to see a Microswitch that is MBB. Got any references of
one that is ?
The mechanical design of uSW and closely related Digitast buttons rather 
excludes that.

-jg

0
Reply Jim 7/30/2008 5:09:13 AM

"Jim Granville" <no.spam@designtools.maps.co.nz> wrote in message 
news:488ff776@clear.net.nz...
> Fred wrote:
>> "Jim Granville" <no.spam@designtools.maps.co.nz> wrote in message 
>> news:488f0139$1@clear.net.nz...
>>
>>>Yes, SPCO and SPDT are effectively interchangable
>>>(change Over/Double Throw) - The venerable Microswitch has that,
>>>as does the Digitast buttons. Digikey shows those for 28c+cap
>>
>>
>> Hmm SPDT switches come in two varieties.  Break before make and make 
>> before break.  There is a danger you'll get one where the switch will 
>> momentarily connect all 3 terminals together for a short period of time. 
>> It's important to check and specify you get the right one for this 
>> application.
>
> I have yet to see a Microswitch that is MBB. Got any references of
> one that is ?
> The mechanical design of uSW and closely related Digitast buttons rather 
> excludes that.
>

I agree that many forms of switches are break before make.  The thing is I 
have come across make before break and they have ended up causing grief. 
It's just something I would bear in mind.


0
Reply Fred 7/30/2008 10:33:37 AM

12 Replies
642 Views

(page loaded in 0.13 seconds)

Similiar Articles:


















7/23/2012 7:05:58 PM


Reply: