Establezca una señal alta constante a baja

1

Tengo un circuito de teclado, cuando presiono y sostengo una tecla, la señal "tecla presionada" siempre es alta, siempre y cuando mantenga presionada la tecla, lo cual es normal, cuando lo dejo, vuelve a bajar. Pero no quiero que esta señal esté constantemente alta, no importa cuánto tiempo presione la tecla, me gustaría que me detectaran como una sola pulsación corta. En otros medios, debería encontrar una manera de establecer esta tecla presionada en bajo después de digamos 10 ms. Estoy haciendo todo en VHDL, sin condensadores de resistencias ... Tampoco puedo esperar a que caiga el borde, entonces no tiene sentido, no se mostrará ninguna tecla en la pantalla LCD hasta que se suelte la tecla, lo cual no tiene sentido.

    
pregunta Anarkie

3 respuestas

2

Necesita un detector de bordes ascendente . Esto se hace generando una entrada retrasada que es 1 ciclo de reloj posterior a la entrada real.

Por ejemplo:

               ____     ____     ____     ____     ____     ____     ____     ____      
CLock      ___/    \___/    \___/    \___/    \___/    \___/    \___/    \___/    \

               _______________________________
Input      ___/                               \____________________________________
                        _______________________________
Input_z    ____________/                               \___________________________ 

                 ^ You want to detect this point, where the signals are not the
                   same. Input has gone high, but because Input_z is delayed, it 
                   isn't high yet 

La entrada retrasada se genera de la siguiente manera:

gen_input_z : process(clk,rst) 
begin
    if (rst = '1') then
        Input_z <= '0';
    elsif (rising_edge(clk)) then
        Input_z <= Input;
    end if;
end process

Ahora desea detectar su flanco ascendente:

gen_edge_det : process(clk,rst) 
begin
    if (rst = '1') then
        Edge_detect <= '0';
    elsif (rising_edge(clk)) then
        if (Input = '1' and Input_z = '0') then
            Edge_detect <= '1';
        else 
            Edge_detect <= '0';
        end if;
    end if;
end process

Pero ahora nuestra detección de bordes es solo un ciclo de reloj:

               ____     ____     ____     ____     ____     ____     ____     ____      
CLock      ___/    \___/    \___/    \___/    \___/    \___/    \___/    \___/    \

               _______________________________
Input      ___/                               \____________________________________
                        _______________________________
Input_z    ____________/                               \___________________________ 
                        ________
Edge_det   ____________/        \__________________________________________________

Para modificar eso, agregue un contador que solo haga que la detección de bordes caiga después de un cierto número de ciclos de reloj:

-- Port Declarations
signal clk         : in std_logic;
signal rst         : in std_logic;
signal input       : in std_logic;

-- Signal declarations
signal input_z     : std_logic;
signal edge_detect : std_logic;
signal counter     : unsigned(31 downto 0); -- include numeric_std for this


gen_edge_det : process(clk,rst) 
begin
    if (rst = '1') then
        Edge_detect <= '0';
        counter     <= '0';
        input_z     <= '0';
    elsif (rising_edge(clk)) then
        input_z <= input;
        if (Input = '1' and Input_z = '0') then
            Edge_detect <= '1';
            counter     <= (others => '0');
        elsif (counter < 2) then          -- we want an edge detect of 2 clock cycles 
            Edge_detect <= '1';
            counter     <= counter + "1"; -- declare counter as unsigned.
        else
            Edge_detect <= '0';
        end if;
    end if;
end process

Ahora está haciendo lo que queremos:

               ____     ____     ____     ____     ____     ____     ____     ____      
CLock      ___/    \___/    \___/    \___/    \___/    \___/    \___/    \___/    \

               _______________________________
Input      ___/                               \____________________________________
                        _______________________________
Input_z    ____________/                               \___________________________ 
                        _____________
Edge_det   ____________/             \_____________________________________________
    
respondido por el stanri
3

La forma en que hago esto en el firmware es detectar un cambio en la entrada (después de rechazar el ruido y el rebote) y luego generar un evento basado en la pulsación de una tecla o incluso en la liberación de una tecla para cada tecla.

Luego puede usar los eventos de presionar y soltar teclas, junto con los temporizadores para realizar todas las funciones habituales que asocia con las teclas en la electrónica moderna. Mantenga presionada la tecla durante 3 segundos para entrar en un modo especial, Mantenga presionada la tecla, luego suéltela para bloquear un ajuste de codificador o lo que sea.

Editar: en función de sus cambios, en el caso de usar VHDL (hardware), esto se puede lograr con un reloj y flip-flops. Simplemente compare la entrada X con una versión retrasada de la entrada X '. Eso le dará un pulso de un reloj para el flanco ascendente de entrada (y, si lo desea, un pulso de un reloj para el flanco descendente de entrada). Funciona igual en un HDL que en un código secuencial.

    
respondido por el Spehro Pefhany
1

Yo diría que estás buscando un multivibrador monoestable. Puede hacerlos desde un temporizador 555, o usar un chip dedicado. Para TTL, está disponible como el componente 74xx123. Funcionan al detectar un borde y emitir un pulso de duración programable. Puede configurar los parámetros de pulso con resistencias externas y tapas, si no recuerdo mal. Tire hacia arriba de una hoja de datos. Deben contener circuitos de ejemplo para que te cortes los dientes.

    
respondido por el Jason_L_Bens

Lea otras preguntas en las etiquetas