|
分享一个基于at89c51单片机的密码锁设计,含有源文件以及protues方正文件,可以完美运行.
以上所有资料包含仿真工程文件均在本帖最后下载附件。
密码锁的整体电路图:
程序流程图:
源程序:
- /*
- 课程名称:电子密码锁设计
- 设计任务:根据设定好的密码,采用按键实现6为的输入功能,
- 当用户输入的密码正确并且是在规定的时间(普
- 通用户要求在12s内输入正确的密码)时,锁就
- 打开,如果输入的三次密码不正确,就发出警报
- 声。如果用户的时间超过40秒,电路将报警80
- 秒,若电路连续报警三次,电路将锁定键盘5分
- 钟,防止他人的非法操作
- */
- #include"reg51.h"
- #include"intrins.h"
- #define uint unsigned int
- #define uchar unsigned char
- #define ulong unsigned long
- sbit bj = P3^0; //定义报警
- sbit led_y = P3^5; //定义黄色灯
- sbit led_r = P3^6; //定义红色灯
- sbit led_g = P3^7; //定义绿色灯
- ulong pwd = 234567; //定义电子锁密码
- uint gy = 0; //定义管理员/用户(管理员为1)标识
- uint ss = 0; //定义上锁标识(0时表示已上锁)
- uint flag = 0; //定义中断函数中所用到的标识
- uchar sd = 1; //定义键盘锁定(1为未锁)标识
- uint pcw = 0; //定义密码错误次数
- uint bjc = 0; //定义报警次数
- uint jp = 0; //定义键盘扫描值
- uint cnt = 0; //定义中断次数
- uint mcnt = 0;
- uint cs = 0; //定义超时标识
- uchar key;
- //uchar j;
- //定义共阳数码管段选数组
- uchar code table[11] ={0x3F,0x06,0x5B,0x4F,0x66,
- 0x6D,0x7D,0x07,0x7F,0x6F,0x08};
- //定义按键
- uchar code table1[16] = {0xee,0xde,0xbe,0x7e,
- 0xed,0xdd,0xbd,0x7d,
- 0xeb,0xdb,0xbb,0x7b,
- 0xe7,0xd7,0xb7,0x77};
- //定义储存按键值
- uchar table2[6];
- //定义短延迟函数
- void delay(uint n)
- {
- while(n--);
- }
- //定义延迟n s函数
- void delayns(uint n)
- {
- unsigned char a,b,c,e;
- for(e=n;e>0;e--)
- for(c=167;c>0;c--)
- for(b=171;b>0;b--)
- for(a=16;a>0;a--);
- _nop_(); //if Keil,require use intrins.h
- }
- //定义初始化函数
- void init()
- {
- uchar i,k;
- led_y = 0;
- led_r = 1;
- led_g = 1;
- bj = 1;
- EA = 1; //打开总中断
- EX1 = 1; IT1 = 1; //打开外部中断1,并设置触发方式为下降触发方式
- TMOD = 0X01; //设置定时器0工作方式1
- TH0 = (65536 - 50000)/256;
- TL0 = (65536 - 50000)%256; //给定时器0赋值为50ms
- for(i = 0;i < 6; i++)
- {
- table2[i] = 10;
- }
- for(k = 0;k<8;k++)
- {
- P0=0x08;
- P2 = k;
- }
-
- }
- //定义上锁中断函数
- void INT_0() interrupt 0
- {
- uchar h;
- ss = 0; //密码锁上锁
- led_g = 1;
- for(h = 0;h < 6; h++) //初始化table2[]为10
- {
- table2[h] = 10;
- }
- }
- //定义管理员/用户切换中断函数
- void INT_1() interrupt 2
- {
- uchar h;
- if(flag == 0)
- {
- gy = 1; //关闭管理员指示灯
- led_y = 1; //关闭密码错误指示灯
- flag = 1;
- for(h = 0;h < 6; h++) //初始化table2[]为10
- {
- table2[h] = 10;
- }
- }
- else
- {
- gy = 0; //关闭管理员指示灯
- led_y = 0; //关闭密码错误指示灯
- flag = 0;
- for(h = 0;h < 6; h++) //初始化table2[]为10
- {
- table2[h] = 10;
- }
- }
- }
- //定义计时器中断函数
- void timer() interrupt 1
- {
- TH0 = (65536 - 50000)/256;
- TL0 = (65536 - 50000)%256;
- ++cnt; //中断一次加以
- if(cnt == 20) //每1秒
- {
- cnt = 0;
- ++mcnt;
- if(gy) //管理员时
- {
- if(mcnt > 40)
- {
- bjc++;
- cs = 1;
- bj = 0;
- delayns(80);
- bj = 1;
- }
- else if(mcnt > 5) //大于5秒时
- {
- cs = 1;
- }
- else //小于5秒时
- {
- cs = 0;
- }
- }
- else //用户时
- {
- if(mcnt > 40)
- {
- bjc++;
- cs = 1;
- bj = 0;
- delayns(80);
- bj = 1;
- }
- else if(mcnt > 12) // 大于12秒时
- {
- cs = 1;
- }
- else //小于1秒时
- {
- cs = 0;
- }
- }
-
- }
- }
- //定义显示函数
- void display( uint wei, uint duan)
- {
- P2 = wei;
- P0 = table[duan];
- delay(50);
- }
- //定义键盘扫描函数并显示按键
- void scan()
- {
- uchar i,j,h,k,m=20, e = 1;
- while(j != 6) //读取六个键值
- {
-
- P1 = 0xf0; //置行为0.列为1,读列值
- if(P1 != 0xf0) //判断有无键盘被按下
- {
- delay(19000); //消振
- if(P1 != 0xf0) //确实有键盘被按下
- {
- uchar temp = P1; //存储列列读入值
- if(j==5) //当最后一位密码输入时
- {
- ET0 = 0; //关闭定时/计数0中断
- }
- if(j == 0) //当要输入第一个密码时
- {
- ET0 = 1; TR0 = 1; //开启定时/计数0中断
- led_r = 1; //关闭报警灯
- led_g = 1; //关闭打开指示灯
- for(h = 0;h < 6; h++) //初始化table2[]为10
- {
- table2[h] = 10;
- }
- }
- P1 = 0x0f; //置列为0.行为1,读行值
- key = temp|P1; //将列、行综合,读取键值
- for(i = 0; i < 10; i++)
- {
- if(key == table1[i]) //判断键值
- {
- table2[j] = i; //将密码存储到table2[]中
- j++;
- break;
- }
- }
- }
- }
- for(k = 0;k < 6;k++) //显示输入键值
- {
- uint n=20;
- while(n--)
- display(k,table2[k]);
- }
- }
- for(k = 0;k < 6;k++) //显示输入键值
- {
- uint n=20;
- while(n--)
- display(k,table2[k]);
- }
- }
- //定义报警函数
- void speaker(uint n)
- {
- uint i;
- for(i = 0; i<n; i++)
- {
- bj = 0;
- delayns(1);
- bj = 1;
- }
- }
- //定义密码正确函数验证函数
- void mmyz()
- {
- uchar mmy;
- uint m1 = pwd/100000; //取得密码的第一位
- uint m2 = pwd%100000/10000; //取得密码的第二位
- uint m3 = pwd%100000%10000/1000; //取得密码的第三位
- uint m4 = pwd%100000%10000%1000/100; //取得密码的第四位
- uint m5 = pwd%100000%10000%1000%100/10; //取得密码的第五位
- uint m6 = pwd%100000%10000%1000%100%10; //取得密码的第六位
- //判断密码的正确性
- mmy = (m1==table2[0])&(m2==table2[1])&(m3==table2[2])
- &(m4==table2[3])&(m5==table2[4])&(m6==table2[5]);
- if(!cs) //没超过规定时间
- {
- if(mmy == 1) //密码正确
- {
- ss = 1;
- led_g = 0; //打开密码锁。绿灯亮
- EX0 = 1; IT0 = 1; //打开外部中断0,并设置触发方式为下降触发方式
- pcw = 0; //密码错误次数清零
- bjc = 0; //报警次数清零
- bj = 1; //关闭报警
- }
- else //密码错误
- {
- pcw++; //密码错误加1
- led_r = 0; //密码错误,红灯亮
- if(pcw >=3)
- {
- pcw = 0;
- bjc++;
- P2 = 0xff;
- speaker(1);
- if(bjc == 3)
- {
- bjc = 0; //报警
- led_r = 0;
- led_g = 0;
- P2 = 0xff;
- EA = 0; //关闭总中断
- delayns(300); //锁定5分钟
- EA = 1; //开启总中断
- led_r = 1;
- led_g = 1;
- }
- }
- }
- }
- else //超过规定时间
- {
- uchar h;
- for(h = 0;h < 6; h++) //初始化table2[]为10
- {
- table2[h] = 10;
- }
- }
-
- }
- //定义主函数
- void main()
- {
- uchar i;
- init(); //初始化程序
- while(1)
- {
- if(!ss)
- {
- if(gy) //管理员时
- {
- if(sd == 1)
- {
- scan(); //调用键盘扫面函数,接收输入的键值
- mmyz(); //验证密码
- }
- }
- else //用户时
- {
- if(sd == 1)
- {
- scan(); //调用键盘扫面函数,接收输入的键值
- mmyz(); //验证密码
- }
- }
- }
- else
- {
- for(i = 0;i < 6;i++) //显示输入键值
- {
- table2[i] = 10;
- }
- for(i = 0;i < 6;i++) //显示输入键值
- {
- uint n=20;
- while(n--)
- display(i,table2[i]);
- }
- }
- }
- }
复制代码 |
-
报警电路.png
(2.88 KB, 下载次数: 219)
-
管理员状态下开始.png
(16.58 KB, 下载次数: 194)
-
管理员状态下密码错误.png
(16.85 KB, 下载次数: 190)
-
管理员状态下密码正确.png
(16.6 KB, 下载次数: 190)
-
扫描按键电路.png
(4.84 KB, 下载次数: 187)
-
数码管显示电路.png
(5.13 KB, 下载次数: 182)
-
用户状态下开始.png
(16.58 KB, 下载次数: 198)
-
用户状态下密码错误.png
(16.65 KB, 下载次数: 186)
-
用户状态下密码正确.png
(16.73 KB, 下载次数: 171)
-
整个电路.png
(23.68 KB, 下载次数: 206)
-
指示灯电路.png
(4.75 KB, 下载次数: 197)
-
主电路部分按键选择电路.png
(13.91 KB, 下载次数: 192)
-
-
基于at89c51的电子密码锁设计.7z
296.25 KB, 下载次数: 338, 下载积分: 黑币 -5
评分
-
查看全部评分
|