library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--------------------------------------------------------------------
entity exp19 is
port( Clk : in std_logic; --时钟信号
Rst : in std_logic; --复位信号
Kr : in std_logic_vector(3 downto 0); --键盘行
Kc : buffer std_logic_vector(3 downto 0); --键盘列
SPK : out std_logic; --扬声器输出
KEY_State : out std_logic; --按键指示
Door : buffer std_logic; --门状态
Display : out std_logic_vector(7 downto 0); --七段码管显示
SEG_SEL : buffer std_logic_vector(2 downto 0)); --七段码管片选
end exp19;
--------------------------------------------------------------------
architecture behave of exp19 is
signal keyr,keyc : std_logic_vector(3 downto 0);
signal kcount : std_logic_vector(2 downto 0);
signal kflag1,kflag2 : std_logic;
signal buff1,buff2,buff3,buff4,buff5,buff6 : integer range 0 to 15;
signal push_num : integer range 0 to 15; --按键次数
signal Disp_Temp : integer range 0 to 15;
signal Disp_Decode : std_logic_vector(7 downto 0);
signal SEC1,SEC10 : integer range 0 to 9;
signal Clk_Count1 : std_logic_vector(3 downto 0); --1KHz时钟分频计数器
signal Clk_Count2 : std_logic_vector(9 downto 0); --2Hz时钟分频计数器
signal Clk1KHz : std_logic;
signal Clk2Hz : std_logic;
signal Clk1Hz : std_logic;
signal Error_Num : integer range 0 to 3;
signal Error_Flag : std_logic;
signal Error_Count : std_logic_vector(2 downto 0);
signal Music_Count : std_logic_vector(2 downto 0);
begin
process(Clk)
begin
if(Clk'event and Clk='1') then
if(Clk_Count1<10) then
Clk_Count1<=Clk_Count1+1;
else
Clk_Count1<="0001";
end if;
end if;
end process;
Clk1KHz<=Clk_Count1(2);
process(Clk1KHz)
begin
if(Clk1KHz'event and Clk1KHz='1') then
if(Clk_Count2<1000) then
Clk_Count2<=Clk_Count2+1;
else
Clk_Count2<="0000000001";
end if;
end if;
end process;
Clk2Hz<=Clk_Count2(9);
process(Clk2Hz)
begin
if(Clk2Hz'event and Clk2Hz='1') then
Clk1Hz<=not Clk1Hz;
end if;
end process;
process(Clk1KHz) --扫描键盘
begin
if(Clk1KHz'event and Clk1KHz='1') then
if(Kr="1111") then
kflag1<='0';
kcount<=kcount+1;
if(kcount=0) then
kc<="1110";
elsif(kcount=1) then
kc<="1101";
elsif(kcount=2) then
kc<="1011";
else
kc<="0111";
end if;
else
kflag1<='1';
keyr<=Kr;
keyc<=Kc;
end if;
kflag2<=kflag1;
end if;
end process;
KEY_State<=kflag1;
process(Clk1KHz,Rst) --扫描键盘
begin
if(Rst='0') then
push_num<=0;
elsif(Clk1KHz'event and Clk1KHz='1') then
if(push_num=6) then
push_num<=0;
elsif(kflag1='0' and kflag2='1') then
push_num<=push_num+1;
end if;
end if;
end process;
process(Clk1KHz,Rst) --密码校验
begin
if(Rst='0') then
Door<='0';
Error_Num<=0;
Error_Flag<='0';
elsif(Clk1KHz'event and Clk1KHz='1') then
if(push_num=5 and Error_Num<3) then
--修改此处的值可修改门的密码,此处密码为123456
if(buff1=1 and buff2=2 and buff3=3 and buff4=4 and buff5=5 and buff6=6) then
Door<='1';
else
Door<='0';
end if;
elsif(push_num=6 and Error_Num<3) then
if(Door='0') then
Error_Flag<='1';
Error_Num<=Error_Num+1;
else
Error_Flag<='0';
Error_Num<=0;
end if;
elsif(Error_Count=4) then
Error_Flag<='0';
elsif(Error_Flag='1') then
Door<=not Error_Count(0);
end if;
end if;
end process;
process(Clk2Hz,Rst)
begin
if(Rst='0' or Error_Flag<='0') then
Error_Count<="000";
elsif(Clk2Hz'event and Clk2Hz='1' and Error_Flag<='1') then
Error_Count<=Error_Count+1;
end if;
end process;
process(Clk) --报警声音分频
begin
if(Clk'event and Clk='1') then
Music_Count<=Music_Count+1;
end if;
end process;
process(Clk) --超出错误次数,开始报警
begin
if(Error_Num>=3) then
if(Clk1Hz='1') then
SPK<=Music_Count(2);
else
SPK<=Music_Count(1);
end if;
end if;
end process;
process(Clk1KHz,Rst) --显示右移
begin
if(Rst='0' or push_num=0) then --复位时,全灭
buff1<=15;
buff2<=15;
buff3<=15;
buff4<=15;
buff5<=15;
elsif(Clk1KHz'event and Clk1KHz='1') then
if(kflag1='1' and kflag2='0' and (((keyr="1110" or keyr="1011")and keyc/="0111")or keyr="1101")) then
buff1<=buff2;
buff2<=buff3;
buff3<=buff4;
buff4<=buff5;
buff5<=buff6;
end if;
end if;
end process;
process(Clk1KHz,Rst) -- 获取键值
begin
if(Rst='0' or push_num=6) then --全灭
buff6<=15;
elsif(Clk1KHz'event and Clk1KHz='1') then
if(kflag1='1' and kflag2='0') then
if(keyr="1110") then
case keyc is
when "1110"=>buff6<=1;
when "1101"=>buff6<=4;
when "1011"=>buff6<=7;
when others=>buff6<=buff6; --no change
end case;
elsif(keyr="1101") then
case keyc is
when "1110"=>buff6<=2;
when "1101"=>buff6<=5;
when "1011"=>buff6<=8;
when "0111"=>buff6<=0;
when others=>buff6<=buff6; --no change
end case;
elsif(keyr="1011") then
case keyc is
when "1110"=>buff6<=3;
when "1101"=>buff6<=6;
when "1011"=>buff6<=9;
when others=>buff6<=buff6; --no change
end case;
end if;
end if;
end if;
end process;
process(SEG_SEL)
begin
case (SEG_SEL+1) is
when "000"=>Disp_Temp<=10; --'-'
when "001"=>Disp_Temp<=buff1;
when "010"=>Disp_Temp<=buff2;
when "011"=>Disp_Temp<=buff3;
when "100"=>Disp_Temp<=buff4;
when "101"=>Disp_Temp<=buff5;
when "110"=>Disp_Temp<=buff6;
when "111"=>Disp_Temp<=10; --'1'
end case;
end process;
process(Clk)
begin
if(Clk'event and Clk='1') then --扫描累加
SEG_SEL<=SEG_SEL+1;
Display<=Disp_Decode;
end if;
end process;
process(Disp_Temp) --显示转换
begin
case Disp_Temp is
when 0=>Disp_Decode<="00111111
评论0