1.矩阵键盘驱动电路设计
2.原理图
3.矩阵键盘原理
4.矩阵键盘设计思路
5.键盘扫描
6.源代码:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_unsigned.all;
USE IEEE.STD_LOGIC_ARITH.ALL;
entity keyboard is
port(
sysclk : in STD_LOGIC; --ipput->system clock
reset : in STD_LOGIC; --reset signal -> 0 : reset , 1 : normal state
DIG_S,SEG : out std_logic_vector(7 downto 0);
keyh: out STD_LOGIC_vector(4 downto 0);
keyl: in STD_LOGIC_vector(3 downto 0)
);
end entity keyboard;
architecture behav of keyboard is
signal clk : std_logic; --1khz 0.001s
signal clk1 : std_logic; --100hz 0.001s
signal cnt : std_logic_vector ( 15 downto 0); --counter 16bit
signal cnt1 : std_logic_vector ( 5 downto 0);
signal keyl1:std_logic_vector(3 downto 0);
signal flag0,flag1,flag2,flag3,flag4: integer:=4; --init the flags total 5
signal key_value: integer:=17;
signal xs:std_logic_vector ( 7 downto 0);
signal i,j:integer:=0;
signal a,b,c,cge,cshi:integer:=0;
signal a1,b1,cge1,cshi1:std_logic_vector (7 downto 0);
signal ys:integer:=0;
signal bj :std_logic_vector (1 downto 0);
begin
----div the system clock module--
--分频,分出1kHz的时钟 clk--
process( sysclk ,reset ) --process sentiment is sysclk and reset
begin
if reset='0' then
cnt <= "0000000000000000"; --reset enable ,initial the cnt
clk <= '1';
elsif ( sysclk'event and sysclk = '1') then --if system rise edge
cnt <= cnt + 1; -- cnt++
if (cnt = "0110000110101000") then --0110000110101000=25000
cnt <= "0000000000000000"; --clear cnt
clk <= NOT clk ; -- (1/50M) * 25000 =0.0005 s
end if ; -- so th clk cycle is 0.0005s * 2 =0.001 s = 1kHz
end if;
end process ;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--分频,从clk分出100hz的clk1,即为10ms的周期--
process (clk ,reset)
begin
if reset='0' then
cnt1 <= "000000";
clk1 <= '0';
elsif ( clk'event and clk = '1') then
cnt1 <= cnt1 + 1;
if (cnt1 = "0101") then--0101
cnt1 <= "000000";
clk1 <= NOT clk1 ;
end if ;
end if;
end process ;
--键盘扫描进程--
process (clk1)
variable count:integer:=0; --define a variable
begin
if clk1'event and clk1='1' then --rising edge
if (flag0=4 and flag1=4 and flag2=4 and flag3=4 and flag4=4) then
keyl1<="1111";keyh<="11111";
keyh(i)<='0';
keyl1<=keyl; --read the col value
for n in 0 to 3 loop
if(keyl1(n)='0') then
if(i=0) then flag0<=n;
elsif(i=1) then flag1<=n;
elsif(i=2) then flag2<=n;
elsif(i=3) then flag3<=n;
elsif(i=4) then flag4<=n;
end if;
end if;
end loop;
i<=i+1;
if(i=4) then i<=0;
end if;
end if;
if(flag0<4) then
case (flag0) is
when 0 => key_value<=10;
when 1 => key_value<=11;
when 2 => key_value<=12;
when 3 => key_value<=13;
when others => key_value<=17;
end case;flag0<=4;
end if;
if(flag1<4) then
case (flag1) is
when 0 => key_value<=7;
when 1 => key_value<=8;
when 2 => key_value<=9;
when 3 => key_value<=14;
when others => key_value<=17;
end case;flag1<=4;
end if;
if(flag2<4) then
case (flag2) is
when 0 => key_value<=4;
when 1 => key_value<=5;
when 2 => key_value<=6;
when others => key_value<=17;
end case;flag2<=4;
end if;
if(flag3<4) then
case (flag3) is
when 0 => key_value<=1;
when 1 => key_value<=2;
when 2 => key_value<=3;
when 3 => key_value<=15;
when others => key_value<=17;
end case;flag3<=4;
end if;
if(flag4<4) then
case (flag4) is
when 1 => key_value<=0;
when 2 => key_value<=16;
when others => key_value<=17;
end case;flag4<=4;
end if;
if(key_value < 17) then --如果数值小于17说明有按键按下--
a<=key_value; --把按键的值赋值给a,第一次按下得到a的值,并在进程中显示--
key_value<=17; --退出之后重新赋值key_value=17,开始下一次扫描--
end if;
end if;
end process;
process(a,b,cge,cshi)
begin
case a is
when 0 => a1<="11000000";
when 1 => a1<="11111001";
when 2 => a1<="10100100";
when 3 => a1<="10110000";
when 4 => a1<="10011001";
when 5 => a1<="10010010";
when 6 => a1<="10000010";
when 7 => a1<="11011000";
when 8 => a1<="10000000";
when 9 => a1<="10010000";
when 16=> a1<="01111111";
when others => a1<="11111111";
end case;
end process;
process(clk,j)
begin
if clk'event and clk='1' then
DIG_S<="11111110";
SEG<= a1;
end if;
end process;