首先对矩阵键盘的每个按键进行编码,编码如图一所示(0000、0001、…、1110、1111)。由于COL通过电阻上拉到VCC,因此当没有键被按下时,COL的值为”1111”;当有键被按下(假设被按下的键是编码为”0000”的键),FPGA输出的行扫描信号ROW连续为”1110” => “1101” => “1011” => “0111”,当ROW等于”1110”即ROW0为低时,COL0也为低,则表示FPGA判断出编码为”0000”的按键被按下,FPGA输出有按键被按下的指示信号和该按键的编码。
VHDL代码如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity matrikeyscan is
port( clk : in std_logic; --系统时钟输入
col : in std_logic_vector(3 downto 0); --列扫描输入
row : out std_logic_vector(3 downto 0); --行扫描输出
keyout : out std_logic_vector(3 downto 0); --按键编码输出
putdown : out std_logic); --按键批示信号,’1’表示有键被按下,’0’表示没有键--被按下
end matrikeyscan;
architecture behave of matrikeyscan is
signal rowreg : 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';
elsif 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 rowreg is
when "1110" => rowreg <= "1101";
when "1101" => rowreg <= "1011";
when "1011" => rowreg <= "0111";
when "0111" => rowreg <= "1110";
when others => rowreg <= "1110";
end case;
end if;
end process;
--
--对行扫描信号和列扫描信号进行组合。
row <= rowreg;
con <= rowreg & col;
--
--对行扫描信号和列扫描信号进行CASE语句判断。得到是否有键被按下,输出按键按--键指示信号和按键的编码
process(clkreg)
begin
if clkreg'event and clkreg = '1' then
case con is
when "11101110" => keyout <= "0000"; putdown <= '1';
when "11101101" => keyout <= "0001"; putdown <= '1';
when "11101011" => keyout <= "0010"; putdown <= '1';
when "11100111" => keyout <= "0011"; putdown <= '1';
when "11011110" => keyout <= "0100"; putdown <= '1';
when "11011101" => keyout <= "0101"; putdown <= '1';
when "11011011" => keyout <= "0110"; putdown <= '1';
when "11010111" => keyout <= "0111"; putdown <= '1';
when "10111110" => keyout <= "1000"; putdown <= '1';
when "10111101" => keyout <= "1001"; putdown <= '1';
when "10111011" => keyout <= "1010"; putdown <= '1';
when "10110111" => keyout <= "1011"; putdown <= '1';
when "01111110" => keyout <= "1100"; putdown <= '1';
when "01111101" => keyout <= "1101"; putdown <= '1';
when "01111011" => keyout <= "1110"; putdown <= '1';
when "01111111" => putdown <= '0';
when "11101111" => putdown <= '0';
when "11011111" => putdown <= '0';
when "10111111" => putdown <= '0';
when "01111111" => putdown <= '0';
when others => null;
end case;
end if;
end process;
end behave;
用户315677 2010-12-16 22:03