1. 程式人生 > >VHDL實現矩陣鍵盤檢測

VHDL實現矩陣鍵盤檢測

矩陣鍵盤相比獨立鍵盤,其實就是起到節約IO口的作用,尤其在需要多個按鍵的時候。原理圖(摘自其他地方):


比如0鍵,沒按下時,ROW0因為上拉而為高電平。當0按下時,如果此時COL0為低電平,則ROW0為低電平。因此矩陣鍵盤就是要讓幾列(或行)輪流置零,並檢測行(或列)的電平高低,從而確定某一按鍵是否按下。這就是掃描過程。

以下是VHDL程式碼:

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity matrix is

port(clk:in std_logic;

row: in std_logic_vector(3 downto 0);

col:out std_logic_vector(3 downto 0);

keyout:out std_logic_vector(3 downto 0);

flag:out std_logic);

end matrix;

architecture behave of matrix is

signal colreg: std_logic_vector(3 downto 0);

signal con:std_logic_vector(7 downto 0);

signal cnt:std_logic_vector(15 downto 0);

signal clkreg:std_logic;

begin

--分頻,在1~10KHZ左右的時鐘進行鍵盤掃描--

process(clk)

begin

if clk'event and clk = '1' then

if cnt = "1100001101001111" then

cnt<="0000000000000000";

clkreg<='0';

else if cnt = "0110000110100111" then

cnt<=cnt+"0000000000000001";

clkreg<='1';

else

cnt<=cnt+"0000000000000001";

end if;

end if;

end process;

--產生列掃描訊號--

process(clkreg)

begin

if clkreg'event and clkreg = '1' then

case colreg is

when "1110" => colreg<="1101";

when "1101" => colreg<="1011";

when "1011" => colreg<="0111";

when "0111" => colreg<="1110";

when others => colreg<="1110";

end case;

end if;

end process;

--對行訊號和列訊號進行組合--

col<=colreg;

con<= colreg & row;

--對組合的掃描訊號進行判斷,並輸出按鍵指示訊號以及編碼--

process(clkreg)

begin

if clkreg'event and clkreg = '1' then

case con is

when "11101110" => keyout<="0000";flag<='1';

when "11011110" => keyout<="0001";flag<='1';

when "10111110" => keyout<="0010";flag<='1';

when "01111110" => keyout<="0011";flag<='1';

when "11101101" => keyout<="0100";flag<='1';

when "11011101" => keyout<="0101";flag<='1';

when "10111101" => keyout<="0110";flag<='1';

when "01111101" => keyout<="0111";flag<='1';

when "11101011" => keyout<="1000";flag<='1';

when "11011011" => keyout<="1001";flag<='1';

when "10111011" => keyout<="1010";flag<='1';

when "01111011" => keyout<="1011";flag<='1';

when "11100111" => keyout<="1100";flag<='1';

when "11010111" => keyout<="1101";flag<='1';

when "10110111" => keyout<="1110";flag<='1';

when "01110111" => keyout<="1111";flag<='1';

when "11101111" => flag<='0';

when "11011111" => flag<='0';

when "10111111" => flag<='0';

when "01111111" => flag<='0';

end case;

end if;

end process;

end behave;