基于单片机的电子密码锁的设计Word下载.docx
- 文档编号:5748861
- 上传时间:2023-05-05
- 格式:DOCX
- 页数:29
- 大小:1.08MB
基于单片机的电子密码锁的设计Word下载.docx
《基于单片机的电子密码锁的设计Word下载.docx》由会员分享,可在线阅读,更多相关《基于单片机的电子密码锁的设计Word下载.docx(29页珍藏版)》请在冰点文库上搜索。
单片微机(Single-ChipMicrocomputer)简称为单片机。
他在一块芯片上集中了中央处理单元CPU、随机存储器RAM、只读存储器ROM、定时/计数和多功能输入/输出I/O口,如并行I/O、串行口I/O和转换A/D等。
就其组成而言,一块单片机就是一台计算机,由于它具有体积小、功能强和价格便宜等优点,因而被广泛地应用于产品智能化和工业控制自动化上。
2.3.2主要元器件选择
如图2.3.2-1
图2.3.2-1主要元器件选择
第三章控制系统的软件设计
3.1软件设计
3.1.1单片机中中断系统基本结构
中断是一项重要的计算机技术,是处理正常工作与紧急状态的好办法,是实现人机实时交互的重要途径,在单片机应用系统中,终端技术得到了广泛应用。
下面详细介绍单片机中断系统基本结构、与中断相关的特殊寄存器的设置及中断应用系统编程方法。
当CPU查询到系统有中断请求时,如果系统处于中断允许状态,CPU将停止当前的工作,相应中断请求,转向中断服务,中断服务完成后,返回源程序继续执行当前任务,这叫单片机中断。
能让CPU产生中断的信号源叫中断源。
8051单片机有INT0、INT1、T0、T1、TI、RI六个中断源,但是只有EX0、ET0、EX1、ET1、ES五个向量,下面简要介绍六个中断源。
INT0、INT1:
外部中断源,右P3.2和P3.3引脚输入。
具有低电平和脉冲两种出发方式,
在每个机器周期的S5P2采样引脚信号,如有效则由硬件将它的中断请教标志IE置1,请求中断.当CPU响应中断时,由硬件复位。
T0、T1:
定时/计数器中断,当定时/计数器产生溢出时,置位中断请求标志TF请求中断处理。
RI、TI:
串行中断,RI是接受,TI为发送。
单片机串行口接受到一个字符后RI置1,发送完一个字符TI置1。
值得注意的是,RI、TI在响应中断后,必须由用指令将其复位。
3.1.2中断响应
CPU在执行程序的过程中,在每个机器周期的S5P2对中断位置位按中断优先级进行查询,一旦查询到有中断请求,CPU只要不在执行同级或高级的中断服务程序和当前指令(RETI指令或访问IE、IP的指令除外)执行完毕两种情况,则响应中断。
如果当前正在执行的指令是RETI或访问IE、IP的指令,则当前指令执行完毕后,CPU才可响应中断。
中断响应时间可以从中断信号被查询开始算起,中断响应时间在以下三种情况,响应还会更长:
①CPU正在执行一个比响应的中断源优先级相当或更高的中断源的中断服务程序,此时必须等到中断服务程序执行完毕才可中断响应。
②正在执行的当前指令不是在最后一个机器周期,只有指令执行完后才响应中断。
③如果当前执行的是RETI或访问IE、IP的指令,则当前指令执行完毕后,CPU需再执行一条指令才可以中断响应,因此附加等待响应时间不会超过5个机器周期。
3.1.3中断入口:
单片机响应中断后,将转向特定的入口进行中断服务,单片机的中断入口地址如下表3.1.3-1
中断源
入口地址
IE0(外部中断0)
0003H
TF0(定时器0溢出中断)
000BH
IE1(外部中断1)
0013H
TF1(定时器1溢出中断)
001BH
RI+TI(串行口中断)
0023H
表3.1.3-1单片机中断入口地址表
从表中可以看出,两相邻中断源的入口地址间隔为8个单元。
这意味着如果要把中断源对应的中断服务程序从入口地址开始存放,则程序的长度不能超过8个字节,否则会影响到下一个中断源的入口地址的使用。
而通常情况下,中断服务程序的长度不止8个字节,因此,常见的处理方法是:
在入口地址处存放一条无条件转移指令,通过这条转移指令转向对应的中断服务程序入口,中断服务程序以RETI为结束。
3.1.4中断请求的撤销
CPU响应中断请求,在中断返回(RETI)之前,该中断请求应被撤除,否则会引发另一次中断。
定时/计数器中断请求撤销:
CPU在响应中断之后,由硬件自动清除中断请求标志TF。
外部中断请求撤销:
如果采用脉冲触发方式,CPU在响应中断后,由硬件自动清除中断请求标志IE;
对于电平触发方式的外部中断请求,中断标志的撤销是自动的,由于造成中断请求的低电平继续存在,所以在响应中断后再次会产生中断请求,为此响应中断后要撤销外部信号。
3.1.5每秒钟的设定
延时方法可以右两种,一种是利用MCS-51内部定时器溢出中断来确定1秒的时间,另一种是采用软延时的方法。
3.1.6计数器初值计算
定时器工作时必须给计数器送计数器初值,这个值是送到TH和TL中的。
我们可以把计数器记满为零所需的计数值设定为C和计数初值设定为TC可得到如下计算公式:
TC=M-C。
3.2实验程序
#include<
reg51.h>
intrins.h>
#defineINT8Uunsignedchar
#defineINT16Uunsignedint
sbitred=P3^6;
//定义红灯,即锁定状态
sbitgreen=P3^7;
//定义绿灯,即解锁状态
sbitk1=P1^0;
//定义数字键“1”
sbitk2=P1^1;
//定义数字键“2”
sbitk3=P1^2;
//定义数字键“3”
sbitk4=P1^3;
//定义数字键“4”
sbitk5=P1^4;
//定义数字键“5”
sbitk6=P1^5;
//定义数字键“6”
sbitk7=P1^6;
//定义数字键“7”
sbitk8=P1^7;
//定义数字键“8”
sbitk9=P3^0;
//定义数字键“9”
sbitk0=P3^1;
//定义数字键“0”
sbitka=P3^2;
//定义“返回”键
sbitkb=P3^3;
//定义“确定”键
sbitkc=P3^4;
//定义“更改密码”键
sbitkd=P3^5;
//定义“锁定”键
INT8Umod=1,i,error,j,change,state,right;
//定义初始模式、位码、错误次数、取反次数、更改密码模式、按键状态、密码是否相等
INT16Ut=0,poi=1800,tt=0;
//定义定时、倒计时数、时间累计
INT8UcodeDSY_CODE[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF};
//定义段码
INT8Uarray[]={0,0,0,0};
//保存数位分解结果的数组
INT8Unico_A[]={0,0,0,0};
//密码A数组
INT8Unico_B[]={0,0,0,0};
//密码B数组
voidINT_TO_4Digit(INT16Un)//数位分解函数
{
array[0]=0;
while(n>
=1000){array[0]++;
n-=1000;
}
array[1]=0;
=100){array[1]++;
n-=100;
array[2]=0;
=10){array[2]++;
n-=10;
array[3]=n;
voidDSY_Show()interrupt1//T0中断函数
TH0=-1000/256;
//1ms定时
TL0=-1000%256;
if(k1==0||k2==0||k3==0||k4==0||k5==0||k6==0||k7==0||k8==0||k9==0||k0==0)state=1;
//若任意数字键按下,state=1
if(k1!
=0&
&
k2!
k3!
k4!
k5!
k6!
k7!
k8!
k9!
k0!
state==1)state=2;
//若无数字键按下,且按键状态为1时,按键状态更改为2
if(ka==0&
state==0)state=3;
//若“返回”键按下,且按键状态为0,按键状态更改为3
if(ka!
state==3)state=4;
//若“返回键”没有按下,且按键状态为3,按键状态更改为4
if(nico_A[0]!
=nico_B[0]||nico_A[1]!
=nico_B[1]||nico_A[2]!
=nico_B[2]||nico_A[3]!
=nico_B[3])right=1;
//若密码A数组任一位不等于密码B数组,即密码不相等
if(nico_A[0]==nico_B[0]&
nico_A[1]==nico_B[1]&
nico_A[2]==nico_B[2]&
nico_A[3]==nico_B[3])right=2;
//若密码A数组与密码B数组完全相等,即密码相等
if(ka==0||kb==0||kc==0||kd==0)tt=0;
//如果“返回”、“确定”、“更改密码”、“锁定”任意一键按下,时间累计清零
switch(mod)//选择模式
case1:
if(change==0){red=0;
green=1;
}//若不是在更改密码模式,红灯亮,绿灯灭
if(change==1&
state==4){change=0;
mod=5;
state=0;
}//若在更改密码状态,且按键模式为4时,变为输入密码状态,且模式变为5,按键状态变为1
P0=0xFF;
//关闭段码
if(k1==0)nico_B[0]=1;
//若按下数字键“1”,密码B的第0位为1
if(k2==0)nico_B[0]=2;
if(k3==0)nico_B[0]=3;
if(k4==0)nico_B[0]=4;
if(k5==0)nico_B[0]=5;
if(k6==0)nico_B[0]=6;
if(k7==0)nico_B[0]=7;
if(k8==0)nico_B[0]=8;
if(k9==0)nico_B[0]=9;
if(k0==0)nico_B[0]=0;
if(t++==1000){t=0;
tt++;
}//定时1秒,然后t清零,时间累计+1
if(tt==1800){tt=0;
error=0;
}//半小时内无任何操作,错误次数清零
if(state!
=2)return;
//如果按键状态不为2,返回
tt=0;
//时间累计清零
//按键状态变为0
mod=2;
//模式变为2
break;
//退出本次循环
case2:
if(change==1)//若为更改密码状态,会显示数字
P2=(1<
<
0);
//输出位码
P0=DSY_CODE[nico_B[0]];
//输出段码
if(change==0)//若为输入密码状态,会显示一横
P0=DSY_CODE[10];
if(state==4){mod=1;
}//若按键状态为4,模式变为1,且按键状态变为1
if(k1==0)nico_B[1]=1;
if(k2==0)nico_B[1]=2;
if(k3==0)nico_B[1]=3;
if(k4==0)nico_B[1]=4;
if(k5==0)nico_B[1]=5;
if(k6==0)nico_B[1]=6;
if(k7==0)nico_B[1]=7;
if(k8==0)nico_B[1]=8;
if(k9==0)nico_B[1]=9;
if(k0==0)nico_B[1]=0;
mod=3;
case3:
if(change==1)
i);
P0=DSY_CODE[nico_B[i]];
if(change==0)
i=(i+1)%2;
//i的输出结果在0、1之间循环
if(state==4){mod=2;
if(k1==0)nico_B[2]=1;
if(k2==0)nico_B[2]=2;
if(k3==0)nico_B[2]=3;
if(k4==0)nico_B[2]=4;
if(k5==0)nico_B[2]=5;
if(k6==0)nico_B[2]=6;
if(k7==0)nico_B[2]=7;
if(k8==0)nico_B[2]=8;
if(k9==0)nico_B[2]=9;
if(k0==0)nico_B[2]=0;
mod=4;
case4:
i=(i+1)%3;
if(state==4){mod=3;
if(k1==0)nico_B[3]=1;
if(k2==0)nico_B[3]=2;
if(k3==0)nico_B[3]=3;
if(k4==0)nico_B[3]=4;
if(k5==0)nico_B[3]=5;
if(k6==0)nico_B[3]=6;
if(k7==0)nico_B[3]=7;
if(k8==0)nico_B[3]=8;
if(k9==0)nico_B[3]=9;
if(k0==0)nico_B[3]=0;
case5:
i=(i+1)%4;
if(ka==0||kb==0||kc==0||kd==0)t=0;
//如果“返回”、“确定”、“更改密码”、“锁定”任意一键按下,定时清零
kb==0&
green==0){nico_A[0]=nico_B[0];
nico_A[1]=nico_B[1];
nico_A[2]=nico_B[2];
nico_A[3]=nico_B[3];
mod=8;
}//若在更改密码状态且绿灯亮时按下确定,密码B会代入密码A,且模式变为8
if(state==4&
red==0||state==4&
green==0&
change==1){mod=4;
}//若在按键状态为4且红灯亮时或者按键状态为4,绿灯亮且为更改密码状态时,模式变为4,按键状态变为1
if(kb==0&
right==2&
red==0){red=1;
green=0;
}//若在密码相同且红灯时按下“确定”,红灯灭,绿灯亮,错误次数清零
if(kd==0&
change==0)mod=1;
//若在绿灯亮且在输入密码状态时按下“锁定”键,模式变为1
right==1&
red==0)mod=6;
//若在密码不相等且红灯时按下“确定”,模式变为6
if(kc==0&
change==0){mod=1;
change=1;
}//若在绿灯且输入密码状态时按下“更改密码”,模式变为1,且变为更改密码状态
error==2&
mod=7;
}//若在错误次数为2,且密码不相等并且红灯亮时按下确定键,红灯绿灯均熄灭并且模式变为7
case6:
if(t++!
=500)return;
//定时500ms
t=0;
red=~red;
j++;
//t归0,红灯取反,j=j+1
if(j!
=6)return;
//如果没有取反6次,返回
j=0;
error++;
//取反次数归0,累计1次错误次数
mod=1;
case7:
INT_TO_4Digit(poi);
P0=DSY_CODE[array[i]];
=1000)return;
//定时1秒
poi--;
//每过1秒,倒计时数减1
if(poi!
=0)return;
//如果倒计时数不等于0,就返回
poi=1800;
//错误次数清零,模式变为1,倒计时数变为1800
case8:
green=~green;
change=0;
voidmain()
TMOD=0X01;
//T0工作于方式1
IE=0x82;
//使能T0中断
TR0=1;
//启动T0
while
(1);
//主程序无限延时,定时器中断持续触发
第四章控制系统的运行与调试
4.1系统仿真
4.1.1元件位置摆放,如图4.1.1-1
图4.1.1-1元件摆放图
4.1.2各个元件的连线标号,如图4.1.2-1
图4.1.2-1
(1)连线标号图
图4.1.2-1
(2)连线标号图
图4.1.2-1(3)连线标号图
4.2图文说明
★★★初始密码为0000★★★
开始时,红灯亮,绿灯灭,数码管无任何显示,电子锁为锁定状态
当按下任意一个数字键时,数码管会显示一横表示已经输入了一个数字
按下“返回”键时,可以返回上一步
当按下四个数字键时,再按下“确定”,如果输入的密码错误,红灯会闪烁3次,并且累计1次错误次数
然后返回初始状态
如果输入密码错误次数在半小时内达到3次,红灯和绿灯均熄灭,并且数码管显示1800,每过一秒减少1
倒计时结束后,电子锁将返回初始状态,并且将错误次数清零
若输入的密码正确,红灯灭,绿灯亮,错误次数清零,电子锁进入解锁状态
若在电子锁解锁状态时按下“锁定”键,电子锁将重新上锁,进入锁定状态
若在解锁状态按下“更改密码”,电子锁将进入更改密码模式
若在更改密码模式时按下“返回”,电子锁将返回开锁状态
在更改模式输入数字键,数码管会显示数字
输入“返回”,可以返回上一步
在输入四个数字后再按“确定”,绿灯会闪烁3次,表示密码已经更改完成,然后返回开锁状态
总结
在本设计中,本人使用了涉及I/O控制,包括LED、数码管、按键等程序设计,使用了使用外部中断与定时计数器程序设计。
通过对这些案例的学习研究与跟踪调试,并根据要求进行仿真实训设计,可全面掌握8051单片机的C语言基础程序设计技术,熟练使用C语言控制和运用单片机内部资源,为8051单片机扩展资源的应用及系统综合设计打下良好基础。
参考文献
[1]彭伟编著《单片机C语言程序设计实训100例》
[2]王幸之等编著《AT89系列单片机原理与接口技术》[M]2004
[3]戴佳
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 单片机 电子 密码锁 设计