课程设计fpga密码锁.docx
《课程设计fpga密码锁.docx》由会员分享,可在线阅读,更多相关《课程设计fpga密码锁.docx(13页珍藏版)》请在冰豆网上搜索。
![课程设计fpga密码锁.docx](https://file1.bdocx.com/fileroot1/2023-2/8/c7de21af-695d-4e6f-960b-d7e8224d15da/c7de21af-695d-4e6f-960b-d7e8224d15da1.gif)
课程设计fpga密码锁
FPGA实验报告
实验名称:
FPGA课程设计
实验日期:
2013年6月3日
姓名:
学号:
一、实验目的
1.设计一个密码锁
2.加深FPGA电路原理的理解
3.掌握VHDL语言的使用,学会用VHDL语言来编程解决实际问题
4.学会使用EDA开发软件设计小型综合电路,掌握仿真的技巧
5.学会应用开发系统实现硬件电路,检验电路的功能
二、实验内容
题目:
电子密码锁
内容:
设计一个4位串行数字锁
1.开锁代码为4位二进制,当输入代码的位数与锁内给定的密码一致,且按规定程序开锁时,方可开锁。
否则进入“错误”状态,发出报警信号。
2.锁内的密码可调,且预置方便,保密性好。
3.串行数字锁的报警,直到按下复位开关,才停下。
此时,数字锁又自动等待下一个开锁状态。
三、实验步骤
1.系统总框图
本系统的硬件部分主要由密码锁按键消抖模块,密码输入比较更改模块,密码显示模块、报警模块组成。
整体系统框图如下图所示。
2.密码锁的主要功能
密码锁控制器的主要功能有:
(1)密码输入:
有二个按键来控制(分别代表0和1),每按下一个键,要求在数码管上显示,并依次左移。
(2)密码校验:
如果有按键按下,直到松开该按键,如果密码校验正确,无变化,否则如果密码校验错误蜂鸣器响,表明密码错误。
(3)错误报警:
密码输入错误开始报警。
(4)密码修改:
输入密码正确后按按键输入要设置和更改的密码,按按键确认密码设置与更改,则密码设置成功。
3.密码锁的各个模块
(1)按键消抖。
每按下一个键,仅产生一个信号脉冲,作为按键的使能信号,使能信号控制显示的数字。
(2)密码输入比较
密码输入值的比较主要有两部分,密码位数和内容,任何一个条件不满足,都不能打开锁。
锁内密码为“0000”,key2和key1置低电平,分别表示输入“1”和“0”。
输入密码前先按start键,再依次正确输入0000,会在数码管逐一显示,按确认键,经检验,输入的密码等于锁内预先设置的密码密码锁开启信号,锁开启。
同时,可以进行密码修改。
若在输入密码的过程中,4位二进制密码出现输入错误,那么锁不能开启,同时,蜂鸣器发出报警信号。
直到按下复位开关,报警才停止。
此时,数字锁又自动进入等待下一次开锁的状态。
(3)密码修改
为防止任意进行密码修改,必须在正确输入密码后,才能重新设置密码。
输入正确密码后,锁打开,就可直接进行修改密码的操作。
修改密码实质就是用输入的新密码去取代原来的旧密码,按确定按键ok,存储新密码。
(4)报警
对50M晶振进行分频,实现对蜂鸣器的控制
(5)数码显示
八段数码管是电子开发过程中常用的输出显示设备。
在本设计中使用的是8个四位一体、共阴极型八段数码管。
其单个静态数码管如下图所示。
由于八段数码管公共端连接到VCC(共阳极型),当数码管的中的一个段被输入低电平,则相应的这一段被点亮。
反之则不亮。
四位一体的八段数码管在单个静态数码管的基础上加入了用于选择哪一位数码管的位选信号端口。
八个数码管的a、b、c、d、e、f、g、h、dp都连在了一起,8个数码管分别由各自的位选信号来控制,被选通的数码管显示数据,其余关闭。
单个数码管管脚示意图
本实验通过计数信号count控制数码管亮的个数,用temp信号控制数码管的动态扫描显示,以实现每输入一位密码,数码管显示左移一位。
4.软件仿真
(1)密码输入正确时,蜂鸣器不响,beep=1。
(默认密码为0000),仿真图如下:
(2)密码输入错误时(0001),蜂鸣器响,beep=0。
(默认密码为0000),仿真图如下:
四、实验总结
这次密码锁的设计过程表明,用VHDL可以快速、灵活地设计出符合要求的密码锁控制器,而且操作简单。
可以实现密码输入、密码校验、密码设置和更改等功能。
设计过程能够在设计完成后在QuartusⅡ环境下进行电路的模拟仿真,反馈结果可以验证程序设计的可行性与可靠性。
本密码锁控制器设置的是4位密码,在系统复位后,输入一个完整的密码串,输入完后,系统会进行比对,如果发现密码吻合,则开门,如果输入的密码串都是错误的,则系统报警。
这样的设计可以很好的满足人们的日常需求。
同时,密码锁还具有密码修改功能,方便操作,使得密码锁的使用更加安全、便捷。
在软件、硬件设计和仿真过程中间我们也遇到不少问题,但最终还是把它们解决了,使得设计符合要求。
除了自己思考设计之外,这与和同学的同心协力的合作与讨论是分不开的的。
相互的探讨使得我们的思路更加开阔,解决问题的办法也更多。
总之,此次课程设计让我收益良多,同时因为有了实践操作,对EDA技术能够更好的掌握和应用了。
附:
VHDL程序总代码
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_arith.all;
useieee.std_logic_unsigned.all;
entitylockis
port(
key1,key2:
instd_logic;--按键
clk,start,ok:
instd_logic;--时钟,开始,确定,复位
beep:
outstd_logic:
='1';--正确,蜂鸣器信号
dig:
outstd_logic_vector(7downto0);--数码管片选信号
seg:
outstd_logic_vector(7downto0)--数码管片内显示
);
endlock;
architecturert1oflockis
signalkeyin,password:
std_logic_vector(3downto0):
="0000";--输入密码,密码
signalopen1:
std_logic:
='0';--开锁信号
signalbeep1,keyen1,keyen2:
std_logic:
='1';--蜂鸣器信号
signalshuru:
std_logic;--输入信号
signalcount:
std_logic_vector(2downto0):
="000";--计数输入密码的位数
signaltemp:
std_logic_vector(1downto0):
="00";
begin
process(clk,key1)
variablem:
integerrange0to250000;--按键消抖
begin
ifclk'eventandclk='1'then
ifkey1='0'then
ifm=250000thenm:
=m;
elsem:
=m+1;
endif;
ifm=249999thenkeyen1<='0';
elsekeyen1<='1';
endif;
elsem:
=0;
endif;
endif;
endprocess;
process(clk,key2)
variablea:
integerrange0to250000;--按键消抖
begin
ifclk'eventandclk='1'then
ifkey2='0'then
ifa=250000thena:
=a;
elsea:
=a+1;
endif;
ifa=249999thenkeyen2<='0';
elsekeyen2<='1';
endif;
elsea:
=0;
endif;
endif;
endprocess;
process(clk,start,ok)--密码输入,比较,修改模块
begin
ifclk'eventandclk='1'then
ifstart='0'then
shuru<='1';count<="000";keyin<="0000";open1<='0';beep1<='1';
endif;
ifshuru='1'then
ifcount="000"then
ifkeyen1='0'then
keyin(0)<='0';
count<=count+1;
elsifkeyen2='0'then
keyin(0)<='1';
count<=count+1;
endif;
endif;
ifcount="001"then
ifkeyen1='0'then
keyin
(1)<='0';
count<=count+1;
elsifkeyen2='0'then
keyin
(1)<='1';
count<=count+1;
endif;
endif;
ifcount="010"then
ifkeyen1='0'then
keyin
(2)<='0';
count<=count+1;
elsifkeyen2='0'then
keyin
(2)<='1';
count<=count+1;
endif;
endif;
ifcount="011"then
ifkeyen1='0'then
keyin(3)<='0';
count<=count+1;
shuru<='0';
elsifkeyen2='0'then
keyin(3)<='1';
count<=count+1;
shuru<='0';
endif;
endif;
endif;
ifok='0'andopen1='0'then
if(keyin=password)andcount="100"then
open1<='1';shuru<='1';
else
beep1<='0';open1<='0';
endif;
endif;
ifok='0'andopen1='1'then
count<="000";
password<=keyin;
endif;
endif;
endprocess;
process(clk,start,ok)--报警模块
variableg:
integerrange0to25000;
begin
ifclk'eventandclk='1'then
ifg=25000then
g:
=0;
else
g:
=g+1;
endif;
ifg<=12500andbeep1='0'then
beep<='0';
else
beep<='1';
endif;
endif;
endprocess;
process(clk)
variablen:
integerrange0to2500;--计数模块
begin
ifclk'eventandclk='1'then
ifn=2500then
n:
=0;
iftemp="11"then
temp<="00";
else
temp<=temp+1;
endif;
else
n:
=n+1;
endif;
endif;
endprocess;
process(clk)--数码管显示模块
begin
ifclk'eventandclk='1'then
ifcount="001"then
casetempis
when"00"=>dig<="01111111";
ifkeyin(0)='0'thenseg<="11000000";
elseseg<="11111001";endif;
whenothers=>seg<="11111111";
endcase;
elsifcount="010"then
casetempis
when"00"=>dig<="01111111";
ifkeyin
(1)='0'thenseg<="11000000";
elseseg<="11111001";endif;
when"01"=>dig<="10111111";
ifkeyin(0)='0'thenseg<="11000000";
elseseg<="11111001";endif;
whenothers=>seg<="11111111";
endcase;
elsifcount="011"then
casetempis
when"00"=>dig<="01111111";
ifkeyin
(2)='0'thenseg<="11000000";
elseseg<="11111001";endif;
when"01"=>dig<="10111111";
ifkeyin
(1)='0'thenseg<="11000000";
elseseg<="11111001";endif;
when"10"=>dig<="11011111";
ifkeyin(0)='0'thenseg<="11000000";
elseseg<="11111001";endif;
whenothers=>seg<="11111111";
endcase;
elsifcount="100"then
casetempis
when"00"=>dig<="01111111";
ifkeyin(3)='0'thenseg<="11000000";
elseseg<="11111001";endif;
when"01"=>dig<="10111111";
ifkeyin
(2)='0'thenseg<="11000000";
elseseg<="11111001";endif;
when"10"=>dig<="11011111";
ifkeyin
(1)='0'thenseg<="11000000";
elseseg<="11111001";endif;
when"11"=>dig<="11101111";
ifkeyin(0)='0'thenseg<="11000000";
elseseg<="11111001";endif;
whenothers=>null;
endcase;
else
dig<="11111111";seg<="11111111";
endif;
endif;
endprocess;endrt1;