Dicas de como eliminar o repique das chaves mecânicas

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
A versão imprimível não é mais suportada e pode ter erros de renderização. Atualize os favoritos do seu navegador e use a função de impressão padrão do navegador.

O repique (bouncing) das chaves mecânicas é um processo natural do chaveamento. Em circuitos sensíveis ao repique é necessário eliminá-lo utilizando ou circuitos de hardware analógico, ou software, ou hardware digital. Nos sites a seguir o processo é explicado, e são apresentadas algumas soluções.

Como remover o repique de uma chave com circuitos

Solução 1 - Schmitt Trigger
Debouncing TI1.png
Debouncing TI2.png

Usando circuito descrito em códigos VHDL

Código de www.labbookpages.co.uk
--------------------------------------------------------------------------------
--
--   FileName:         SwitchDebouncer.vhd
--------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity SwitchDebouncer is
	generic (CLK_FREQ			: positive;
				NUM_SWITCHES	: positive);
	port (	clk				: in	std_logic;
				reset				: in	std_logic;
				switchesIn		: in	std_logic_vector(NUM_SWITCHES-1 downto 0);
				switchesOut		: out	std_logic_vector(NUM_SWITCHES-1 downto 0));
end entity;

architecture Structural of SwitchDebouncer is
	signal sample	: std_logic;
begin

	SampleGen : process(clk)
		constant SAMPLE_COUNT_MAX	: integer := (CLK_FREQ / 2000) - 1;	-- 500 us
		variable counter				: integer range 0 to SAMPLE_COUNT_MAX;
	begin
		if (clk'event and clk='1') then
			if (reset='1') then
				sample	<= '0';
				counter	:= 0;
			else
				if (counter=SAMPLE_COUNT_MAX) then
					counter	:= 0;
					sample	<= '1';
				else
					sample	<= '0';
					counter	:= counter + 1;
				end if;
			end if;
		end if;
	end process;

	DebounceGen : for sw in 0 to NUM_SWITCHES-1 generate
		constant PULSE_COUNT_MAX	: integer := 20;
		signal sync						: std_logic_vector(1 downto 0);
		signal counter					: integer range 0 to PULSE_COUNT_MAX;
	begin
		Debounce : process(clk)
		begin
			if (clk'event and clk='1') then
				if (reset='1') then
					sync					<= (others => '0');
					counter				<= 0;
					switchesOut(sw)	<= '0';
				else
					sync <= sync(0) & switchesIn(sw);
					if (sync(1)='0') then		-- Switch not pressed
						counter <= 0;
						switchesOut(sw) <= '0';

					elsif(sample = '1') then	-- Switch pressed
						if (counter=PULSE_COUNT_MAX) then
							switchesOut(sw) <= '1';
						else
							counter <= counter + 1;
						end if;
					end if;
				end if;
			end if;
		end process;
	end generate;
end Structural;
Código 1 de eewiki.net
-- DBounce.vhd
--//////////////////////// Button Debounceer ///////////////////////////--
-- ***********************************************************************
-- FileName: DBounce.vhd
-- FPGA: Microsemi IGLOO AGLN250V2
-- IDE: Libero v9.1.4.0 SP4 
--
-- HDL IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY
-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
-- DIGI-KEY ALSO DISCLAIMS ANY LIABILITY FOR PATENT OR COPYRIGHT
-- INFRINGEMENT.
--
-- Version History
-- Version 1.0 12/06/2011 Tony Storey
-- Initial Public Release
-- Small Footprint Button Debouncer


library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;

entity DBounce is
    Port(
        clk, nreset : in std_logic;
        button_in   : in std_logic;
        DB_out      : buffer std_logic
        );
end DBounce;

architecture arch of DBounce is
    constant N              : integer := 21;   -- 2^20 * 1/(33MHz) = 32ms
    signal q_reg, q_next    : unsigned(N-1 downto 0);
    signal DFF1, DFF2       : std_logic;
    signal q_reset, q_add   : std_logic;
begin

    -- COUNTER FOR TIMING 
    q_next <= (others => '0') when q_reset = '1' else  -- resets the counter 
                    q_reg + 1 when q_add = '1' else    -- increment count if commanded
                    q_reg;  

    -- SYNCHRO REG UPDATE
    process(clk, nreset)
    begin
        if(rising_edge(clk)) then
            if(nreset = '0') then
                q_reg <= (others => '0');   -- reset counter
            else
                q_reg <= q_next;            -- update counter reg
            end if;
        end if;
    end process;

    -- Flip Flop Inputs
    process(clk, button_in)
    begin
        
        if(rising_edge(clk)) then
            if(nreset = '0') then
                DFF1 <= '0';
                DFF2 <= '0';
            else
                DFF1 <= button_in;
                DFF2 <= DFF1;
            end if;
        end if;
    end process;
    q_reset <= DFF1 xor DFF2;           -- if DFF1 and DFF2 are different q_reset <= '1';

    -- Counter Control Based on MSB of counter, q_reg
    process(clk, q_reg, DB_out)
    begin
        
        if(rising_edge(clk)) then
            q_add <= not(q_reg(N-1));        -- enables the counter whe msb is not '1'
            if(q_reg(N-1) = '1') then
                DB_out <= DFF2;
            else
                DB_out <= DB_out;
            end if;
        end if;

    end process;
end arch;
Código 2 de eewiki.net
--------------------------------------------------------------------------------
--
--   FileName:         debounce.vhd
--   Dependencies:     none
--   Design Software:  Quartus II 32-bit Version 11.1 Build 173 SJ Full Version
--
--   HDL CODE IS PROVIDED "AS IS."  DIGI-KEY EXPRESSLY DISCLAIMS ANY
--   WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
--   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
--   PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
--   BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
--   DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
--   PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
--   BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
--   ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
--
--   Version History
--   Version 1.0 3/26/2012 Scott Larson
--     Initial Public Release
--
--------------------------------------------------------------------------------

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(
    clk     : IN  STD_LOGIC;  --input clock
    button  : IN  STD_LOGIC;  --input signal to be debounced
    result  : OUT STD_LOGIC); --debounced signal
END debounce;

ARCHITECTURE logic OF debounce IS
  SIGNAL flipflops   : STD_LOGIC_VECTOR(1 DOWNTO 0); --input flip flops
  SIGNAL counter_set : STD_LOGIC;                    --sync reset to zero
  SIGNAL counter_out : STD_LOGIC_VECTOR(counter_size DOWNTO 0) := (OTHERS => '0'); --counter output
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 <= flipflops(1);
      END IF;    
    END IF;
  END PROCESS;
END logic;