目 录
第1章 实验简介 .............................................................................................. 1 1.1课题背景 .................................................................................................. 1 1.2 研究意义 ................................................................................................. 1 1.3 本文主要内容 ........................................................................................ 1 第2章 硬件电路设计 ..................................................................................... 2 2.1相关芯片简介 ......................................................................................... 3 2.2 仿真电路总体设计 ............................................................................... 5 第3章 软件编程设计 ..................................................................................... 6 3.1系统概述 .................................................................................................. 6 3.2 程序流程图设计 ................................................................................... 7 3.3 按键控制 ............................................................................................ 9 3.4 字符动态显示 ................................................................................... 10 第4章 系统实现 ........................................................................................... 10 第5章 结论 .................................................................................................... 11 5.1 设计总结 .............................................................................................. 11 5.2 收获与体会 ......................................................................................... 11 5.3 缺点与不足 ......................................................................................... 11
. 专业 专注 .
. . .. . .
. 专业 专注 .
. . .. . .
第1章 实验简介
1.1课题背景
在日常的生活和工作中,住宅与部门的安全防范、单位的文件档案、财务报表以及一些个人资料的保存多以锁的办法来解决。这种办法不仅给不法分子带来了可乘之机,而且传统的机械式开锁也给人们的出行带来了不便,最重要的是一旦钥匙丢失后安全性也大打折扣。随着科学技术的不断发展,人们对日常生活中的安全保险器件的要求越来越高。为满足人们对锁的使用需要,增加其安全性,用电子密码锁代替钥匙锁应运而生。密码锁具有安全性高、成本低、功耗低、易操作等优点。 1.2 研究意义
在安全技术防范领域,具有防盗换码功能的电子密码锁逐渐代替传统的机械式密码锁,克服了机械式密码锁密码量少、安全性能差等缺点,使密码锁无论在技术上还是在性能上都大大提高一步。随着人们对安全的重视和科技的发展,许多电子智能锁。但是这些产品的特点是针对特定的指纹和有效磁卡的,只能适用于保密要求的箱、柜、门等。而且指纹识别器若在公共场所使用存在容易机械损坏,IC卡还存在容易丢失、损坏等特点。加上其成本较高,一定程度上了这类产品的普及和推广,鉴于目前的技术水平与市场的接收程度,电子密码锁是这类电子防盗产品的主流。此外,可以通过编写汇编语言程序以及硬件电路仿真设计来提高我们分析问题、解决问题的能力。 1.3 本文主要内容
. 专业 专注 .
. . .. . .
本文介绍电子密码锁的软硬件设计,下面简单介绍成品的功能与操作。
实现的功能:
电子密码锁主要由一片8086CPU,一片74LS138译码器,三片74LS373,一片74LS245缓冲器,一片8255A及数码管构成,通过软件编程以及硬件链接可以实现四位密码的设定、更改以及显示,通过判断密码的正确与否来控制锁的开关。
具体操作:
输入密码:
(1)、开始执行时数码管每一位都显示“米”,点输入密码数码管只有第一位显示“米”,点击数字键进行数字选择;
(2)、按下“确认”键后跳到第二个数字,操作同第一步;
(3)、当四个密码选中完毕,按下“确认输入”键,显示输入的密码; (4)、按下“开锁”键,若密码正确,同时显示*YES,密码锁打开; (5)、按下“开锁”键,若密码错误,则显示ERRO,密码锁不能打开,按下“输入密码”键,即可重新输入密码。 更改密码:
(1)、在显示*YES时,按下“更改密码”键后,输入新的四位密码; (2)、按下“确认输入”键,显示新密码,按下“确认”键,即可设定新密码。
错误警报:
若输入错误密码超过5次,警报会自动响起,只有再次输入正确密码后方可解除警报。
. 专业 专注 .
. . .. . .
第2章 硬件电路设计
2.1相关芯片简介
1. 8255 第一片8255
定义A.B.C口都为输出状态,A.B口控制数码管的输入口,对应相应的段码表,来显示。C口的PC0,PC1经过2-4译码器,来激活数码管1,2,3,4通道,并采用00,01,10,11,循环输出的方式,使数码管通道循环激活,实现动态显示。
第二片8255
. 专业 专注 .
. . .. . .
定义A,B,C口都为输入状态,对应输入相应的按钮状态,对应相应的程序,实现相应功能。 2. 8253
使用0通道,方式3,对输入的始终信号分频,当输入密码次数大于5次时,初始化8253,并发出警报提示声。
. 专业 专注 .
. . .. . .
当输入密码正确后,激活1通道,警报提示声接触。 3. 2-4译码器
由于8086运行速度过快,数码管动态显示出现显示不全的现象,因此PC0,PC1输出经过2-4译码器之后,再激活数码管,起到缓冲作用。 4. 16位数码管
16位数码管的数码管,由16个引脚控制,低电平有效,其中A-H控制外圈0,
K-M控制内部*
S1-s4是通道控制,高电平有效。
. 专业 专注 .
. . .. . .
2.2 仿真电路总体设计 8086 CPU 可编程并行接口总线连接 8255A 输出 数码管 控制连接 警报器 . 专业 专注 .
. . .. . .
控制按钮 本实验设计中,硬件部分涉及到了8086CPU、可编程并行接口8255A,并配合74LS373锁存器、74LS245缓冲器、74LS138译码器等基本元器件,实现了设想的电子密码锁。
8255A:如图2-6,8255A的D0~D7端口与CPU数据线ADO~AD7相接,CPU通过控制线的片选、读、写信号接口对8255A进行读、写与片选操作。外设接口端的A0-A7八个开关连接245的A0-A7端口,将外设信息传送到245中,键入密码输入、密码确定、修改密码等多种功能。
. 专业 专注 .
. . .. . .
图2-6 开关功能
如图2-7,A口的PA0-PA7端口通过锁存器与数码管相连用于外圈显示,B口的PB0-PB7端口通过74LS373锁存器与数码管进行连接用于内部“米”字格的显示。
第3章 软件编程设计
3.1系统概述
密码锁是一种通过密码输入来控制电路或芯片工作,从而控制机械的开关
. 专业 专注 .
. . .. . .
和闭合,完成开锁闭锁任务的电子产品。它的种类很多,有简易的电路产品,也有基于芯片的性价比较高的产品。现在运用较广的电子密码锁是以芯片为核心,通过编程来实现的,其性能和安全性已大大超过机械锁。其特点是保密性好,随机开锁成功率几乎为零。密码可变,用户可随时更改密码,防止密码被盗,同时也可以避免因人员的更替而使锁的密级下降。无活动零件,不会磨损,寿命长。使用灵活性好,不像机械锁必须佩带钥匙才能开锁。
3.2 程序流程图设计
密码的输入与判定
初始化 更改密码 按数字按钮 确定 . 专业 专注 .
. . .. . .
换位
位数+1
位数=4 重新输入
N
. Y 显示 判定 N E R R O
Y
* Y E S 开锁 专业 专注 .
. . .. . .
图3-1 密码的输入与判定
密码的更改
更改密码 按数字按钮 确定
换位 位数+1
位数=4 重新输入
N
. 专业 专注 .
. . .. . .
Y
显示 N 判定
E R R O
Y
图3-2 密码的更改
* Y E S 开锁
. 专业 专注 .
. . .. . .
3.3 按键控制
(1)、控制字
给8255A输入端口控制字: void fun82531() { __asm {
mov dx, 0x8006 mov al, 0x37 out dx, al }
outp(GATE0,0x02); outp(GATE0,0x00); }
void fun82532() { __asm {
. 专业 专注 .
. . .. . .
mov dx, 0x8006 mov al, 0x77 out dx, al }
outp(GATE0,0x99); outp(GATE0,0x99); }
(2)、密码键入控制
整个过程中主要是对是否有按键信息输入进行扫描判断,并将所得信息与灯管编号进行比对,确定所选择要键入数字的灯管。当目前的灯管数字被选出后,自动跳到下一个灯管,直到四位数字全部选择完毕。
3.4 字符动态显示
四位密码选出后,显示四位选定数字,然后检测密码正确性,8255A通过端口A、B、C读取指令,根据检测结果,密码正确则输出代码显示*YES,错误则显示ERRO。
见附录:检测密码正确性
更改密码,键入“更改密码”控制字后,与输入密码的流程相同,先选择灯管,待选定数字后跳至下一个,直到四位数字全部选定,然后键入“确认更改”指令,则密码更改成功。
见附录:密码更改
. 专业 专注 .
. . .. . .
第4章 系统实现
4.1 proteus仿真实验
图4-1 Proteus仿真图
如图4-1,为本实验的Proteus仿真模拟图,整个实验共用到8086CPU一个、74LS245一个、可编程并行接口8255A一个,74LS273锁存器三个、74LS138译码器一个、数码管一个、与非门两个、开关八个、电阻八个。
第6章 结论
6.1 设计总结
. 专业 专注 .
. . .. . .
通过对电子密码锁的设计,从设计硬件电路到编写代码,再到对程序的调试,在整个的设计过程中学到了很多。例如,我们用到了8255A的并行接口,将二进制的控制信息传入8086CPU中处理,选择对密码是否正确进行调整。与此同时,我们又通过这次产品的设计加深了对硬件知识的理解以及常用芯片功能的掌握。在使用8255A和8253的时候,要对其进行初始化,这初始化程序的编写,有助于对这些接口芯片的工作原理的理解。总之,在实验中自己动手,把理论知识用于实践,从中能够学到很多。
6.2 收获与体会
通过这一个多月以来对电子密码锁的硬件电路的设计,以及对软件程序的编写,我们又对计算机硬件技术基础这门课程有了更深一层的理解。与此同时,我们还有如下收获:
首先,我们能熟练掌握计算机硬件技术知识,其中包括硬件电路设计和软件编程设计等内容。计算机硬件技术基础是比较难学的科目,尤其是对那些没有过编程基础的学员来说,刚开始接触时感觉力不从心。但是,通过设计这个电子密码锁,我组成员都能对硬件设计以及软件编程熟练掌握,并且能实现原计划的功能,效果比较显著。
其次,增强了我们组员之间的团结协作的能力。通过实验,我们明白了团队力量的强大,只有一个团队能够齐心协力、合理分工,工作才能有条不紊的高效开展。
6.3 缺点与不足
虽然在这次电子密码锁的制作中我们收获了很多,但是也不乏问题存在。 首先,刚开始的时候分工不明确,导致制作进程比较缓慢。由于刚接触一
. 专业 专注 .
. . .. . .
门全新的课程,再加上对程序的编写不是很熟悉,所以大家都不知道从何入手,没有明确的分工。随着教员对硬件知识的讲解,再结合平时的小组讨论与自我学习,大家对C语言基本理解。于是开始分配任务,有主攻硬件设计的,有软件编程的,也有PPT制作和论文编写的,以此提高了我们的效率。
其次,由于我们知识积累不足,导致大家在制作中遇到很多困难,期出现厌烦心理,抱怨声音较多,甚至出现了分歧与争吵。当然,对于一个团队来说,出现矛盾是在所难免的,这时候作为组长更应该起到稳定军心的作用。大家在一起,从头来过,寻找解决问题的办法,一起攻克难关。
. 专业 专注 .
. . .. . .
程序:
#define GATE0 0x8000 #define GATE1 0x8002 #define GATE2 0x8004 #define GATECOM 0x8006 #define IOA1 0xc000 #define IOB1 0xc002 #define IOC1 0xc004 #define IOCC1 0xc006 #define IOA2 0xD000 #define IOB2 0xD002 #define IOC2 0xD004 #define IOCC2 0xD006
char err1[]={0CH, 38H,38H,00H}; char err2[]={77H, 67H,67H,0FFH};
. 专业 专注 .
. . .. . .
char cs[]={0b00000000,0b00000001,0b00000010,0b00000011}; char num1[]={00H,0f3h,88h,0c0h,73h,44H,04H,0F0H,00H,40H}; char num2[]={0ffh,0ffh,77h,77h,77h,77h,77h,0ffh,77h,77h}; char yes1[]={0FFH,0FFH,0CH,44h,}; char yes2[]={00H, 0DAH,77H,77h};
void outp(unsigned int addr, char data) // Output byte to port { __asm
{ mov dx, addr mov al, data out dx, al } }
char inp(unsigned int addr) // Input byte from port { char result; __asm
{ mov dx, addr in al, dx
. 专业 专注 .
. . .. . .
mov result, al }
return result; }
/////////////////////////
void fun82531() { __asm {
mov dx, 0x8006 mov al, 0x37 out dx, al }
outp(GATE0,0x02); outp(GATE0,0x00); }
void fun82532()
. 专业 专注 .
. . .. . .
{ __asm {
mov dx, 0x8006 mov al, 0x77 out dx, al }
outp(GATE0,0x99); outp(GATE0,0x99); }
void delay(int s) {
unsigned int i,j; for(i=0;ifor(j=0;j<1000;j++); // 大约s=20 延时1s }
//******************************************************** void yes() {
. 专业 专注 .
. . .. . .
char tmp; int i;
char yes1[]={0FFH,0FFH,0CH,44h,}; char yes2[]={00H, 0DAH,77H,77h};
char cs[]={0b00000000,0b00000001,0b00000010,0b00000011};
tmp=inp(IOA2);
while(tmp==0xffed) { tmp=inp(IOA2); for(i=0;i<4;i++) {
outp(IOC1,cs[i]); outp(IOA1,yes1[i]); outp(IOB1,yes2[i]); delay(1); }
} }
//*************************************************************
. 专业 专注 .
. . .. . .
void fun82551() { __asm {
mov dx, 0xc006 mov al, 0x80 out dx, al } }
void fun82552() { __asm {
mov dx, 0xD006 mov al, 0x9b out dx, al } }
. 专业 专注 .
. . .. . .
//************************************************************** void err() // 密码错误 {
char tmp; int i;
char err1[]={0CH, 38H,38H,00H}; char err2[]={77H, 67H,67H,0FFH}; char
cs[]={0b00000000,0b00000001,0b00000010,0b00000011};
tmp=inp(IOA2);
while(tmp==0xffed) {
tmp=inp(IOA2); for(i=0;i<4;i++) {
outp(IOC1,cs[i]); outp(IOA1,err1[i]); outp(IOB1,err2[i]); delay(1);
. 专业 专注 .
. . .. . .
} } }
//***********************************************************************
void chushihua(int r) // 复位 { int i; if(r==1) {
for(i=0;i<4;i++) {
outp(IOC1,cs[i]); outp(IOA1,num1[0]); outp(IOB1,num2[0]); delay(1);
. 专业 专注 .
. . .. . .
}
} }
char xianshi() {
char tmp; char result; tmp=inp(IOB2); if(tmp==0xfffe)//0 {
outp(IOA1,num1[0]); outp(IOB1,num2[0]); result=0; }
if(tmp==0xfffd)//1 {
outp(IOA1,num1[1]); outp(IOB1,num2[1]); result=1;
. 专业 专注 .
. . .. . .
}
if(tmp==0xfffb) {
outp(IOA1,num1[2]); outp(IOB1,num2[2]); result=2; }
if(tmp==0xfff7) {
outp(IOA1,num1[3]); outp(IOB1,num2[3]); result=3; }
if(tmp==0xffef) {
outp(IOA1,num1[4]); outp(IOB1,num2[4]); result=4; }
if(tmp==0xffdf) {
outp(IOA1,num1[5]);
. 专业 专注 .
. . .. . .
outp(IOB1,num2[5]); result=5; }
if(tmp==0xffbf) {
outp(IOA1,num1[6]); outp(IOB1,num2[6]); result=6; }
if(tmp==0xff7f) {
outp(IOA1,num1[7]); outp(IOB1,num2[7]); result=7; }
tmp=inp(IOC2);
if(tmp==0xfffe) {
outp(IOA1,num1[8]); outp(IOB1,num2[8]); result=8; }
. 专业 专注 .
. . .. . .
if(tmp==0xfffd) {
outp(IOA1,num1[9]); outp(IOB1,num2[9]); result=9; }
return result; }
//*************************************************************** char change(int c) // 单纯的更改密码的函数 {
char result;
char tmp;
outp(IOC1,cs[c]); outp(IOA1,yes1[0]); outp(IOB1,yes2[0]);
tmp=inp(IOA2);
. 专业 专注 .
. . .. . .
while(tmp!=0xfff5) {
tmp=inp(IOA2); result= xianshi();
}
return result;
//直接传出去改过之后的哪位数字,不管是更改密码还是输入密码,只管输出
}
//*****************************************************************
char genggaimima() //更改密码 {
int c=0; char i1;
i1= change(c);
return i1; // 要求更改密码,直接更改第一位,并输出更改之后的第一位密码是多少 i=1,可以更改密码
}
. 专业 专注 .
. . .. . .
//********************************************************************* char huanwei(char c) //换位 { c++; delay(50);
return c; //传出去换位之后的位 }
//***********************************************
//********************************************** char shurumima() //第一位输入密码 输入密码 {
int c=0;
char s1;//输入的第一位密码 s1= change(c); return s1;
//传出去第一位输入的密码 }
. 专业 专注 .
. . .. . .
//////////////////////////////////////////////////////////////////////
void querengg(char shuru[]) /// 显示输入之后的密码 ffdf {
int i,j,m;
for(j=0;j<7;j++) {
for(i=0;i<4;i++) {
m=shuru[i]; outp(IOC1,cs[i]); outp(IOA1,num1[m]); outp(IOB1,num2[m]); delay(1); }
} }
int panduan1(char shuru[],char mima[])//判断 以更改密码 I为0不允许更改密码
. 专业 专注 .
开锁 I为1,可 . . .. . .
{ int i;
if(shuru[0]==mima[0]&&shuru[1]==mima[1]&&shuru[2]==mima[2]&&shuru[3]==mima[3]) //判断输入的密码和更改的密码是否一样
{
yes(); i=1; }
else {
err();
i=0; }
return i; }
int panduan2(char shuru[],char mima[],int t)//判断 错误超过6次,警报 t为 错误密码次数
{
if(shuru[0]==mima[0]&&shuru[1]==mima[1]&&shuru[2]==mima[2]&&shuru[3]==mima[3]) //判断输入的密码和更改的密码是否一样
. 专业 专注 .
. . .. . .
{ yes();
t=0;
} else {
err();
t++; } return t; }
//////////////////////////////
void main(void) {
int i1=0,i2=1,i3=2,i4=3; int s1=0,s2=1,s3=2,s4=3;
. 专业 专注 .
. . .. . .
int r=1; //变量R非常重要,只有当R=1时,才可以修改密码,初始化密码,在判断密码中,会返回一个R,得知R=1or0. !!亮点
int t=0;
char mima[100]={0,0,0,0}; //这两个数组是亮点 char shuru[100]={0,0,0,0}; char tmp;
int c1=0; //更改密码的led位置 !!亮点 int c2=0; //输入密码的led位置
fun82551(); fun82552();
while(1) {
tmp=inp(IOA2);
if(tmp==0xfffC&&r==1) . 专业 专注 .
// 显示
. . .. . .
0000
{
chushihua(r); mima[0]=0; mima[1]=0; mima[2]=0; mima[3]=0; }
if(tmp==0xffbd&&r==1) 始改密码 r=1时才能更改密码
{
mima[i1]=genggaimima(); c1=huanwei(c1); mima[i2]=change(c1); c1=huanwei(c1); mima[i3]=change(c1); c1=huanwei(c1); mima[i4]=change(c1); c1=0;
. 专业 专注 .
// 按更改密码 开
. . .. . .
int i,j,m;
for(j=0;j<25;j++) {
for(i=0;i<4;i++) {
m=mima[i]; outp(IOC1,cs[i]); outp(IOA1,num1[m]); outp(IOB1,num2[m]); delay(1); }
} }
if(tmp==0xffdd) // {
. 专业 专注 .
确认输入 . . .. . .
querengg(shuru); }
if(tmp==0x7d) // 重新输入 输入密码 {
shuru[s1]=shurumima(); c2=huanwei(c2); shuru[s2]=change(c2); c2=huanwei(c2); shuru[s3]=change(c2); c2=huanwei(c2); shuru[s4]=change(c2); c2=0; }
if(tmp==0xfffd)//显示**** { int i;
for(i=0;i<4;i++) {
. 专业 专注 .
. . .. . .
outp(IOC1,cs[i]); outp(IOA1,yes1[0]); outp(IOB1,yes2[0]); delay(1); }
}
if(tmp==0xffed) // 开锁 {
r=panduan1(shuru,mima); //返回一个R,R=1可以修改密码
和初始化,R!=1,不能
t=panduan2(shuru,mima,t); //用来知道连续错误了几次 if(t>5) {
fun82531(); //激活通道0 这样就会报警 }
if(t==0)
. 专业 专注 .
. . .. . .
{
fun82532(); //让8253激活通道1.这样就不响了 } } }
} . 专业 专注 .
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- fenyunshixun.cn 版权所有 湘ICP备2023022495号-9
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务