实验报告四位数电子密码锁.docx

上传人:b****5 文档编号:6444356 上传时间:2023-01-06 格式:DOCX 页数:10 大小:99.48KB
下载 相关 举报
实验报告四位数电子密码锁.docx_第1页
第1页 / 共10页
实验报告四位数电子密码锁.docx_第2页
第2页 / 共10页
实验报告四位数电子密码锁.docx_第3页
第3页 / 共10页
实验报告四位数电子密码锁.docx_第4页
第4页 / 共10页
实验报告四位数电子密码锁.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

实验报告四位数电子密码锁.docx

《实验报告四位数电子密码锁.docx》由会员分享,可在线阅读,更多相关《实验报告四位数电子密码锁.docx(10页珍藏版)》请在冰豆网上搜索。

实验报告四位数电子密码锁.docx

实验报告四位数电子密码锁

四位数电子密码锁

一,实验目的

1.学习查找相关资料,并对小型项目开发有一定的认识;

2.掌握能进行模块化设计的能力;

3.学会对各部分电路,进行讨论、说明与仿真验证,最后在整合起来。

二,硬件要求

1、拨位开关。

2、FPGA主芯片:

EP1K30QC208。

3、LED显示模块。

4、4*4键盘。

5、七段数码管

三,实验原理

通过对4×4键盘进行扫描,然后获取其键值,并对其进行编码,从而进行按键的识别,并将相应的按键值进行显示。

键盘扫描的实现过程如下:

对于4×4键盘,通常连接为4行、4列,因此要识别按键,只需要知道是哪一行和哪一列即可,为了完成这一识别过程,我们的思想是,首先固定输出4行为高电平,然后输出4列为低电平,在读入输出的4行的值,通常高电平会被低电平拉低,如果读入的4行均为高电平,那么肯定没有按键按下,否则,如果读入的4行有一位为低电平,那么对应的该行肯定有一个按键按下,这样便可以获取到按键的行值。

同理,获取列值也是如此,先输出4列为高电平,然后在输出4行为低电平,再读入列值,如果其中有哪一位为低电平,那么肯定对应的那一列有按键按下。

获取到行值和列值以后,组合成一个8位的数据,根据实现不同的编码在对每个按键进行匹配。

两功能键:

在开锁状态时,一个用于清除数字,一个用于激活电锁。

在上锁状态,一个用于清除,一个用于解除电锁。

四、实验内容及步骤

1、编写4*4数字密码锁的VHDL代码。

2、用MaxPlusII对其进行编译仿真。

3、在仿真确定无误后,选择芯片ACEX1KEP1K30QC208。

4、给芯片进行管脚绑定,在此进行编译。

5、根据自己绑定的管脚,在实验箱上对键盘接口、显示接口和FPGA之间进行正确连线。

6、给目标板下载代码,在4×4键盘输入键值,观看实验结果。

五、程序代码及说明

LIBRARYIEEE;

USEIEEE.STD_LOGIC_1164.ALL;

USEIEEE.STD_LOGIC_ARITH.ALL;

USEIEEE.STD_LOGIC_UNSIGNED.ALL;

LIBRARYaltera;----这是利用库编译成的去拌电路。

USEaltera.maxplus2.ALL;

entitydebouncingis

port(D_IN,CLK:

INSTD_LOGIC;

D_OUT:

OUTSTD_LOGIC);

ENDDEBOUNCING;

ARCHITECTUREAOFdebouncingIS

SIGNALVCC,INV_D:

STD_LOGIC;

SIGNALD1,D0:

STD_LOGIC;

signalQ0,Q1:

STD_LOGIC;

BEGIN

VCC<='1';

INV_D<=NOTD_IN;

DFF1:

DFFPORTMAP(D=>VCC,Q=>Q0,CLK=>CLK,CLRN=>INV_D,PRN=>VCC);

DFF2:

DFFPORTMAP(D=>VCC,Q=>Q1,CLK=>CLK,CLRN=>Q0,PRN=>VCC);

PROCESS(CLK)

BEGIN

IFCLK'EVENTANDCLK='1'THEN

D0<=NOTQ1;

D1<=D0;

ENDIF;

ENDPROCESS;

D_OUT<=NOT(D1ANDNOTD0);

ENDA;

--***************************************************************

--这里密码锁的主程序

LIBRARYIEEE;

USEIEEE.STD_LOGIC_1164.ALL;

USEIEEE.STD_LOGIC_ARITH.ALL;

USEIEEE.STD_LOGIC_UNSIGNED.ALL;

LIBRARYaltera;

USEaltera.maxplus2.ALL;

--*********************************************

ENTITYelec_lockIS

PORT(

CLK_4M:

INSTD_LOGIC;--systemoriginalclock4M

CLK_SCAN,outnum:

OUTSTD_LOGIC_VECTOR(3downto0);--scansequence

KEY_IN:

INSTD_LOGIC_VECTOR(3downto0);--KEYINbuttoncode

FLAG_NUMB:

OUTSTD_LOGIC;判断按下的是数字键

FLAG_FUNC:

OUTSTD_LOGIC;判断按下的是功能键

ENLOCK:

OUTSTD_LOGIC;--1:

LOCK,0:

UNLOCK

SELOUT:

OUTSTD_LOGIC_VECTOR(2DOWNTO0);---38选择信号

SEGOUT:

OUTSTD_LOGIC_VECTOR(6DOWNTO0)--SEG7Display

);

ENDelec_lock;

--*********************************************

ARCHITECTUREaOFelec_lockIS

componentdebouncing--调用去抖

port(d_in:

INSTD_LOGIC;

clk:

INSTD_LOGIC;

d_out:

OUTSTD_LOGIC);

endcomponent;

SIGNALCLK:

STD_LOGIC;

SIGNALCLK_KEYBOARD:

STD_LOGIC_VECTOR(1downto0);

SIGNALCLK_DEBOUNCE:

STD_LOGIC;

SIGNALCLK_DISPLAY:

STD_LOGIC_VECTOR(1downto0);

SIGNALC:

STD_LOGIC_VECTOR(3downto0);

SIGNALN:

STD_LOGIC_VECTOR(3downto0);

SIGNALF:

STD_LOGIC_VECTOR(3downto0);

SIGNALFN:

STD_LOGIC;

SIGNALFF:

STD_LOGIC;

SIGNALSEL:

STD_LOGIC_VECTOR(3downto0);

SIGNALACC:

STD_LOGIC_VECTOR(15DOWNTO0);

SIGNALREG:

STD_LOGIC_VECTOR(15DOWNTO0);

SIGNALRR2:

STD_LOGIC;--**RR2=Clear

SIGNALQA,QB,BB:

STD_LOGIC;

SIGNALNC:

STD_LOGIC_VECTOR(2DOWNTO0);

SIGNALDB:

STD_LOGIC_VECTOR(3DOWNTO0);--NumberTODisplay

SIGNALSEG:

STD_LOGIC_VECTOR(6DOWNTO0);--SEG7DisplaySignal

BEGIN

--*******************************************连接模块

--CONNECTION

FLAG_NUMB<=FN;

FLAG_FUNC<=FF;

CLK_DEBOUNCE<=CLK;

SELOUT<='0'&CLK_DISPLAY;

SEGOUT(6DOWNTO0)<=SEG;--SevenSegmentDisplay

--*********************************************时钟模块

--scansignalgenerator

counter:

block

SignalQ:

STD_LOGIC_VECTOR(22DOWNTO0);

SignalS:

STD_LOGIC_VECTOR(1DOWNTO0);--keyboardscanabout15Hz***

SIGNALSEL:

STD_LOGIC_VECTOR(3downto0);

BEGIN

PROCESS(Clk_4M)--各种时钟产生

Begin

IFCLK_4M'EventANDCLK_4M='1'then

Q<=Q+1;

ENDIF;

ENDPROCESS;

CLK<=Q(0);--CLK=CLK_DEBOUNCE

CLK_KEYBOARD<=Q(5DOWNTO4);--产生扫描信号-----32分频

CLK_DISPLAY<=Q(5DOWNTO4);用于数码扫描时钟

--Togeneratekeyboardscansequence1110->1101->1011->0111对应一,二,三,四行

SEL<="1110"WHENCLK_KEYBOARD=0ELSE----行扫描

"1101"WHENCLK_KEYBOARD=1ELSE

"1011"WHENCLK_KEYBOARD=2ELSE

"0111";

CLK_SCAN<=SEL;

endblockcounter;

--*********************************************

--debounuingckt

debounuing:

block----消抖处理模块

begin

U1:

debouncingPORTMAP(

d_in=>key_in(0),

d_out=>C(0),

clk=>CLK

);

U2:

debouncingPORTMAP(

d_in=>key_in

(1),

d_out=>C

(1),

clk=>CLK

);

U3:

debouncingPORTMAP(

d_in=>key_in

(2),

d_out=>C

(2),

clk=>CLK

);

U4:

debouncingPORTMAP(

d_in=>key_in(3),

d_out=>C(3),

clk=>CLK

);

ENDblockdebounuing;

--******************************************************

--key_decoder

key_decoder:

block--按键译码模块

signalZ:

std_logic_VECTOR(5downto0);--KEYPOSITION

SIGNALR1,R0:

STD_LOGIC;

begin

PROCESS(clk)

begin

Z<=CLK_KEYBOARD&C;----CLK_KEYBOARD表示键盘行值见时钟模块

IFCLK'EVENTANDCLK='1'THEN----C为处理消抖后键盘列值

caseZis----译码

when"000111"=>N<="0000";--00111

when"001011"=>N<="0001";--11110

when"001101"=>N<="0010";--21110

when"001110"=>N<="0011";--31110

when"010111"=>N<="0100";--41101

when"011011"=>N<="0101";--51101

when"011101"=>N<="0110";--61101

when"011110"=>N<="0111";--71011

when"100111"=>N<="1000";--81011

when"101011"=>N<="1001";--91011

whenothers=>N<="1111";

endcase;

ENDIF;

--****************************

IFCLK'EVENTANDCLK='1'THEN

caseZis

when"101101"=>F<="0100";--*_LOCK--这里只用到两个功能键,最后一行没用到。

when"101110"=>F<="0001";--#_UNLOCK

whenothers=>F<="1000";

endcase;

ENDIF;

endprocess;

FN<=NOT(N(3)ANDN

(2)ANDN

(1)ANDN(0));

FF<=(NOTF(3)ANDF

(2)ANDNOTF

(1)ANDNOTF(0))OR(NOTF(3)ANDNOTF

(2)ANDNOTF

(1)ANDF(0));

--TogenerateclearsignalforACC16位为输入

PROCESS(CLK)

BEGIN

IFCLK'EVENTANDCLK='1'THEN

R1<=R0;R0<=FF;--R0为开或关锁标志

ENDIF;

RR2<=R1ANDNOTR0;--功能标志为0且R1输出为1,表示功能执行完成

CLEAR<=RR2;--开放信号由此而得

ENDPROCESS;

endblockkey_decoder;

--*****************************************************

--KEYIN///BACK///ALLCLEAR---键盘输入处理模块

KEYIN_PROCESS:

BLOCK

SIGNALRST,D0,D1:

STD_LOGIC;

BEGIN

PROCESS(CLK,FN,RST)

BEGIN

IFRST='1'THEN

ACC<="0000000000000000";--CLEARINPUT

NC<="000";---表示显示位数

ELSE

IFFN'EVENTANDFN='1'THEN

IFNC<4THEN---表示显示位数

ACC<=ACC(11DOWNTO0)&N;---实现左移

NC<=NC+1;

ENDIF;

ENDIF;

ENDIF;

ENDPROCESS;

RST<=RR2;

ENDBLOCKKEYIN_PROCESS;

--*********************************************

LOCK_PROCESS:

BLOCK---控制模块

BEGIN

PROCESS(CLK,F)

BEGIN

IF(CLK'EVENTANDCLK='1')THEN

IFNC=4THEN

IFF

(2)='1'THEN--LOCK

REG<=ACC;---------密码存储

QA<='1';QB<='0';---------置关锁标志位

ELSIFF(0)='1'THEN--UNLOCK

IFREG=ACCTHEN--CHECKPINCODE

QB<='1';QA<='0';----------置开锁标志位

ENDIF;

ELSIFACC="0000000100100011"THEN-----------源始密码开锁

--Toset"0123"istheUniversal.pinnumber

QB<='1';QA<='0';

ENDIF;

ENDIF;

ENDIF;

ENDPROCESS;

ENDBLOCKLOCK_PROCESS;

ENLOCK<=QAANDNOTQB;-----锁的标志位1关锁,0打开

--**********************************************

MULTIPLEXER:

BLOCK---多路显示控制处理模块

BEGIN

DB<=ACC(15DOWNTO12)WHENCLK_DISPLAY=0ELSE

ACC(11DOWNTO8)WHENCLK_DISPLAY=1ELSE

ACC(7DOWNTO4)WHENCLK_DISPLAY=2ELSE

ACC(3DOWNTO0)WHENCLK_DISPLAY=3ELSE

"1111";

outnum<=db;

EndBlockMULTIPLEXER;

--**********************************************

SEVEN_SEGMENT:

Block--BinaryCode->Segment7Code---显示模块

Begin

--gfedcba

SEG<="0111111"WHENDB=0ELSE

"0000110"WHENDB=1ELSE

"1011011"WHENDB=2ELSE

"1001111"WHENDB=3ELSE

"1100110"WHENDB=4ELSE

"1101101"WHENDB=5ELSE

"1111101"WHENDB=6ELSE

"0000111"WHENDB=7ELSE

"1111111"WHENDB=8ELSE

"1101111"WHENDB=9ELSE

"0100010";

EndBlockSEVEN_SEGMENT;

ENDa;

仿真结果:

六、实验心得

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1