Cómo contar las teclas presionadas en el tablero spartan FPGA

0

Estoy usando la placa FPGA Spartan 2 y quiero contar las teclas presionadas desde el teclado este es mi código VHDL:

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

ENTITY Keyboard IS
 PORT(CLOCK : IN STD_LOGIC;
      RESET : IN STD_LOGIC;
      RK : IN STD_LOGIC_VECTOR(3 DOWNTO 1);
      DE : OUT STD_LOGIC_VECTOR(3 DOWNTO 1);
      Invalid_Key : OUT STD_LOGIC := '0';
      Seg1 : OUT STD_LOGIC_VECTOR(7 Downto 0);
      Seg2 : OUT STD_LOGIC_VECTOR(7 Downto 0);
      LEDRow1 : OUT STD_LOGIC_VECTOR(7 Downto 0);
      LEDRow2 : OUT STD_LOGIC_VECTOR(7 Downto 0);       
      Key : OUT STD_LOGIC_VECTOR(0 TO 15));
END Keyboard;

Architecture Behavier OF Keyboard IS
 Signal CLK : STD_LOGIC_VECTOR(23 DOWNTO 0);
 Signal KC : STD_LOGIC_VECTOR(1 DOWNTO 0);
 Signal KEY_PUSH : STD_LOGIC_VECTOR(4 DOWNTO 0);
 Signal KeyTemp : STD_LOGIC_VECTOR(1 TO 16) := "0000000000000000";
 Signal Counter : STD_LOGIC_VECTOR(4 downto 0) := "00000";
Begin
 DE(3) <= '0';
 DE(2 DOWNTO 1) <= KC;
 KEY_PUSH <= KC & RK;

 Process(KEY_PUSH)
 begin
  Case KEY_PUSH is
   WHEN "11101" => --0
    if Counter <= 15 then
      Invalid_Key <= '0';
      Counter <= Counter + 1;
     KeyTemp(conv_integer(Counter)) <= '0';           
    else
     Invalid_Key <= '1';
    end if;
   WHEN "00110" => --1
    if Counter <= 15 then
      Invalid_Key <= '0';
     Counter <= Counter + 1;
      KeyTemp(conv_integer(Counter)) <= '1';
    else
     Invalid_Key <= '1';
    end if;

   WHEN "00101" =>
    Invalid_Key <= '1';  -- 2
   WHEN "00011" =>
    Invalid_Key <= '1';  -- 3
   WHEN "01110" =>
    Invalid_Key <= '1';  -- 4
   WHEN "01101" =>
    Invalid_Key <= '1';  -- 5
   WHEN "01011" =>
    Invalid_Key <= '1';  -- 6
   WHEN "10110" =>
    Invalid_Key <= '1';  -- 7
   WHEN "10101" =>
    Invalid_Key <= '1';  -- 8
   WHEN "10011" =>
    Invalid_Key <= '1';  -- 9
   WHEN "11011" => -- #
    Invalid_Key <= '1';  -- #   

   WHEN "11110" => -- *
     Invalid_Key <= '0';
    KeyTemp <= "0000000000000000";
    Counter <= "00000";
   WHEN OTHERS =>   
    Invalid_Key <= '0';
  End Case;

   case Counter is
    when "00000" => -- 0
     Seg1 <= "00111111";
      Seg2 <= "00111111";
    when "00001" => -- 1
     Seg1 <= "00111111";
      Seg2 <= "00000110";
    when "00010" => -- 2
     Seg1 <= "00111111";
      Seg2 <= "01011011";
    when "00011" => -- 3
     Seg1 <= "00111111";
      Seg2 <= "01001111";
    when "00100" => -- 4
     Seg1 <= "00111111";
      Seg2 <= "01100110";
    when "00101" => -- 5
     Seg1 <= "00111111";
      Seg2 <= "01101101";
    when "00110" => -- 6
     Seg1 <= "00111111";
      Seg2 <= "01111101";
    when "00111" => -- 7
     Seg1 <= "00111111";
      Seg2 <= "00100111";
    when "01000" => -- 8
     Seg1 <= "00111111";
      Seg2 <= "01111111";
    when "01001" => -- 9
     Seg1 <= "00111111";
      Seg2 <= "01101111";
    when "01010" => -- 10
     Seg1 <= "00000110";
      Seg2 <= "00111111";
    when "01011" => -- 11
     Seg1 <= "00000110";
      Seg2 <= "00000110";
    when "01100" => -- 12
     Seg1 <= "00000110";
      Seg2 <= "01011011";
    when "01101" => -- 13
     Seg1 <= "00000110";
      Seg2 <= "01001111";
    when "01110" => -- 14
     Seg1 <= "00000110";
      Seg2 <= "01100110";
    when "01111" => -- 15
     Seg1 <= "00000110";
      Seg2 <= "01101101";
    when "10000" => -- 16
     Seg1 <= "00000110";
      Seg2 <= "01111101";
    when others =>
     Seg1 <= "00000000";
     Seg2 <= "00000000";      
   end case;

  LEDRow1 <= KeyTemp(1 to 8);
  LEDRow2 <= KeyTemp(9 to 16);  

  if Counter = 16 then
   Key <= KeyTemp;
  end if;
 End Process;

 Process(CLOCK, CLK)
 begin
  IF (Clock'EVENT AND Clock='1') THEN
   Clk <= Clk + 1;
  END IF;    
 end Process;   

 Process(Reset, CLK(10))
 begin
  IF RESET = '1' THEN
   KC <= "00";
  ELSIF (CLK(10) 'EVENT AND CLK(10)='1') THEN 
   KC <= KC + 1;    
  END IF;
 end Process;   
END Behavier;

solo las teclas 1 y 0 son aceptables

Quiero mostrar el valor del contador en 2 segmentos y mostrar los 0 y 1 en dos líneas de LED Matrix, pero hay un problema en el contador, creo que el problema es "Key_PUSH" o "RK" están cambiando muchas veces cuando presiona una tecla.

¿Cómo puedo crear un contador para las teclas presionadas?

    
pregunta G3ntle_Man

2 respuestas

1

Los interruptores mecánicos rebotan cuando se presionan. Su software necesita rebotar la pulsación de tecla antes de considerarla válida. Por lo general, esto consiste en retrasar 30-70 ms después de que se detecte la presión inicial de la tecla y volver a verificar el interruptor. Si aún está encendido, cuéntelo como un cierre de interruptor.

Es posible que a veces tenga que esperar hasta que se suelte el interruptor (lo que se llama detección del borde posterior) para que su lógica no cuente el mismo cierre del interruptor más de una vez.

    
respondido por el Glenn W9IQ
1

Tiene un error en su código cuando intenta realizar una asignación en lugar de una evaluación condicional:

  

si Contador < = 15 entonces

Supongo que esto debería ser:

if Counter = 15 then

pero, no he leído toda la lógica de su código.

Su lista de sensibilidad de procesos necesita trabajo.

Además, posiblemente deba rebotar el interruptor, como se indica en la otra respuesta, dependiendo de la velocidad de su reloj y de si ya se ha rebotado en el DSK (o en cualquier placa que esté usando).

    
respondido por el Blair Fonville

Lea otras preguntas en las etiquetas