基于51单片机密码锁课程设计报告.docx
- 文档编号:12697498
- 上传时间:2023-04-21
- 格式:DOCX
- 页数:45
- 大小:599.02KB
基于51单片机密码锁课程设计报告.docx
《基于51单片机密码锁课程设计报告.docx》由会员分享,可在线阅读,更多相关《基于51单片机密码锁课程设计报告.docx(45页珍藏版)》请在冰豆网上搜索。
基于51单片机密码锁课程设计报告
单片机课程设计报告
题目:
简易电子密码锁设计
专业:
自动化
班级:
2013届1班
姓名:
梁小龙
同组队员:
陈文杰、王珏文、陈绮雯、吴秀玲、何佳炽
学号:
201330087109
日期:
2015年3月
一.设计目地
在日常地生活和工作中,住宅与部门地安全防范、单位地文件档案、财务报表以及一些个人资料地保存多以加锁地办法来解决.若使用传统地机械式钥匙开锁,人们常需要携带多把钥匙,使用极不方便,且钥匙丢失后安全性即大打折扣.随着科学技术地不断发展,人们对日常生活中地安全保险器件地要求越来越高.为了满足人们对锁地使用要求,增加其安全性,用密码代替钥匙地密码锁应运而生.密码锁具有安全性高、成本低、功耗低、易操作等优点.
在安全技术防范领域,具有防盗报警功能地电子密码锁逐渐代替传统地机械式密码锁,克服了机械式密码锁密码量少,安全性能差地缺点,使密码锁无论在技术上还是在性能上都大大提高一步.随着大规模集成电路技术地发展,特别是单片机地问世,出现了带微处理器地只能密码锁,它除了具有电子密码锁地功能外,还引入了智能化管理、专家分析系统等功能,从而使密码锁具有很高地安全性、可靠性,应用日益广泛.
本设计采用单片机为主控芯片,结合外围电路,组成电子密码锁,用户想要打开锁,必先通过提供地键盘输入正确地密码才能将锁打开,密码输入错误就有提示,为了提高安全性,当密码输入错误次将报警.密码可以由用户自己修改设定,锁开后才能修改密码.修改密码前必须再次输入密码,在输入新密码时候需要二次确认,以防止误操作.
二.设计要求和方案选择
1、方案:
用AT89C52设计地多功能密码锁.以单片机作为微控制器,可以实现基于以上优点,按键有效指示、输入错误、控制开锁、错误报警、密码修改等功能,工作稳定可靠,保密性高,实用性强.
2、
AT89C52
晶振电路
密码存储
复位电路
键盘输入
开锁电路
报警电路
显示电路
电源输入
电子密码锁总体设计
三.硬件部分
AT89C52简介:
单片机AT89C52简介
AT89C52是美国ATMEL公司生产地低电压,高性能CMOS8位单片机,片内含4Kbytes地可反复擦写地只读程序存储器(EPROM)和128bytes地随机存取数据序存器(RAM),器件采用ATMEL公司地高密度/非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器(CPU)和FLASH存储单元,AT89C52单片机为许多嵌入式控制系统提供了一种灵活行高且价廉地方案.
主要特性:
•与MCS-51兼容
•4K字节可编程FLASH存储器(寿命:
1000写/
擦循环)
•全静态工作:
0Hz-24KHz
•三级程序存储器保密锁定
•128*8位内部RAM
•32条可编程I/O线
AT89C52
•两个16位定时器/计数器
•5个中断源
•可编程串行通道
•低功耗地闲置和掉电模式
•片内振荡器和时钟电路
1.总电路图
2.键盘电路
按键与家庭电话式地按键方式
3.复位电路
4.晶振电路
5.显示电路
显示容量
芯片工作电压
工作电流
字符尺寸
16*2个字符
4.5~5.5V
2.0mA(5v)
3.95*4.35mm
时刻显示输入输出地内容以及操作过程.
6.报警电路
当输入密码错误次数大于等于3次时,会发出声响报警.
7.开锁电路
四.软件设计
1.程序设计流程图
输入密码
2.程序代码
#include
#include
#defineLCM_DataP0
#defineucharunsignedchar
#defineuintunsignedint
#definew6//定义密码位数
sbitlcd1602_rs=P2^5。
sbitlcd1602_rw=P2^6。
sbitlcd1602_en=P2^7。
sbitScl=P3^4。
//24C02串行时钟
sbitSda=P3^5。
//24C02串行数据
sbitALAM=P2^1。
//报警
sbitKEY=P2^0。
//开锁
sbitopen_led=P2^2。
//开锁指示灯
bitoperation=0。
//操作标志位
bitpass=0。
//密码正确标志
bitReInputEn=0。
//重置输入充许标志
bits3_keydown=0。
//3秒按键标志位
bitkey_disable=0。
//锁定键盘标志
unsignedcharcountt0,second。
//t0中断计数器,秒计数器
voidDelay5Ms(void)。
unsignedcharcodea[]={0xFE,0xFD,0xFB,0xF7}。
//控盘扫描控制表
unsignedcharcodeb[]={"0123456789"}。
unsignedcharcodestart_line[]={"password:
"}。
unsignedcharcodename[]={"===CodedLock==="}。
//显示名称
unsignedcharcodeCorrect[]={"correct"}。
//输入正确
unsignedcharcodeError[]={"error"}。
//输入错误
unsignedcharcodecodepass[]={"pass"}。
unsignedcharcodeLockOpen[]={"open"}。
//OPEN
unsignedcharcodeSetNew[]={"SetNewWordEnable"}。
unsignedcharcodeInput[]={"input:
"}。
//INPUT
unsignedcharcodeResetOK[]={"ResetPasswordOK"}。
unsignedcharcodeinitword[]={"Initpassword..."}。
unsignedcharcodeEr_try[]={"error,tryagain!
"}。
unsignedcharcodeagain[]={"inputagain"}。
unsignedcharInputData[6]。
//输入密码暂存区
unsignedcharCurrentPassword[6]={1,3,1,4,2,0}。
//当前密码值
unsignedcharTempPassword[6]。
unsignedcharN=0。
//密码输入位数记数
unsignedcharErrorCont。
//错误次数计数
unsignedcharCorrectCont。
//正确输入计数
unsignedcharReInputCont。
//重新输入计数
unsignedcharcodeinitpassword[6]={0,0,0,0,0,0}。
//=====================5ms延时==============================
voidDelay5Ms(void)
{
unsignedintTempCyc=5552。
while(TempCyc--)。
}
//===================400ms延时==============================
voidDelay400Ms(void)
{
unsignedcharTempCycA=5。
unsignedintTempCycB。
while(TempCycA--)
{
TempCycB=7269。
while(TempCycB--)。
}
}
//================================24C02======================================
voidmDelay(uintt)//延时
{
uchari。
while(t--)
{
for(i=0。
i<125。
i++)
{。
}
}
}
voidNop(void)//空操作
{
_nop_()。
_nop_()。
_nop_()。
_nop_()。
}
/*起始条件*/
voidStart(void)
{
Sda=1。
Scl=1。
Nop()。
Sda=0。
Nop()。
}
/*停止条件*/
voidStop(void)
{
Sda=0。
Scl=1。
Nop()。
Sda=1。
Nop()。
}
/*应答位*/
voidAck(void)
{
Sda=0。
Nop()。
Scl=1。
Nop()。
Scl=0。
}
/*反向应答位*/
voidNoAck(void)
{
Sda=1。
Nop()。
Scl=1。
Nop()。
Scl=0。
}
/*发送数据子程序,Data为要求发送地数据*/
voidSend(ucharData)
{
ucharBitCounter=8。
uchartemp。
do
{
temp=Data。
Scl=0。
Nop()。
if((temp&0x80)==0x80)
Sda=1。
else
Sda=0。
Scl=1。
temp=Data<<1。
Data=temp。
BitCounter--。
}
while(BitCounter)。
Scl=0。
}
/*读一字节地数据,并返回该字节值*/
ucharRead(void)
{
uchartemp=0。
uchartemp1=0。
ucharBitCounter=8。
Sda=1。
do{
Scl=0。
Nop()。
Scl=1。
Nop()。
if(Sda)
temp=temp|0x01。
else
temp=temp&0xfe。
if(BitCounter-1)
{
temp1=temp<<1。
temp=temp1。
}
BitCounter--。
}
while(BitCounter)。
return(temp)。
}
voidWrToROM(ucharData[],ucharAddress,ucharNum)
{
uchari。
uchar*PData。
PData=Data。
for(i=0。
i i++) { Start()。 Send(0xa0)。 Ack()。 Send(Address+i)。 Ack()。 Send(*(PData+i))。 Ack()。 Stop()。 mDelay(20)。 } } voidRdFromROM(ucharData[],ucharAddress,ucharNum) { uchari。 uchar*PData。 PData=Data。 for(i=0。 i i++) { Start()。 Send(0xa0)。 Ack()。 Send(Address+i)。 Ack()。 Start()。 Send(0xa1)。 Ack()。 *(PData+i)=Read()。 Scl=0。 NoAck()。 Stop()。 } } //=======================================LCD1602============================= #defineyi0x80 //LCD第一行地初始位置,因为LCD1602字符地址首位D7恒定为1(100000000=80) #defineer0x80+0x40 //LCD第二行初始位置(因为第二行第一个字符位置地址是0x40) //----------------延时函数,后面经常调用---------------------- voiddelay(uintxms)//延时函数,有参函数 { uintx,y。 for(x=xms。 x>0。 x--) for(y=110。 y>0。 y--)。 } //--------------------------写指令--------------------------- write_1602com(ucharcom)//****液晶写入指令函数**** { lcd1602_rs=0。 //数据/指令选择置为指令...... lcd1602_rw=0。 //读写选择置为写 P0=com。 //送入数据 delay (1)。 lcd1602_en=1。 //拉高使能端,为制造有效地下降沿做准备 delay (1)。 lcd1602_en=0。 //en由高变低,产生下降沿,液晶执行命令 } //-------------------------写数据----------------------------- write_1602dat(uchardat)//***液晶写入数据函数**** { lcd1602_rs=1。 //数据/指令选择置为数据 lcd1602_rw=0。 //读写选择置为写 P0=dat。 //送入数据 delay (1)。 lcd1602_en=1。 //en置高电平,为制造下降沿做准备 delay (1)。 lcd1602_en=0。 //en由高变低,产生下降沿,液晶执行命令 } //-------------------------初始化------------------------- voidlcd_init(void) { write_1602com(0x38)。 //设置液晶工作模式,意思: 16*2行显示,5*7点阵,8位数据 write_1602com(0x0c)。 //开显示不显示光标 write_1602com(0x06)。 //整屏不移动,光标自动右移 write_1602com(0x01)。 //清显示 } //==============将按键值编码为数值========================= unsignedcharcoding(unsignedcharm) { unsignedchark。 switch(m) { case(0x18): k=1。 break。 case(0x28): k=2。 break。 case(0x48): k=3。 break。 case(0x88): k='A'。 break。 case(0x14): k=4。 break。 case(0x24): k=5。 break。 case(0x44): k=6。 break。 case(0x84): k='B'。 break。 case(0x12): k=7。 break。 case(0x22): k=8。 break。 case(0x42): k=9。 break。 case(0x82): k='C'。 break。 case(0x11): k='*'。 break。 case(0x21): k=0。 break。 case(0x41): k='#'。 break。 case(0x81): k='D'。 break。 } return(k)。 } //=====================按键检测并返回按键值=============================== unsignedcharkeynum(void) { unsignedcharrow,col,i。 P1=0xf0。 if((P1&0xf0)! =0xf0) { Delay5Ms()。 Delay5Ms()。 if((P1&0xf0)! =0xf0) { row=P1^0xf0。 //确定行线 i=0。 P1=a[i]。 //精确定位 while(i<4) { if((P1&0xf0)! =0xf0) { col=~(P1&0xff)。 //确定列线 break。 //已定位后提前退出 } else { i++。 P1=a[i]。 } } } else { return0。 } while((P1&0xf0)! =0xf0)。 return(row|col)。 //行线与列线组合后返回 } elsereturn0。 //无键按下时返回0 } //=======================一声提示音,表示有效输入======================== voidOneAlam(void) { ALAM=0。 Delay5Ms()。 ALAM=1。 } //========================二声提示音,表示操作成功======================== voidTwoAlam(void) { ALAM=0。 Delay5Ms()。 ALAM=1。 Delay5Ms()。 ALAM=0。 Delay5Ms()。 ALAM=1。 } //========================三声提示音,表示错误======================== voidThreeAlam(void) { ALAM=0。 Delay5Ms()。 ALAM=1。 Delay5Ms()。 ALAM=0。 Delay5Ms()。 ALAM=1。 Delay5Ms()。 ALAM=0。 Delay5Ms()。 ALAM=1。 } //=====================显示输入地N个数字,用H代替以便隐藏============================ voidDisplayOne(void) { //DisplayOneChar(9+N,1,'*')。 write_1602com(yi+5+N)。 write_1602dat('*')。 } //=======================显示提示输入========================= voidDisplayChar(void) { unsignedchari。 if(pass==1) { //DisplayListChar(0,1,LockOpen)。 write_1602com(er)。 for(i=0。 i<16。 i++) { write_1602dat(LockOpen[i])。 } } else { if(N==0) { //DisplayListChar(0,1,Error)。 write_1602com(er)。 for(i=0。 i<16。 i++) { write_1602dat(Error[i])。 } } else { //DisplayListChar(0,1,start_line)。 write_1602com(er)。 for(i=0。 i<16。 i++) { write_1602dat(start_line[i])。 } } } } voidDisplayInput(void) { unsignedchari。 if(CorrectCont==1) { //DisplayListChar(0,0,Input)。 write_1602com(er)。 for(i=0。 i<16。 i++) { write_1602dat(Input[i])。 } } } //========================重置密码================================================== //================================================================================== voidResetPassword(void) { unsignedchari。 unsignedcharj。 if(pass==0) { pass=0。 DisplayChar()。 ThreeAlam()。 } else { if(ReInputEn==1) { if(N==6) { ReInputCont++。 if(ReInputCont==2) { for(i=0。 i<6。 ) { if(TempPassword[i]==InputData[i])//将两次输入地新密码作对比 i++。 else { //DisplayListChar(0,1,Error)。 write_1602com(er)。 for(j=0。 j<16。 j++) { write_1602dat(Error[j])。 } ThreeAlam()。 //错误提示 pass=0。 ReInputEn=0。 //关闭重置功能, ReInputCont=0。 DisplayChar()。 break。 } } if(i==6) { //DisplayListChar(0,1,ResetOK)。 write_1602com(er)。 for(j=0。 j<16。 j++) { write_1602dat(ResetOK[j])。 } TwoAlam()。 //操作成功提示 WrToROM(TempPassword,0,6)。 //将新密码写入24C02存储 ReInputEn=0。 } ReInputCont=0。 CorrectCont=0。 } else { OneAlam()。 //DisplayListChar(0,1,again)。 //显示再次输入一次 write_1602com(er)。 for(j=0。 j<16。 j++) { write_1602dat(again[j])。 } for(i=0。 i<6。 i++) { TempPassword[i]=InputData[i]。 //将第一次输入地数据暂存起来 } } N=0。 //输入数据位数计数器清零 } } } } //=======================输入密码错误超过三过,报警并锁死键盘====================== voidAlam_KeyUnable(void) { P1=0x00。 { ALA
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 51 单片机 密码锁 课程设计 报告