单片机电子密码锁课程设计Word文档格式.docx
- 文档编号:20807682
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:18
- 大小:40.75KB
单片机电子密码锁课程设计Word文档格式.docx
《单片机电子密码锁课程设计Word文档格式.docx》由会员分享,可在线阅读,更多相关《单片机电子密码锁课程设计Word文档格式.docx(18页珍藏版)》请在冰豆网上搜索。
2)密码可变,用户可以随时更改密码,防止密码被盗,同时也可以避免因人员的更替而使锁的密级下降。
3)误码输入保护,当输入密码多次错误时,报警系统自动启动。
4)无活动零件,不会磨损,寿命长。
5)使用灵活性好,不像机械锁必须佩带钥匙才能开锁。
6)电子密码锁操作简单易行,一学即会。
2、硬件电路设计
下面是整个设计的流程图:
51单片机
这次课程设计采用的是5系列单片机AT89C52。
其外部封装如下图所示:
AT89C52单片机有4组8位的可编程I/O口,分别位P0、P1、P2、P3口,每个口有8位(8根引脚),共32根[8]。
P0口(Pin39~Pin32):
8位双向I/O口线,名称为~
P1口(Pin1~Pin8):
8位准双向I/O口线,名称为~
P2口(Pin21~Pin28):
P3口(Pin10~Pin17):
8位准双向I/O口线,名称为~
键盘电路
本次试验采用的是行列键盘,C语言程序中有相应的驱动程序,其硬件电路如下所示,下右对应的为各个按键所对应的数字及功能。
5
6
7
8
确认
重输
改密
液晶显示电路
实验中采用的是LM016L液晶显示,其数据端口采集数据通过单片机的P0口,接法如下图所示。
不同情况下会有不同的显示,显示内容包括:
Welcome、HelloBoss、Wrong、OK等内容。
警报电路
下图是警报电路连接图,警报触发为:
连续三次输错密码,警报触发后会有一个时间延迟,延迟时间内任何操作都是无效的,过后通过关锁按钮可解除。
密码储存电路
实验中考虑到实用性方面时,就想到了密码储存及修改的问题,于是采用了FM24C02F作为面膜储存模块,电路连接如下所示:
晶振、复位及关锁
晶振、复位及关锁电路如下所示(作图所示按钮为复位按钮):
三、软件设计
C语言源程序:
#include<
>
#defineCHECK_BUSY
#defineDataPortP0
#defineKeyPortP1
sbitRS=P2^4;
//液晶显示的定义端口
sbitRW=P2^5;
sbitEN=P2^6;
sbitscl=P3^0;
//24c02端口定义
sbitsda=P3^1;
sbitbaojing=P2^1;
//报警器
sbitjdq=P2^0;
//继电器
sbitjb=P2^3;
//警报灯
sbitclose=P2^2;
unsignedcharold1,old2,old3,old4,old5,old6;
//原始密码000000
unsignedcharnew1,new2,new3,new4,new5,new6;
//代表新密码
voiddelay1(unsignedintm)
{
unsignedintn;
for(n=0;
n<
m;
n++);
}
voiddelay(unsignedintm)
unsignedinta;
unsignedcharb;
for(a=0;
a<
a++)
{for(b=0;
b<
125;
b++);
voidDelayUs2x(unsignedchart)
{
while(--t);
voidDelayMs(unsignedchart)
while(t--)
{
DelayUs2x(256);
}
voidbaojingqi()
baojing=0;
if(baojing==0)
{
bitLCD_Check_Busy(void)//判忙函数
#ifdefCHECK_BUSY
DataPort=0xFF;
RS=0;
RW=1;
EN=0;
_nop_();
EN=1;
return(bit)(DataPort&
0x80);
#else
return0;
#endif
voidLCD_Write_Com(unsignedcharcom)//写入命令函数
//while(LCD_Check_Busy());
//忙则等待
DelayMs(5);
RS=0;
RW=0;
EN=1;
DataPort=com;
_nop_();
EN=0;
voidLCD_Write_Data(unsignedcharData)//写入数据函数
//while(LCD_Check_Busy());
RS=1;
DataPort=Data;
voidLCD_Clear(void)//清屏函数
LCD_Write_Com(0x01);
voidLCD_Write_Char(unsignedcharx,unsignedchary,unsignedcharData)//写入字符函数
if(y==0)
{LCD_Write_Com(0x80+x);
}
else
{LCD_Write_Com(0xC0+x);
LCD_Write_Data(Data);
voidLCD_Write_String(unsignedcharx,unsignedchary,unsignedchar*s)//写入字符串函数
while(*s)
LCD_Write_Char(x,y,*s);
s++;
x++;
voidLCD_Init(void)//液晶显示的初始化函数
LCD_Write_Com(0x38);
//显示模式设置
LCD_Write_Com(0x08);
//显示关闭
//显示清屏
LCD_Write_Com(0x06);
//显示光标移动设置
LCD_Write_Com(0x0C);
//显示开及光标设置
unsignedcharKeyScan(void)//键盘扫描函数,使用行列反转扫描法
unsignedcharcord_h,cord_l;
//行列值中间变量
KeyPort=0x0f;
//行线输出全为0
cord_h=KeyPort&
0x0f;
//读入列线值
if(cord_h!
=0x0f)//先检测有无按键按下
DelayMs(10);
//去抖
if((KeyPort&
0x0f)!
=0x0f)
KeyPort=cord_h|0xf0;
//输出当前列线值
cord_l=KeyPort&
0xf0;
//读入行线值
while((KeyPort&
0xf0)!
=0xf0);
//等待松开并输出
return(cord_h+cord_l);
//键盘最后组合码值
}}return(0xff);
//返回该值
unsignedcharKeyPro(void)
switch(KeyScan())
case0x7e:
break;
//0按下相应的键显示相对应的码值
case0x7d:
return1;
//1
case0x7b:
return2;
//2
case0x77:
return3;
//3
case0xbe:
return4;
//4
case0xbd:
return5;
//5
case0xbb:
return6;
//6
case0xb7:
return7;
//7
case0xde:
return8;
//8
case0xdd:
return9;
//9
case0xdb:
return10;
//10
case0xd7:
return11;
//11
case0xee:
return12;
//12
case0xed:
return13;
//13
case0xeb:
return14;
//14
case0xe7:
return15;
//15
default:
return0xff;
voidinit()//24c02初始化子程序
scl=1;
sda=1;
voidrespons()//应答
unsignedchari;
while((sda==1)&
&
(i<
250))
i++;
scl=0;
voidclock()//I2C总线时钟
unsignedchari=0;
255))
voidstart()//启动I2C总线
sda=0;
voidstop()//停止I2C总线
voidwritebyte(unsignedchara)//写一个字节
unsignedcharb,tem;
tem=a;
for(b=0;
8;
b++)
tem=tem<
<
1;
sda=CY;
//temp左移时,移出的值放入了CY中
//待sda线上的数据稳定后,将scl拉高
nop_();
unsignedcharreadbyte()//读一个字节
unsignedchari,j,k=0;
for(i=0;
i<
i++)
if(sda==1)j=1;
elsej=0;
k=(k<
1)|j;
_nop_();
return(k);
unsignedcharread24c02(unsignedcharaddress)//从24c02的地址address中读取一个字节数据
unsignedchardate;
start();
writebyte(0xa0);
clock();
writebyte(address);
writebyte(0xa1);
date=readbyte();
stop();
delay1(100);
return(date);
voidwrite24c02(unsignedcharaddress,unsignedcharinfo)//向24c02的address地址中写入一字节数据info
writebyte(info);
delay1(5000);
//这个延时一定要足够长,否则会出错。
因为24c02在从sda上取得数据后,还需要一定时间的烧录过程。
main()
unsignedcharnum,i,bj,c=0;
unsignedchartemp[6];
bitFlag;
init();
//初始化24C02
LCD_Init();
//初始化液晶屏
//延时用于稳定,可以去掉
LCD_Clear();
//清屏
LCD_Write_String(0,0,"
welcome"
);
//写入第一行信息
old1=read24c02(110);
old2=read24c02(111);
old3=read24c02(112);
old4=read24c02(113);
old5=read24c02(114);
old6=read24c02(115);
while
(1)//主循环
num=KeyPro();
//扫描键盘
if(num!
=0xff)//如果扫描是按键有效值则进行处理
if(i==0)//输入是第一个字符的时候需要把改行清空,方便观看密码
LCD_Write_String(0,1,"
"
//清除该行
if(i<
6)//密码是6位,大于6位时不再输入按键值
temp[i]=num;
LCD_Write_Char(i,1,'
*'
}
i++;
//输入数值累加
if(num==11)//重试键
{i=0;
if(num==12)
if(bj==0)
while(i<
=6)
//输入数值累加
if(num==10)
num=0;
new1=temp[0];
new2=temp[1];
new3=temp[2];
new4=temp[3];
new5=temp[4];
new6=temp[5];
old1=new1;
old2=new2;
old3=new3;
old4=new4;
old5=new5;
old6=new6;
//新密码代替旧密码
write24c02(110,old1);
write24c02(111,old2);
write24c02(112,old3);
write24c02(113,old4);
write24c02(114,old5);
write24c02(115,old6);
ok"
bj=1;
DelayMs(220);
DelayMs(220);
if(close==0)
i=0;
if(num==10)//数字10为确认键
if(i==7)//6位后的按键输入数值,相当于确认按键(任意按键即可)
//计数器复位
Flag=1;
//先把比较位置1
old1=read24c02(110);
old2=read24c02(111);
old3=read24c02(112);
old4=read24c02(113);
old5=read24c02(114);
old6=read24c02(115);
Flag=Flag&
(new1==old1)&
(new2==old2)&
(new3==old3)&
(new4==old4)&
(new5==old5)&
(new6==old6);
//比较输入值和已有密码
if(Flag)//如果比较全部相同,标志位置1
HelloBoss!
//密码正确显示的信息
jdq=0;
bj=0;
delay(3000);
jdq=1;
else
c++;
error!
"
//密码错误,提示重新输入
while(c==3)
baojingqi();
jb=0;
DelayMs(255);
baojing=1;
jb=1;
c=0;
else//当密码不是6位数字时按下确认键也算输错密码一次
}}}}
}
四、软硬件调试结果
电路总原理图
电路总原理图如下所示:
调试结果
各种情况下的的调试结果如下个图所示:
依次为开机、开锁、成功修改密码、密码错误。
5、总结
在这次实验中,用到了单片机和C语言的知识,这两门知识都是非常具有实用性的。
在这次实验中再次加深了对此的认识。
首先,在一开始输程序的时候,在程序仿真过程中出现了不能打开头文件的现象,后来经老师知道后知道了头文件的具体作用和使用方式。
这些都是以前所没能
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 电子 密码锁 课程设计