北邮数字电路综合实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数字电路综合实验报告
简易智能密码锁
一、实验课题及任务要求
设计并实现一个数字密码锁,密码锁有四位数字密码和一个确认开锁按键,密码输入正确,密码锁打开,密码输入错误进行警示。
基本要求:
1、密码设置:通过键盘进行 4 位数字密码设定输入,在数码管上显示所输入数字。
通过密码设置确定键(BTN 键)进行锁定。
2、开锁:在闭锁状态下,可以输入密码开锁,且每输入一位密码,在数码管上显示“-”,提示已输入密码的位数。
输入四位核对密码后,按“开锁”键,若密码正确则系统开锁,若密码错误系统仍然处于闭锁状态,并用蜂鸣器或led 闪烁报警。
3、在开锁状态下,可以通过密码复位键(BTN 键)来清除密码,恢复初始密码“0000”。
闭锁状态下不能清除密码。
4、用点阵显示开锁和闭锁状态。
提高要求:
1、输入密码数字由右向左依次显示,即:每输入一数字显示在最右边的数码管上,同时将先前输入的所有数字向左移动一位。
2、密码锁的密码位数(4~6 位)可调。
3、自拟其它功能。
二、系统设计
2.1系统总体框图
2.2逻辑流程图
2.3MDS图
2.4分块说明
程序主要分为6个模块:键盘模块,数码管模块,点阵模块,报警模块,防抖模块,控制模块。
以下进行详细介绍。
1.键盘模块
本模块主要完成是4×4键盘扫描,然后获取其键值,并对其进行编码,从而进行按键的识别,并将相应的按键值进行显示。
键盘扫描的实现过程如下:对于4×4键盘,通常连接为4行、4列,因此要识别按键,只需要知道是哪一行和哪一列即可,为了完成这一识别过程,我们的思想是,首先固定输出高电平,在读入输出的行值时,通常高电平会被低电平拉低,当当前位置为高电平“1”时,没有按键按下,否则,如果读入的4行有一位为低电平,那么对应的该行肯定有一个按键按
下,这样便可以获取到按键的行值。
同理,获取列值也是如此,先输出4列为高电平,然后在输出4行为低电平,再读入列值,如果其中有哪一位为低电平,那么肯定对应的那一列有按键按下。
由此可确定按键位置。
2.数码管模块
本实验采用六位七段共阴极数码管,通过选通6个位选管脚,向相应的IO 口送低电平来点亮其中任何一位数码管,因为现在采用四位密码锁,所以只是用了其中四个,最高位两位数码管位选全部置1.
如下附上7段共阴极数码管真值表
3.点阵模块
点阵模块,共由8*8*2个发光二极管组成,行低电平有效,列高电平有效。
要求在开锁模式和闭锁模式显示不同的图案,则先将要显示的每幅图像画8*8个小方格的矩形框中,再在有图案下落处的小方格里填上“1”,无图案处填上“0”,这样就形成了与图案所对应的二进制数据在该矩形框上的分布。
当闭锁时以红色点阵显示,此时绿色点阵全部置0,反之亦然。
X
7 8 9 X
4 5 6 X
1 2 3 X X 0 x 消抖 键盘译码 按键储存 键盘扫描
4.报警模块
当报警程序被调用,蜂鸣器输出高电平进行报警,表示输入密码错误
5.防抖
按键输入只有为15ms以上的高电平时才会读出按键值从而消除电路中的抖动。
6.控制中心
lockmode='1表示关锁,此时点阵显示落锁,按任何键都不会显示密码,清零或者开锁,在此时输入密码kwei从0开始不断加1,输入的密码位数在数码管上依次左移,当输入密码m与寄存器中预设密码mm相同时,按下确认键btn2切换为开锁状态,lockmode=0,此时按下btn1表示清零,恢复为初始密码0000,按set键寄存器内密码,按下btnloc切换为关锁状态。
三、仿真波形分析
在QUARTUS2中应用系统自带的功能进行波形仿真,这里采用了分模块仿真。
主程序仿真
在主要功能程序方面波形如下,在初始化模式按下set键系统进入修改密码状态,setmode波形显示高电平。
为仿真方便,仅使kbin(即行输入信号)在1011和1111两个状态下相互转换,在不同的kbout(即列扫描输出信号)下分别对应4、5、6、7四个数字,故密码寄存器m[x]为输入的修改后的密码。
按下btn2(确认键)确认密码后,setmode变为低电平,即修改密码状态结束。
按下btn1时清零,密码寄存器取值还原为0000,至此均为开锁状态下的操作,lockmode 一直为低电平。
按下闭锁键btnloc后,lockmode从0跳变到1,由此进入闭锁模式。
按键消抖模块仿真
当按下键时得到的高电平为输入x,持续一定时间后方可输出一个高电平,而无论按下的时间多长,都只输出一个高电平y,从而实现消除按键电路中的抖动。
分频模块仿真
为仿真方便,改变分频比。
原程序在50Mhz时钟输入下,输出分别为1Mhz、200hz、1000hz、500hz,分别用于键盘扫描、消抖模块输入、点阵扫描以及数码管扫描。
数码管模块仿真
由smgcatout输出可以看出低四位数码管依次选通。
第i位选通时,smgzf为m[i]的七段数码管的译码值。
点阵模块仿真
当lockmode=1时dzcolr全部为0仅dzcolg显示图案;当lockmode=0时dzcolg全部为0由dzcolr显示图案;而dzrow一直在进行行扫描,形成了两种不同颜色点阵。
报警模块仿真
当bj=0时,fmq为0;bj=1时,fmq将clk分频后输出,即蜂鸣器发出声响。
四、源程序
-----------------------顶层文件-------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity lock is
port (clk : in std_logic;
setmode:out std_logic;
lockmode:out std_logic;
set:in std_logic;
btn1,btn2,btnloc:in std_logic;
smgzf: out std_logic_vector(6 downto 0);
smgcatout:out std_logic_vector(5 downto 0);
kbin: in std_logic_vector(3 downto 0);
kbout: buffer std_logic_vector(3 downto 0);
dzrow,dzcolr,dzcolg: out std_logic_vector(7 downto 0);
fmq: out std_logic
);
end lock;
architecture behave of lock is
signal setm: std_logic;
signal lockm: std_logic;
signal lbj: std_logic;
signal lkwei: integer range 0 to 4;
signal lm1,lm2,lm3,lm4:integer range 0 to 9;
signal clk_1: std_logic; --1MHz
signal clk_2: std_logic; --200Hz
signal clk_3: std_logic; --1000Hz
signal clk_4: std_logic; --500Hz
component kb is -----------键盘模块
port (clk : in std_logic;
set:in std_logic;
btn1,btn2,btnloc:in std_logic;
kbin: in std_logic_vector(3 downto 0);
kbout: buffer std_logic_vector(3 downto 0);
bj:out std_logic;
setmod:out std_logic;
lockmod:out std_logic;
kbwei:out integer range 0 to 4;
m1x,m2x,m3x,m4x:out integer range 0 to 9
);
end component;
component smg is -------------数码管显示模块
port (clk : in std_logic;
setmode:in std_logic;
lockmode:in std_logic;
kwei:in integer range 0 to 4;
m1,m2,m3,m4:in integer range 0 to 9;
smgzf: out std_logic_vector(6 downto 0);
smgcatout:out std_logic_vector(5 downto 0)
);
end component;
component dz is -----点阵模块
port (clk : in std_logic;
--set:in std_logic;
lockmode:in std_logic;
dzrow,dzcolr,dzcolg: out std_logic_vector(7 downto 0) );
end component;
component alarm is ------报警模块
port (clk : in std_logic;
bj:in std_logic;
fmq: out std_logic
);
end component;
component fenpin is -------分频模块
port(clk: in std_logic;
clk_out1: out std_logic;
clk_out2: out std_logic;
clk_out3: out std_logic;
clk_out4: out std_logic);
end component;
begin
a1: fenpin
port map(clk=>clk,clk_out1=>clk_1,clk_out2=>clk_2,
clk_out3=>clk_3,clk_out4=>clk_4);
u1: kb
port map(clk => clk,
set => set,
btn1 =>btn1,btn2=>btn2,btnloc=>btnloc,
kbin=>kbin,
kbout=>kbout,
bj=>lbj,
setmod=>setm,
lockmod=>lockm,
kbwei=>lkwei,
m1x=>lm1,m2x=>lm2,m3x=>lm3,m4x=>lm4);
u2 :smg
port map(clk => clk_4,
setmode=>setm,
lockmode=>lockm,
kwei=>lkwei,
m1=>lm1,m2=>lm2,m3=>lm3,m4=>lm4,
smgzf=>smgzf,
smgcatout=>smgcatout);
u3 :dz
port map(clk=>clk_3, lockmode=>lockm ,dzrow=>dzrow, dzcolr=>dzcolg, dzcolg=>dzcolr );
u4 :alarm
port map(clk => clk, bj=>lbj, fmq=>fmq);
setmode<=setm;
lockmode<=lockm;
end;
-----------------------键盘模块-------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity kb is
port (clk : in std_logic;
set:in std_logic;
btn1,btn2,btnloc:in std_logic;
kbin: in std_logic_vector(3 downto 0);
kbout: buffer std_logic_vector(3 downto 0);
bj:out std_logic;
setmod:out std_logic;
lockmod:out std_logic;
kbwei:out integer range 0 to 4;
m1x,m2x,m3x,m4x:out integer range 0 to 9
);
end kb;
architecture behave of kb is
signal jpout:integer range 0 to 10;
signal alarm:std_logic;
signal tmp4: integer range 0 to 2499999;
signal clkfd: std_logic;
signal m1,m2,m3,m4,mm1,mm2,mm3,mm4: integer range 0 to 9; signal wei:integer range 0 to 3;
signal kwei:integer range 0 to 4;
signal setmode:std_logic;
signal lockmode:std_logic;
signal set1:std_logic;
signal clear: std_logic;
signal sure: std_logic;
signal lock: std_logic;
signal en,finish: std_logic;
signal btn1_out, btn2_out, btnloc_out, set_out: std_logic;
signal clk_1: std_logic; --1MHz
signal clk_2: std_logic; --200Hz
component scan is
port(clk_1: in std_logic;
clk_2: in std_logic;
row: in std_logic_vector(3 downto 0);
col: buffer std_logic_vector(3 downto 0);
en_up: buffer std_logic;
y: out integer range 0 to 10);
end component;
component fenpin is
port(clk: in std_logic;
clk_out1: out std_logic;
clk_out2: out std_logic;
clk_out3: out std_logic;
clk_out4: out std_logic);
end component;
component debounce is
port(clk, x: in std_logic;
y: out std_logic);
end component;
begin
setmod<=setmode;
lockmod<=lockmode;
bj<=alarm;
kbwei<=kwei;
m1x<=m1;m2x<=m2;m3x<=m3;m4x<=m4;
u1: scan port map(clk_1=>clk_1, clk_2=>clk_2, row=>kbin, col=>kbout, en_up=>en, y=>jpout);
u2: fenpin port map(clk=>clk, clk_out1=>clk_1, clk_out2=>clk_2, clk_out3=>open,clk_out4=>open);
u3: debounce port map(clk=>clk_2, x=>btn1, y=>btn1_out);
u4: debounce port map(clk=>clk_2, x=>btn2, y=>btn2_out);
u5: debounce port map(clk=>clk_2, x=>btnloc, y=>btnloc_out);
u6: debounce port map(clk=>clk_2, x=>set, y=>set_out);
process(clk)
begin
if(clk'event and clk='1')then
if (tmp4=2499999) then
tmp4<=0;clkfd<=not clkfd;
else
tmp4<=tmp4+1;
end if;
end if;
end process;
process(clk_1,en,jpout)
begin
if(clk_1'event and clk_1='1') then
if(lockmode='1')then ----------闭锁状态下输入密码并读入按键值后存入mm
wei<=0;
if(jpout/=10)then
if(kwei=3)then mm4<=jpout;kwei<=kwei+1;
elsif(kwei=2)then mm3<=jpout;kwei<=kwei+1;
elsif(kwei=1)then mm2<=jpout;kwei<=kwei+1;
elsif(kwei=0)then mm1<=jpout;kwei<=kwei+1;
end if;
end if ;
if(sure='1')then ---------确认后判断密码是否正确
if((mm1=m1)and(mm2=m2)and(mm3=m3)and(mm4=m4)) then lockmode<='0';alarm<='0';----------正确开锁
else kwei<=0;alarm<='1'; ----------错误报警
end if;
end if;
else kwei<=0;---------------开锁状态下
if(lock='1')then --------------上锁
lockmode<='1';
else
if(set1='1')then setmode<='1'; -------修改密码
else setmode<='0';
end if;
if(clear='1') then -----------清零
m1<=0;m2<=0;m3<=0;m4<=0;--mm1<=0;mm2<=0;mm3<=0;mm4<=0;
wei<=0;kwei<=0;alarm<='0'
elsif(setmode='1')then
if(jpout/=10)then ----------------修改密码状态下读入按键值存入m并移位
if(wei=0)then m1<=m2;m2<=m3;m3<=m4;m4<=jpout;wei<=wei+1;
elsif(wei=1)then m1<=m2;m2<=m3;m3<=m4;m4<=jpout;wei<=wei+1;
elsif(wei=2)then m1<=m2;m2<=m3;m3<=m4;m4<=jpout;wei<=wei+1;
elsif(wei=3)then m1<=m2;m2<=m3;m3<=m4;m4<=jpout;wei<=0;
end if;
end if;
if(sure='1')then -----------确认后结束修改密码状态
setmode<='0';alarm<='0';
end if;
end if;
end if;
end if;
end if;
end process;
process(set,sure) --------修改密码键
begin
if(clkfd'event and clkfd='1')then
if(set='1')then
set1<='1';
end if;
if(sure='1')then
set1<='0';
end if;
end if;
end process;
process(btn1) -----------清零键
begin
if(btn1='1')then
clear<='1';
else clear<='0';
end if;
end process;
process(btn2) ----------确认键
begin
if(btn2='1')then
sure<='1';
else sure<='0';
end if;
end process;
process(btnloc) -----闭锁键
begin
if(btnloc='1')then
lock<='1';
else lock<='0';
end if;
end process;
end;
----------------------------键盘扫描-------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity scan is
port(
clk_1: in std_logic;--高频(for scan) 1Mhz clkout1
clk_2: in std_logic; --低频(for debounce) 200hz clkout2
row: in std_logic_vector(3 downto 0);
col: buffer std_logic_vector(3 downto 0);
en_up: out std_logic;
y: out integer range 0 to 10 );
end scan;
architecture a of scan is
signal en: std_logic;
component debounce is
port(clk, x: in std_logic;
y: out std_logic);
end component;
begin
u1: debounce port map(clk=>clk_2, x=>en, y=>en_up);
process(clk_1)
begin
if(clk_1'event and clk_1='1') then ---------列扫描
if(en='1') then
col<="1000";
else
case col is
when "1110" => col<="1101";
when "1101" => col<="1011";
when "1011" => col<="1110";
when others => col<="1110";
end case;
end if;
end if;
end process;
process(clk_1, col, row)
begin
if(clk_1'event and clk_1='1') then
case col is
when "1000" =>
if((row(3) and row(2) and row(1) and row(0))='1') then
en<='0';
end if;
when "1110" =>
case row is
--when "1110" => y<="1111";
when "1101" =>y<=1; en<='1'; --1
when "1011" =>y<=4; en<='1'; --4
when "0111" =>y<=7; en<='1'; --7
when others => y<=10;
end case;
when "1101" =>
case row is
when "1110" =>y<=0; en<='1'; --0
when "1101" =>y<=2; en<='1'; --2
when "1011" =>y<=5; en<='1'; --5
when "0111" =>y<=8; en<='1' ; --8
when others =>y<=10;
end case;
when "1011" =>
case row is
--when "1110" => y<="1111";
when "1101" =>y<=3; en<='1'; --3
when "1011" =>y<=6; en<='1'; --6
when "0111" =>y<=9; en<='1'; --9
when others =>y<=10;
end case;
when others => null;
end case;
end if;
end process;
end a;
----------------------------消抖-------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity debounce is
port(
clk, x: in std_logic; ------------- 200hz低频时钟
y: out std_logic
);
end debounce;
architecture a of debounce is
type state is(s0,s1,s2,s3,s4); ------------5个状态
signal pre_s, next_s: state;
begin
process(clk)
begin
if(clk'event and clk='1') then
pre_s<=next_s;
end if;
end process;
process(pre_s, x) -------输入为连续3个或以上的高电平时,输出一个高电平
begin
case pre_s is
when s0 => -----------初始状态s0
if(x='1') then
next_s<=s1;
else
next_s<=s0;
end if;
y<='0';
when s1 =>
if(x='1') then
next_s<=s2;
else
next_s<=s0;
end if;
y<='0';
when s2 =>
if(x='1') then
next_s<=s3;
else
next_s<=s0;
end if;
y<='0';
when s3 => ------------连续3个高电平,输出一个高电平
y<='1';
next_s<=s4;
when s4 => ----------3个以上高电平,不再继续输出高电平
y<='0';
if(x='1') then
next_s<=s4;
else
next_s<=s0;
end if;
end case;
end process;
end a;
---------------------------分频模块-------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity fenpin is
port(
clk: in std_logic;
clk_out1: out std_logic;
clk_out2: out std_logic;
clk_out3: out std_logic;
clk_out4: out std_logic
);
end fenpin;
architecture div of fenpin is
constant div1: integer:=24;--1Mhz,用于键盘扫描
constant div2: integer:=124999;--200hz,用于消抖
constant div3: integer:=24999;--1000hz,用于点阵扫描constant div4: integer:=49999;--500hz,用于数码管扫描signal c1: integer range 0 to div1;
signal c2: integer range 0 to div2;
signal c3: integer range 0 to div3;
signal c4: integer range 0 to div4;
signal temp1: std_logic;
signal temp2: std_logic;
signal temp3: std_logic;
signal temp4: std_logic;
begin
process(clk)
begin
if(clk'event and clk='1') then
if(c1=div1) then
temp1<=not temp1;
c1<=0;
else
c1<=c1+1;
end if;
if(c2=div2) then
temp2<=not temp2;
c2<=0;
else
c2<=c2+1;
end if;
if(c3=div3) then
temp3<=not temp3;
c3<=0;
else
c3<=c3+1;
end if;
if(c4=div4) then
temp4<=not temp4;
c4<=0;
else
c4<=c4+1;
end if;
end if;
end process;
clk_out1<=temp1;
clk_out2<=temp2;
clk_out3<=temp3;
clk_out4<=temp4;
end div;
------------------------------------数码管-------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity smg is
port (clk : in std_logic; --500hz clkout4
setmode:in std_logic;
lockmode:in std_logic;
kwei:in integer range 0 to 4;
m1,m2,m3,m4:in integer range 0 to 9; ----------四位密码的值 smgzf: out std_logic_vector(6 downto 0); ---------编码值
smgcatout:out std_logic_vector(5 downto 0)
);
end smg;
architecture behave of smg is
signal smgcat:integer range 0 to 5;
signal m1y,m2y,m3y,m4y:std_logic_vector(6 downto 0);
begin
process(clk) -----------位选码
begin
if(clk'event and clk='1')then
if (smgcat=5)then
smgcat<=0;
else
smgcat<=smgcat+1;
end if;
end if;
end process;
process(setmode,lockmode,smgcat)
begin
if(lockmode='0')then
case smgcat is --------------输入密码值在数码管显示,从左到右
when 0=>smgcatout<="110111";smgzf<=m1y;
when 1=>smgcatout<="111011";smgzf<=m2y;
when 2=>smgcatout<="111101";smgzf<=m3y;
when 3=>smgcatout<="111110";smgzf<=m4y;
when 4=>smgcatout<="111111";
when 5=>smgcatout<="111111";
end case;
else
smgzf<="0000001"; --------------输入密码在数码管显示“-” if (kwei=1)then smgcatout<="111110";
elsif (kwei=2)then smgcatout<="111100";
elsif (kwei=3)then smgcatout<="111000";
elsif (kwei=4)then smgcatout<="110000";
else smgcatout<="111111";
end if;
end if;
end process;
process(m1) --------------七段数码管真值表
begin
case m1 is
when 0=>m1y<="1111110";
when 1=>m1y<="0110000";
when 2=>m1y<="1101101";
when 3=>m1y<="1111001";
when 4=>m1y<="0110011";
when 5=>m1y<="1011011";
when 6=>m1y<="1011111";
when 7=>m1y<="1110000";
when 8=>m1y<="1111111";
when 9=>m1y<="1111011";
when others=>m1y<="0000000";
end case;
end process;
process(m2)
begin
case m2 is
when 0=>m2y<="1111110";
when 1=>m2y<="0110000";
when 2=>m2y<="1101101";
when 3=>m2y<="1111001";
when 4=>m2y<="0110011";
when 5=>m2y<="1011011";
when 6=>m2y<="1011111";
when 7=>m2y<="1110000";
when 8=>m2y<="1111111";
when 9=>m2y<="1111011";
when others=>m2y<="0000000";
end case;
end process;
process(m3)
begin
case m3 is
when 0=>m3y<="1111110";
when 1=>m3y<="0110000";
when 2=>m3y<="1101101";
when 3=>m3y<="1111001";
when 4=>m3y<="0110011";
when 5=>m3y<="1011011";
when 6=>m3y<="1011111";
when 7=>m3y<="1110000";
when 8=>m3y<="1111111";
when 9=>m3y<="1111011";
when others=>m3y<="0000000";
end case;
end process;
process(m4)
begin
case m4 is
when 0=>m4y<="1111110";
when 1=>m4y<="0110000";
when 2=>m4y<="1101101";
when 3=>m4y<="1111001";
when 4=>m4y<="0110011";
when 5=>m4y<="1011011";
when 6=>m4y<="1011111";
when 7=>m4y<="1110000";
when 8=>m4y<="1111111";
when 9=>m4y<="1111011";
when others=>m4y<="0000000";
end case;
end process;
end;
------------------------点阵-------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity dz is
port (clk : in std_logic; --1000hz clkout3
lockmode:in std_logic;
dzrow,dzcolr,dzcolg: out std_logic_vector(7 downto 0)
);
end dz;
architecture behave of dz is
signal dzcat:integer range 0 to 7;
begin
process(clk) ----------------------------计数器输出dzcat用于行扫描
begin
if(clk'event and clk='1')then
if (dzcat=7)then
dzcat<=0;
else
dzcat<=dzcat+1;
end if;
end if;
end process;
process(lockmode,clk)
begin
if(lockmode='1')then ----------点阵显示闭锁图形
case dzcat is
when
0=>dzrow<="01111111";dzcolr<="00000000";dzcolg<="00011000";
when
1=>dzrow<="10111111";dzcolr<="00000000";dzcolg<="00100100";
when
2=>dzrow<="11011111";dzcolr<="00000000";dzcolg<="00100100";
when
3=>dzrow<="11101111";dzcolr<="00000000";dzcolg<="01111110";
when
4=>dzrow<="11110111";dzcolr<="00000000";dzcolg<="01111110";
when
5=>dzrow<="11111011";dzcolr<="00000000";dzcolg<="01111110";
when
6=>dzrow<="11111101";dzcolr<="00000000";dzcolg<="01111110";
when
7=>dzrow<="11111110";dzcolr<="00000000";dzcolg<="00000000";
end case;
else -----------------点阵显示开锁图形
case dzcat is
when
0=>dzrow<="01111111";dzcolr<="00000110";dzcolg<="00000000";
when
1=>dzrow<="10111111";dzcolr<="00001001";dzcolg<="00000000";
when
2=>dzrow<="11011111";dzcolr<="00001001";dzcolg<="00000000";
when
3=>dzrow<="11101111";dzcolr<="11111100";dzcolg<="00000000";
when
4=>dzrow<="11110111";dzcolr<="11111100";dzcolg<="00000000";
when
5=>dzrow<="11111011";dzcolr<="11111100";dzcolg<="00000000";
when
6=>dzrow<="11111101";dzcolr<="11111100";dzcolg<="00000000";
when
7=>dzrow<="11111110";dzcolr<="00000000";dzcolg<="00000000";
end case;
end if;
end process;
end;
----------------------------蜂鸣报警-------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity alarm is
port (clk : in std_logic; ---------高频时钟信号
bj:in std_logic; -----------报警使能信号
fmq: out std_logic ----------蜂鸣器输出
);
end alarm;
architecture behave of alarm is
signal beep_1500,beep_750,clktmp,tmp:std_logic;
signal count:std_logic_vector(23 downto 0);
signal beep:std_logic;
begin
process(clk)
begin
if clk'event and clk='1' then
count<=count+'1';
end if;
clktmp<=count(23);
beep_1500<=count(14); ----------分频得到1500hz和750hz的频率用于报警
beep_750<=count(15);
end process;
process(clktmp)
begin
if clktmp'event and clktmp='1' then
tmp <= NOT tmp;
end if;
end process;
process(bj)
begin
if(bj='1')then --------开始报警
if tmp='0' then
beep <= beep_1500;
else beep <= beep_750;
end if;
else beep<='0';
end if;
end process;
process(beep) -------蜂鸣器发声
begin
fmq<=beep;
end process;
end behave;
五、功能说明及资源利用
5.1功能说明
lockmode对应的led灯亮时表示闭锁状态,此时点阵显示落锁图形,按任何键都不会显示密码,清零或者开锁,在此时输入密码kwei从0开始不断加1,输入的密码在数码管上显示为“-”且依次左移,按下确认键btn2后,当输入密码m与寄存器中预设密码mm不同时,蜂鸣器开始报警,当输入密码m与寄存器中预设密码mm相同时,切换为开锁状态,lockmode对应的led灯灭,此时按下btn1表示清零,恢复为初始密码0000;按set键重新设置密码,setmode 对应的led灯亮起,修改完密码后按下确认键btn2,则setmode 对应的led灯灭,退出修改密码状态;按下btnloc切换为关锁状态。
5.2资源利用
元器件清单:计算机,QuartusⅡ软件,MAXⅡ EPM1270T144C5开发板
资源利用情况:经过编译后的编译报告如下
可见使用了304个逻辑单元,用了所有资源的24%;使用了53个PIN口,占所有资源的46%。
六、故障和问题分析
重新设置密码时输入的密码直接显示在密码管上,设置密码完后不确认密码,直接按下闭锁键,则进入闭锁状态,但密码管仍显示密码,与实际情况不符。
后重新修改状态转移的变量控制,使得程序更严谨,更加符合实际生活中的需要。
另一方面,开始时设计的清零程序清零后,按完闭锁键后不输入密码直接按开锁键也可以进入开锁状态。
后检查程序后发现寄存的输入密码也被重置为0000,修改后解决了这个问题。
七、总结及结论
本次实验成功的实现了四位密码锁程序,其功能满足实验要求,还有一些可以改进的地方,如没有实现密码位数可调。
作为第一次用VHDL语言设计的大程序,体会了分块设计的重要性,多个prosses并行发生,只需设计好每个模块的的功能之后统一用顶层文件调用。
在程序设计过程中,我觉得最重要的是要想好要实现的功能和程序本身状态转移的关系,牵一发而动全身,如果随心所欲想到哪编到哪就很容易出现一些逻辑上的bug非常不好解决。
这次的实验考验了我的耐心和细心,也锻炼了独立学习的能力,学会了和同学交流解决问题,巩固了上学期数电实验的知识,拓展了眼界。
如有侵权请联系告知删除,感谢你们的配合!。