|
- /*
- DIY 单管密码锁 - 只需1个数码管和两个按键和STC单片机制作的8位16进制密码锁
- 程序上电后,首先只有1个小数点亮,此为省电模式。
- 按下任意按键后点亮数码管,按下(增加键) 增加当前位的密码,按下(保存)键,输入下一位密码。
- 10秒钟无按键按下后,自动进入省电模式,同时清除客户输入的所有密码。
- 连接1个74HC138译码器外接8个LED,让客户知道是在输入第几位密码。
- 验证密码时,译码器上8个的LED会熄灭,密码错误时显示r 字样,正确时显示o字样。
- 密码正确后需要持续按下(保存)键,继电器才会吸合,放开后继电器也会释放。
- 按下增加按键1秒后,当前输入的密码位会以0.2秒的速度持续增加。
- 共阳数码管A~DP连接P1.0~P1.7口,增加按键、保存按键分别连接P3.0、P3.1和GND。
- 继电器控制口连接P3.2(低电平吸合),74HC138高电平使能有效端连接P3.6,其余两端连接GND,译码输入线连接P3.3~P3.5即可。
- 74HC138输出8端连接8个共阳LED,用于提示客户在第几位输入密码,74HC138以及8个LED可有可无,最好加上。
- LED以及数码管、可能需要串联限流电阻,按照实际额定电压电流进行串联,译码口接反按照源程序将a2和a0的定义颠倒即可。
- 程序延时时间不同型号的可能会有不同,按照型号以及晶振频率进行修改成准确的即可。
- 晶振频率:12Mhz 型号:STC89C****
- By:LscmunaixMG 2017-07-01
- */
- #include "reg51.h"
- #include "intrins.h"
- unsigned char code nbr[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //数码管段码数据
- unsigned char c[8]={0,0,0,0,0,0,0,0}; //客户输入的密码
- unsigned char code d[8]={1,2,3,4,10,11,12,13}; //正确的密码 1234ABCD,不能超过15(0xF)否则无法解锁。
- unsigned char a=0; //当前输入的密码 取值0~15
- unsigned char b=0; //在第几位输入密码 取值0~7
- unsigned char e=0; //段码缓存
- unsigned int f=0; //无按键时间计数
- unsigned char at=0; //增加按键按下时间计数
- sbit key=P3^0; //增加按键
- sbit key2=P3^1; //保存按键
- sbit relay=P3^2; //继电器 低电平吸合
- unsigned char delay=0; //延迟计数
- //74hc138 译码器与使能
- sbit a2=P3^3;
- sbit a1=P3^4;
- sbit a0=P3^5;
- sbit en=P3^6; //高电平译码有效
- void Delay10ms() //@12MHz
- {
- unsigned char i, j;
- i = 20;
- j = 113;
- do
- {
- while (--j);
- } while (--i);
- }
- bit ifpass(){
- unsigned char i=0;
- for(i=0;i<8;i++){ //密码匹配
- if(d[i] != c[i]) { //有1个不匹配
- return 0;
- }
- c[i]=0; //清除
- }
- return 1; //全匹配
- }
- void outb(){
- en=1;
- switch(b){
- case 0:a0=0;a1=0;a2=0;break;
- case 1:a0=0;a1=0;a2=1;break;
- case 2:a0=0;a1=1;a2=0;break;
- case 3:a0=0;a1=1;a2=1;break;
- case 4:a0=1;a1=0;a2=0;break;
- case 5:a0=1;a1=0;a2=1;break;
- case 6:a0=1;a1=1;a2=0;break;
- case 7:a0=1;a1=1;a2=1;break;
- default:break;
- }
- }
- void main(){
- f=1000; //初始省电
- outb();
- while(1){
- if(f >= 1000){ //10秒无按键
- //清除所有按键数据
- b=0;
- outb();
- en=0;
- a=0;
-
- while(f >= 1000){ //进入省电模式
- P1 = 0x7F;
- if(key == 0 || key2 == 0){ //省电模式有按键按下
- Delay10ms();
- while(key == 0 || key2 == 0){
- P1=nbr[0]&0x7F;
- }
- f=0; //退出省电模式
- }
- }
- en=1;
- }
- if(key == 0){ //按键按下
- Delay10ms(); //等待10毫秒
- if(key == 0){ //按键在按下
- f=0; //无按键时间清零
- a++; //计数加1
- a&=0xF;
- while(key == 0){ //等待按键放开
- P1=nbr[a];
- Delay10ms();
- at++; //按下时间计数
- while(key == 0 && at >= 100){ //按下时间到1秒
- P1=nbr[a];
- a++; //计数加1
- a&=0xF;
- for(delay=0;delay<20;delay++){
- Delay10ms();
- if(key == 1){ //按键放开
- at=0; //清除持续时间
- a--;
- a&=0xF;
- break;//跳出循环
- }
- }
-
- }
- }
- at=0;
-
- }
- }
- if(key2 == 0){ //保存按键按下
- Delay10ms(); //等待10毫秒
- if(key2 ==0){
- f=0;
- c[b]=a; //保存密码
- b++; //计数加1
- outb();
- a=0;
- if(b>7){ //输入到8位
- en=0;
- if(ifpass() == 1){ //正确
- e=0xA3;
- relay=0;
- } else { //错误
- e=0xAF;
- }
- a=0;
- } else {
- e=nbr[0]&0x7F;
- }
- while(key2 == 0){
- P1 = e;
- Delay10ms();
- }
- if(b>7){
- en=1;
- b=0;
- outb();
- }
- relay=1;
- }
- }
-
- P1=nbr[a];
- Delay10ms();
- f++;
-
- }
- }
复制代码
|
|