Mudanças entre as edições de "Dicas de como eliminar o repique das chaves mecânicas"

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
 
(Uma revisão intermediária pelo mesmo usuário não está sendo mostrada)
Linha 2: Linha 2:
 
*[http://www.labbookpages.co.uk/electronics/debounce.html Como eliminar o repique das chaves (bouncing)].  
 
*[http://www.labbookpages.co.uk/electronics/debounce.html Como eliminar o repique das chaves (bouncing)].  
 
*[https://eewiki.net/pages/viewpage.action?pageId=4980758#DebounceLogicCircuit(withVHDLexample)-ExampleVHDLCode Debounce Logic Circuit (with VHDL example)]
 
*[https://eewiki.net/pages/viewpage.action?pageId=4980758#DebounceLogicCircuit(withVHDLexample)-ExampleVHDLCode Debounce Logic Circuit (with VHDL example)]
==Códigos VHDL==
+
==Como remover o repique de uma chave com circuitos==
 +
;Solução 1 - Schmitt Trigger
 +
:[[Arquivo:Debouncing_TI1.png]]
 +
:[[Arquivo:Debouncing_TI2.png]]
 +
*FONTE: [https://training.ti.com/debounce-switch?context=1134826-1139263-1136870]
 +
 
 +
==Usando circuito descrito em códigos VHDL==
 
;Código de www.labbookpages.co.uk:
 
;Código de www.labbookpages.co.uk:
 
<syntaxhighlight lang=vhdl>
 
<syntaxhighlight lang=vhdl>
 +
--------------------------------------------------------------------------------
 +
--
 +
--  FileName:        SwitchDebouncer.vhd
 +
--------------------------------------------------------------------------------
 +
 
library ieee;
 
library ieee;
 
use ieee.std_logic_1164.all;
 
use ieee.std_logic_1164.all;
Linha 75: Linha 86:
 
;Código 1 de eewiki.net:
 
;Código 1 de eewiki.net:
 
<syntaxhighlight lang=vhdl>
 
<syntaxhighlight lang=vhdl>
 +
-- 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;
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 
;Código 2 de eewiki.net:
 
;Código 2 de eewiki.net:
 
<syntaxhighlight lang=vhdl>
 
<syntaxhighlight lang=vhdl>
 +
--------------------------------------------------------------------------------
 +
--
 +
--  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;
 
</syntaxhighlight>
 
</syntaxhighlight>

Edição atual tal como às 18h53min de 17 de setembro de 2021

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;