Ir al contenido principal

Pulsador antirebote en VHDL (debouncing)

El uso de actuadores mecánicos como los pulsadores, tiene muchas ventajas, sobre todo económicas, ya que son muy baratos. Sin embargo, precisamente por su naturaleza mecánica, vienen acompañados de ciertos problemas que dependiendo del uso que hagamos de ellos, pueden llegar a ser un verdadero quebradero de cabeza. El mayor de estos inconvenientes es el rebote o bouncing.

Al ser accionados, los pulsadores tardan cierto tiempo en alcanzar un estado estable, es decir, que durante muy poco tiempo (del orden de los milisengundos) pueden cambiar entre el estado pulsado y no pulsado hasta que la señal se estabiliza. A pesar de ser muy poco tiempo, es el suficiente para que un sistema digital lo detecte como varias pulsaciones. La siguiente imagen muestra una señal de rebote típica.

Bounce o rebote

Hay varias aproximaciones para solucionar este problema, tanto hardware como software (si estamos trabajando con microcontroladores). En este artículo vamos a ver cómo atajar este problema desde el punto de vista hardware y más concretamente con VHDL.

Obviamente, hablamos de un circuito secuencial que debe recordar si el botón estaba pulsado en un momento anterior y compararlo con el estado actual, así que es necesario el uso de biestables o flip flops. La idea general es que si durante un periodo de tiempo lo suficientemente amplio (unos 10 u 11 milisegundos) el valor actual del pulsador y el valor del flip flop que almacena el estado anterior son iguales, podemos dar por sentado que el pulsador ha llegado a un estado de pulsación estable. El siguiente código VHDL implementa dicho circuito.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity debouncer_top is
    port (
        clk	: in std_logic;
	btn_in	: in std_logic;
	btn_out	: out std_logic);
end debouncer_top;
architecture beh of debouncer_top is
    constant CNT_SIZE : integer := 19;
    signal btn_prev   : std_logic := '0';
    signal counter    : std_logic_vector(CNT_SIZE downto 0) := (others => '0');
    begin
    process(clk)
    begin
	if (clk'event and clk='1') then
		if (btn_prev xor btn_in) = '1' then
			counter <= (others => '0');
			btn_prev <= btn_in;
		elsif (counter(CNT_SIZE) = '0') then
			counter <= counter + 1;
        	else
			btn_out <= btn_prev;
		end if;
	end if;
    end process;
end beh;

La señal btn_prev es el biestable encargado de almacenar el estado anterior (entiéndase, el estado en el pulso de reloj anterior). Para contar el tiempo se usa un contador de 20 bits (enseguida veremos por qué de 20 y no de otro tamaño). Dentro del proceso, en cada pulso de reloj se comprueba mediante una puerta xor si el valor del pulsador es diferente al del pulso de reloj previo. Si es así, el contador se pone a cero y vuelve a comenzar la cuenta de tiempo, si no, se incrementa el contador, salvo que su último bit sea 1, en cuyo caso, ha pasado el tiempo suficiente como para dar por hecho que la pulsación ya es estable. Si este es el caso, ponemos el valor del biestable btn_prev en btn_out (que es otro biestable que se conecta a la salida del circuito).

El tamaño del contador se ha ajustado para una frecuencia de reloj de 50 MHz. En general, el tiempo que se consigue según el tamaño del contador se puede aproximar con la siguiente fórmula.

Tamaño del contador

Siendo n el número de bits del contador. Así pues, en este caso tenemos un reloj de 50 MHz y un contador de 20 bits. Como en realidad el contador no va a contar hasta el final sino hasta que su bit más significativo sea 1, podemos usar un valor n=19 como una aproximación más que aceptable.

Tiempo contador

Por lo tanto, estamos dejando un margen de algo más de 10 milisegundos para que se estabilice el pulsador. Un valor muy razonable para un pulsador normal.

Comentarios

Entradas populares de este blog

Creando firmas de virus para ClamAV

ClamAv es un antivirus opensource y multiplataforma creado por Tomasz Kojm muy utilizado en los servidores de correo Linux. Este antivirus es desarrollado por la comunidad, y su utilidad práctica depende de que su base de datos de firmas sea lo suficientemente grande y actualizado. Para ello es necesario que voluntarios contribuyan activamente aportando firmas. El presente artículo pretende describir de manera sencilla cómo crear firmas de virus para ClamAV y contribuir con ellas a la comunidad.

Ingeniería inversa de un parche de Microsoft Windows

A estas alturas ya hemos asumido que la seguridad total en Internet es, cuanto menos, un mito. Ningún software está libre de vulnerabilidades, y por mucha auditoría, test de intrusión o pruebas de fuzzing que nos empeñemos en hacer, ninguna metodología puede demostrar sin lugar a dudas que un software es 100% seguro. Ante este panorama, hay dos tendencias mayoritarias a la hora de hacer públicas las vulnerabilidades. Por un lado, están los que piensan que cuando se descubre un fallo ha de hacerse público de forma inmediata. En este escenario, la publicación de una vulnerabilidad es el pistoletazo de salida para una carrera entre el desarrollador para sacar el parche y los "malos" para lograr explotarla. Esta política es conocida como full disclosure . Por otro lado, tenemos a los siguen una política responsible disclosure , que abogan por mantener la vulnerabilidad en secreto hasta la salida del parche por parte del desarrollador. Sin entrar en cuestiones filosóficas que no...

Scripts en NMAP

Cuando pensamos en NMAP, pensamos en el escaneo de puertos de un host objetivo al que estamos relizando una prueba de intrusión, pero gracias a las posibilidades que nos ofrecen su Scripting Engine , NMAP es mucho más que eso. Antes de continuar, un aviso: algunas de posibilidades que nos ofrecen los scripts de NMAP son bastante intrusivas, por lo que recomiendo hacerlas contra hosts propios, máquinas virtuales como las de Metasploitable, o contrato de pentesting mediante. Para este artículo voy a usar las máquinas de Metasploitable3 . No voy a entrar en los detalles sobre el uso básico de NMAP, ya que hay miles de tutoriales en Internet que hablan sobre ello. Lo cierto es que NMAP tiene algunas opciones que permiten obtener información extra, además de qué puertos están abiertos y cuales no. Por ejemplo, la opción -sV trata de obtener el servicio concreto, e incluso la versión del servicio que está corriendo en cada puerto. Otro ejemplo es la opción -O, que intenta averiguar el ...