单片机密码锁带参考课程设计论文 单片机程序+proteus仿真图+原理图+PCB
本次设计使用AT89S52实现一基于单片机的电子密码锁。本系统由单片机系统、矩阵键盘、LCD显示和报警系统组成。系统能完成开锁、超次锁定、修改用户密码基本的密码锁的功能。本系统成本低廉,功能实用。
1、密码显示 为了帮助用户确认是否有键按下,特在电路中设置了模拟显示电路;而为了防止密码外泄;显示时,并不是显示用户按下的数字符号,而是以一个特定的字母符号提醒用户是否有键按下。有键按下,就会显示出字符“*”,没键按下,则不会显示字符。 2、密码更改 设置6位密码,密码通过键盘输入,当按下更改密码的功能键时,要先输入原来的密码,正确无误后,再输入新的密码,最后按下确认键即可。 3、本机键开锁 当用户键入正确密码后,在按确认键,便会自动开锁。但用户键入密码时应注意:数字与数字之间的间隔时间为30秒,例如密码为086541,当键入第一个数字0后应在30秒内键入第二个数字8,否则就会视为无效。如果键入完密码后不按确认键系统会当做放弃开锁处理。
单片机密码锁proteus仿真图文件:
课程设计论文里面的电路图:
单片机密码锁ppt文件:
课程设计论文目录:
目 录
1 前言 4
1.1 数字随机键盘的来源和意义 4
1.2单片机概述 4
2 数字密码锁总体设计说明 5
2.1 总体开发计划 5
2.1.1 基本功能 5
2.1.2 扩展功能 5
2.2 总体设计方案 5
2.2.1 单片机的选择 5
2.2.2 键盘的选择 6
2.2.3 显示模块的选择 6
2.2.4 报警模块的选择 6
3 硬件设计说明 7
3.1 硬件总体设计方案 7
3.1.1 硬件功能模块的划分 7
3.1.2 硬件设计目标 7
3.2 硬件单元设计 7
3.2.1 主控电路 7
3.2.2 显示电路 8
3.2.4 键盘电路 10
3.2.5 报警电路 10
4 软件设计说明 11
4.1 软件设计总体方案 12
4.1.1 软件设计目标 12
4.1.2 软件功能模块划分 12
4.2 软件设计 13
4.2.1 主函数的程序设计 13
4.2.2 系统初始化的程序设计 14
5 系统调试 16
6 总结 19
参考文献 20
附件 21
主程序(完整代码请下载附件):
- /***********天马电子设计*******************/
- #include<AT89X52.h>
- #include "液晶.h"
- #include "stdlib.h"
- #include<Function.h>
- #include "fun_char.h"
- #define uchar unsigned char
- #define uint unsigned int
- sbit beep=P2^4; //警铃
- uint TIM=0;
- uchar mydata[6]; //输入密码
- uchar testdata[6];//存储器保存的密码
- uchar ok_stop=0;
- struct key
- {
- uchar time; //按键时间控制
- uchar down; //输入次数
- uchar open; //键盘打开
- uchar close;//键盘关闭
- uchar setnew;//设置新的密码
- uchar error; //输入密码错误次数
- uchar reset_num; //设置密码次数记录(输入新的密码,需要输入两次,在第二次输入后开始比较)
- uchar reset; //设置新的密码标志位
- uchar disclose; //关闭显示
- uint time_n; //定时器中断次数
- }key={0,0,0,0,0,0,0,0,0,0};
- unsigned char code KEYTAB[16] ={0x7e,0xBE,0XBD,0xBB,0xDE,0xDD,0xDB,0xEE,0xED,0xEB,0x7D,0x7B,0x77,0xb7,0xd7,0xe7};
- void clear_all();//
- /*******************************************
- *函数名称:delay(uint t)延时函数
- *函数作用:延时1ms左右
- *
- *********************************************/
- void delay(uint t)
- {
- uint i,j;
- for(i=0;i<t;i++)
- for(j=0;j<110;j++);
- }
- /*******************************************
- *函数名称:check_code( )
- *函数作用:1、对比输入的密码和存储器中的密码是否一致,一致
- 则开锁。不一致,则记录错误次数,如果次数大于3次,
- 则锁键盘,并报警
- 2、当设置新的密码时,检测两次输入的密码是否一致
- 一致则保存,
- *********************************************/
- void check_code(void)
- {
- unsigned char i=0;
- unsigned char dif_label=0;
- if(key.setnew==0||key.reset_num==1) //正处于开锁状态时输入6位完成或者是设置新的密码时第二次输入完成
- {
- for(i=0;i<6;i++) //对这六位和实际的密码进行比较
- {
- if((mydata[i]!=testdata[i]))//如果有一位不同
- {
- if(key.setnew==0) //如果现在正处于开锁状态
- {
- key.error++;//输入密码错误次数记录
- if(key.error>2)//如果大于2次
- {
- if(key.open==0)//如果现在没有锁键盘
- {
- lock_char(); //显示KEY IS LOCK
- key.open=1; //锁键盘
- TR1=1; //定时器启动
- key.disclose=1; //关闭显示
- key.error=0; //错误清楚
- key.time=0; //按键时间清零
- }
- }
- else //如果没有超过2次
- {
- error_char(); //显示输入密码错误
- beep=0;
- delay(1500);//延时3s左右
- beep=1;
- clear();// 变量清零
- }
- }
- else //如果处于设置密码状态,但是设置的密码两次输入不一样
- {
-
- different_char(); //输出it's different
- delay(1000); //延时2s
- key.down=0; //变量清除
- reset_char();//重新输入新的密码,这个地方最好有个时间记录
- dif_label=1; //
- key.reset_num=0;// 提示重新输入密码
- }
- break;//退出循环
- }
- }
- }
-
- if(key.setnew==1)//如果正输入新的密码
- {
- if(key.reset_num==0) //如果是第一次输入新的密码,则i=6,主要是为了下面好判断
- {
- i=6;//自动保存了
- }
-
- }
- if(i==6&&dif_label==0) //如果输入密码正确,
- {
-
- if(key.setnew==0)//输入密码正确
- {
- key.error=0; //清零
- key.down=0;//复位
- ok_char(); //显示PASSWORD OK
- key.disclose=1;// 停止显示光标闪烁
- key.reset=1;// 允许设置新的密码
- ok_stop=1;//
-
- }
- else//如果现在正处于输入新的密码状态
- {
-
- if(key.reset_num==0) //如果是第一次输入
- {
-
- for(i=0;i<6;i++) //保存密码到testdata中
- {
- testdata[i]=mydata[i];//保存数据
- }
- key.reset_num=1;//进入第二次数据输入
- key.down=0;//清零等待第二次数据输入
- again_char();//现在INPUT AGAIN
- }
- else
- {
- //设置密码成功
- ISendStr(AT24C02, 0 , &mydata[0],6); //保存密码
- delay(20);//
- ok_char(); //显示PASSWORD OK
- delay(1000);//不知道什么时候复位啊
- key.reset_num=0;//这里要重新复位了
- key.down=0;
- ok_stop=1;
- key.disclose=1;//这个地方不再显示了
-
- }
- }
- }
- }
- /*******************************************
- *函数名称:keyscan( ) 键盘扫描函数
- *函数作用: 1、扫描键盘,获得键值
- 2、显示输入键值(*号),并保存
- 3、读取功能按键,并执行相应的功能
- 按键的功能划分如下:
- | 7 | 8 | 9 | 修改密码键 |
- ---------------------------------------
- | 4 | 5 | 6 | 重新输入密码键 |
- ---------------------------------------
- | 1 | 2 | 3 | 没有使用 |
- ---------------------------------------
- | |确 | 清 |
- | 0 |认 | 除 | 没有使用 |
- ---------------------------------------
- *********************************************/
- unsigned char keyscan(void)
- {
- unsigned char i=0;
- unsigned char redat;
- unsigned char keynum=0;
- P3=0XFF;
- P1=0XF0;
- redat=P3&0XF0;
- if(redat!=0xF0)
- {
- delay(12);
- redat=P3&0XF0;//再次延时检测
- if(redat!=0xF0)
- {
- keynum=redat;//获得第四位
- P1=0XFF;//看来这个地方是必须的
- P3=0X0F;//开始读取高四位
- delay(1);
- redat=P1&0X0F;
- keynum|=redat;
- for(i=0;i<16;i++)
- {
- if(keynum==KEYTAB[i])
- {
-
- if(key.down<6)//如果输入次数小于6
- {
- if(i<10&&ok_stop==0) //如果输入键值小于10即0-9
- {
- key.time_n=0;//键盘时间计数清零
- mydata[key.down]=i; // 保存按键
- lcd_pos(key.down+68); //
- lcd_wdat(0x2a);//显示星号
- key.down++; //按键次数加1
- key.time=1;//按键计时开始,如果长时间没有按键按下,认为输入无效
- TR1=1;//启动定时器
- }
- }
- /*****如果按下清除键******/
- if(i==11)//等待按下确认键
- {
- if(key.down>0) //如果当前还有输入的数据
- {
- key.down=key.down-1;//
- mydata[key.down]=0;//还要再弄一些标志变量
- lcd_pos(key.down+68);
- lcd_wdat(0x20);//将星号显示关闭
- key.time_n=0;
- }
- }
- /**************等待按下确认键************/
- if(key.down==6)//如果已经输入了6个数据
- {
- if(i==10) //确认键的键值是10
- {
- TR1=0;//关闭定时器
- key.time_n=0;//重新准备开始
- key.time=0;
- check_code();//开始对比输入的密码值和存储器中保存的密码
-
- }
- }
- if(key.reset==1) //只有当锁打开的时候,才允许设置新的密码
- {
- if(i==15)//没有锁键盘
- {
- key.setnew=1;//允许输入新的密码
- key.disclose=0;//重新打开
- reset_char();
- ok_stop=0;
- }
- }
- if(i==14) //这个按键相当于复位了
- {
- clear_all();//重新复位重新开始
-
- }
- delay(400);//键盘延时
- }
- }
- }
- }
- return 0;
- }
- /*******************************************
- *函数名称:display( ) 显示函数
- *函数作用:
- 1、当输入数字键值小于6时,光标闪烁
- *********************************************/
- void display()
- {
- if(key.down<6)
- {
- delay(120); //这个地方显示光标闪烁
- lcd_pos(68+key.down);//
- lcd_wcmd(0x0f);
- delay(140);
- lcd_pos(68+key.down);//光标闪烁
- lcd_wcmd(0x0c); //
- }
-
- }
- /*******************************************
- *函数名称:init_timer( ) 定时器初始化函数
- *函数作用:
- 定时器定时时间1ms
- *********************************************/
- void init_timer() //
- {
- TMOD|= 0x10;//
- TH1 = 0xEC;
- TL1 = 0x78;
- ET1=1;
- EA=1;
- TR1 = 0; //关闭
- }
- /*******************************************
- *函数名称:clear( ) 清除函数
- *函数作用:
- 只清除按下的次数,以及初始化字符显示
- *********************************************/
- void clear() reentrant
- {
- key.down=0;
- ok_stop=0;
- init_char();
- }
- /*******************************************
- *函数名称:clear_all( ) 清除所有的标志变量
- *函数作用:
-
- *********************************************/
- void clear_all() //所有的变量清零
- {
- clear();
- TR1=0;//关闭定时器
- key.close=0;
- beep=1;
- key.reset=0;
- key.setnew=0;
- key.error=0;
- key.reset_num=0;//全部清零
- key.disclose=0;
- key.open=0;
- }
- /*******************************************
- *函数名称:main( ) 主函数
- *函数作用:
- 这个函数必须有的
- *********************************************/
- void main()//
- {
- uchar i=0;
- beep=1;//初始化蜂鸣器
- lcd_init();
- init_char();
- init_timer();
- while(1)
- {
-
- if(key.open==0)//如果键盘没有锁,调用键盘扫描
- {
- keyscan();
- }
- if(key.disclose==0) //如果显示没有关闭,调用display
- {
- display(); //显示字符应该控制住的
- }
- if(key.close==1) //如果三次密码输入错误,报警完成后开始清除所有变量
- {
-
- clear_all();
- }
-
- }
- }
- /*******************************************
- *函数名称:TI_int1( ) 定时器1中断处理函数
- *函数作用:
-
- *********************************************/
- void T1_int1(void) interrupt 3//定时器中断
- {
- TH1 = 0xEC;
- TL1 = 0x78;
- //beep=~beep;
- if(key.time==1)
- {
- key.time_n++;
- if(key.time_n>1099)
- {
- //清零
- key.close=1;
- key.time_n=0;
- TR1=0;//关闭定时器
- key.time=0;
- }
- }
- else
- { TIM++;
- beep=0;
- if(TIM>1300)
- {
- TIM=0;
- key.open=0;
- key.close=1;
- key.time=0;
- beep=1;
- }
-
- }
-
- }
复制代码
基于单片机电子密码锁设计.rar
(4.66 MB, 下载次数: 330)
|