VHDL实现矩阵键盘

1.矩阵键盘驱动电路设计

VHDL实现矩阵键盘_第1张图片

2.原理图

VHDL实现矩阵键盘_第2张图片

3.矩阵键盘原理

VHDL实现矩阵键盘_第3张图片

4.矩阵键盘设计思路

VHDL实现矩阵键盘_第4张图片

5.键盘扫描

VHDL实现矩阵键盘_第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;

 全部源代码:https://download.csdn.net/download/qq_36243942/11133917


 

 

 

 

 

 

 

你可能感兴趣的:(VHDL学习笔记)