Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

4x4 keypad matriz

the only problem with the code is the problem with the keyboard rebounds and do not know how to fix it if someone could help me with the code would greatly appreciate it since I am on a project and I could not move through this jam that I have

my code:

----------------------------------------------------------------------

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

entity teclado is

port(

clock,rst : in std_logic;

col_line : in std_logic_vector(3 downto 0);

fila_line : out std_logic_vector(3 downto 0);

display : out std_logic_vector(6 downto 0)

);

end teclado;

architecture archi_teclado of teclado is

signal temp : std_logic_vector(29 downto 0);

CONSTANT max: INTEGER := 50000000;

signal clkout: std_logic;

--CONSTANT med: INTEGER := max/2;

CONSTANT half: INTEGER := max/50000;

SIGNAL count: INTEGER RANGE 0 TO half;

signal temp1: INTEGER RANGE 0 TO 16;

begin

PROCESS

BEGIN

WAIT UNTIL clock'EVENT and clock= '1';

IF (count < max) THEN

count <= count + 1;

ELSE

count <= 0;

END IF;

IF (count < half)THEN

clkout <= '0';

ELSE

clkout <= '1';

END IF;

END PROCESS;

key_driver: process(clkout,rst,temp,temp1)

begin

if(rst='0') then

temp1<=16;

elsif (clkout'event and clkout='1') then

temp <= temp + 1;

-- retraso:=retraso+1;

case temp(10 downto 8) is

when "000" =>

fila_line <= "0111"; --1 fila

when "001" =>

if col_line = "0111" then

-- display <= "0110000"; -- 3

temp1<=13;

elsif col_line = "1011" then

-- display <= "0100100"; -- 2

temp1<=15;

elsif col_line = "1101" then

-- display <= "1111001"; -- 1

temp1<=0;

elsif col_line = "1110" then

-- display <= "1000000"; -- 0

temp1<=14;

end if;

when "010" =>

fila_line <= "1011"; -- 2 fila

when "011" =>

-- if (delay='1') THEN

if col_line = "1110" then

-- display <= "0011001"; -- 4

temp1<=7;

elsif col_line = "1101" then

-- display <= "0010010"; -- 5

temp1<=8;

elsif col_line = "1011" then

-- display <= "0000010"; -- 6

temp1<=9;

elsif col_line = "0111" then

-- display <= "1111000"; -- 7

temp1<=12;

end if;

-- end if;

when "100" =>

fila_line <= "1101"; -- 3 fila

when "101" =>

-- if (delay='1') THEN

if col_line = "1110" then

-- display <= "0000000"; -- 8

temp1<=4;

elsif col_line = "1101" then

-- display <= "0010000"; -- 9

temp1<=5;

elsif col_line = "1011" then

-- display <= "0001000"; -- a

temp1<=6;

elsif col_line = "0111" then

-- display <= "0000011"; -- b

temp1<=11;

end if;

-- end if;

when "110" =>

fila_line <= "1110"; --4 fila

when "111" =>

-- if (delay='1') THEN

if col_line = "1110" then

-- display <= "1000110"; -- C

temp1<=1;

elsif col_line = "1101" then

-- display <= "0100001"; -- d

temp1<=2;

elsif col_line = "1011" then

-- display <= "0000110"; -- e

temp1<=3;

elsif col_line = "0111" then

-- display <= "0001110"; -- f

temp1<=10;

end if;

--end if;

when others => null;

end case;

END IF;

CASE temp1 IS

when 0 => display <="1000000";

when 1 => display <="1111001";

when 2 => display <="0100100";

when 3 => display <="0110000";

when 4 => display <="0011001";

when 5 => display <="0010010";

when 6 => display <="0000010";

when 7 => display <="1111000";

when 8 => display <="0000000";

when 9 => display <="0010000";

when 10 => display <="0001000";

when 11 => display <="0000011";

when 12 => display <="1000110";

when 13 => display <="0100001";

when 14 => display <="0000110";

when 15 => display <="0001110";

when 16 => display <="ZZZZZZZ";

end case;

end process key_driver;

end archi_teclado;

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    From a rapid glimpse to your code I got two major flaws:

    - You defined count with a range 0 to half, but then you increment it up to max which is far beyond the specified range.

    - If indeed your problem is with keyboard rebound you must sample the input signal at a slower rate: for example, assert clkout not when count<value but during a single cycle (i.e. IF (count = 0)THEN clkout <= '0'; ELSE clkout <= '1'; )
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    and if cris 72 the range of the account is reduced to the middle of the clock and change it and I narrowed it down to 5ms as the data sheet the keyboard has a debounce a 5ms approximate only thing that was changed CONSTANT hise half: INTEGER: = max/10000, this amount to an approximation of 5ms :)