--
-- 矩阵键盘实验1:向用户介绍矩阵键盘扫描实现的方法,没有考虑去抖和判断键弹起的问题;把相应的键值显示在数码管上
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY KEYSCAN IS
PORT (
clk : IN std_logic;
rst : IN std_logic;
row : OUT std_logic_vector(3 DOWNTO 0); -- 行线
column : IN std_logic_vector(3 DOWNTO 0); -- 列线
dataout : OUT std_logic_vector(7 DOWNTO 0); -- 数码管显示数据
en : OUT std_logic); --数码管显示
使能 END KEYSCAN;
ARCHITECTURE arch OF KEYSCAN IS
SIGNAL div_cnt : std_logic_vector(24 downto 0);
SIGNAL scan_key : std_logic_vector(3 DOWNTO 0); --扫描码
寄存器 SIGNAL key_code : std_logic_vector(3 DOWNTO 0);
SIGNAL dataout_tmp : std_logic_vector(7 DOWNTO 0);
BEGIN
row <= scan_key;
dataout <= dataout_tmp;
en <= "0";
PROCESS(clk,rst)
BEGIN
IF (NOT rst = "1") THEN
div_cnt <= "0000000000000000000000000";
ELSIF(clk"EVENT AND clk = "1")THEN
div_cnt <= div_cnt + 1;
END IF;
END PROCESS;
PROCESS(div_cnt(20 downto 19))
BEGIN
CASE div_cnt(20 downto 19) IS
WHEN "00"=> scan_key<="1110";
WHEN "01"=> scan_key<="1101";
WHEN "10"=> scan_key<="1011";
WHEN "11"=> scan_key<="0111";
END CASE;
END PROCESS;
PROCESS(clk,rst)
BEGIN
IF (NOT rst = "1") THEN
key_code <= "0000";
ELSIF(clk"EVENT AND clk="1")THEN
CASE scan_key IS --检测何处有键按下
WHEN "1110" =>
CASE column IS
WHEN "1110" =>
key_code <= "0000";
WHEN "1101" =>
key_code <= "0001";
WHEN "1011" =>
key_code <= "0010";
WHEN "0111" =>
key_code <= "0011";
WHEN OTHERS =>
NULL;
END CASE;
WHEN "1101" =>
CASE column IS
WHEN "1110" =>
key_code <= "0100";
WHEN "1101" =>
key_code <= "0101";
WHEN "1011" =>
key_code <= "0110";
WHEN "0111" =>
key_code <= "0111";
WHEN OTHERS =>
NULL;
END CASE;
WHEN "1011" =>
CASE column IS
WHEN "1110" =>
key_code <= "1000";
WHEN "1101" =>
key_code <= "1001";
WHEN "1011" =>
key_code <= "1010";
WHEN "0111" =>
key_code <= "1011";
WHEN OTHERS =>
NULL;
END CASE;
WHEN "0111" =>
CASE column IS
WHEN "1110" =>
key_code <= "1100";
WHEN "1101" =>
key_code <= "1101";
WHEN "1011" =>
key_code <= "1110";
WHEN "0111" =>
key_code <= "1111";
WHEN OTHERS =>
NULL;
END CASE;
WHEN OTHERS =>
key_code <= "1111";
END CASE;
END IF;
END PROCESS;
-----显示键值
PROCESS(key_code)
BEGIN
CASE key_code IS
WHEN "0000" =>
dataout_tmp <= "00000011";
WHEN "0001" =>
dataout_tmp <= "10011111";
WHEN "0010" =>
dataout_tmp <= "00100101";
WHEN "0011" =>
dataout_tmp <= "00001101";
WHEN "0100" =>
dataout_tmp <= "10011001";
WHEN "0101" =>
dataout_tmp <= "01001001";
WHEN "0110" =>
dataout_tmp <= "01000001";
WHEN "0111" =>
dataout_tmp <= "00011111";
WHEN "1000" =>
dataout_tmp <= "00000001";
WHEN "1001" =>
dataout_tmp <= "00011001";
WHEN "1010" =>
dataout_tmp <= "00010001";
WHEN "1011" =>
dataout_tmp <= "11000001";
WHEN "1100" =>
dataout_tmp <= "01100011";
WHEN "1101" =>
dataout_tmp <= "10000101";
WHEN "1110" =>
dataout_tmp <= "01100001";
WHEN "1111" =>
dataout_tmp <= "01110001";
WHEN OTHERS =>
NULL;
END CASE;
END PROCESS;
END arch;