程序功能: 1、开锁: 下载程序后,直接按六次S6(即代表数字0),8位LED亮,锁被打开,输入密码时,
六位数码管依次显示小横杠。
2、更改密码:
只有当开锁(LED亮)后,该功能方可使用。
首先按下更改密码键S16,然后设置相应密码,此时六位数码管会显示设置密码对应
的数字。最后设置完六位后,按下S17确认密码更改,此后新密码即生效。
3、重试密码:
当输入密码时,密码输错后按下键S18,可重新输入六位密码。
当设置密码时,设置中途想更改密码,也可按下此键重新设置。
4、关闭密码锁:
按下S19即可将打开的密码锁关闭。
推荐初级演示步骤:输入原始密码000000按6次S6密码正确后LED全部亮表示锁已打开---按下更
改密码按键S16---按S6到S15设置密码---按S17
确认密码更改---按S19关闭密码锁---输入新的密码打开密码锁
功能键
S6---S15 数字键0-9
S16---更改密码 S17---更改密码完毕后确认
S18---重试密码、重新设定 S19---关闭密码锁
初始密码:000000 密码位数:6位
注意:掉电后,所设密码会丢失,重新上点时,密码恢复为原始的000000
与P1相连的8位发光LED点亮代表锁被打开;熄灭代表锁被锁上
代码借鉴了例程,例程没什么注释,我基本上很多关键地方都给出了注释,我觉得已经很走心了,代码这种东西要多看多练,稍微几天不打就没啥感觉了,Keil代码下载:
密码锁.rar
(40.82 KB, 下载次数: 41)
单片机源程序如下:
- #include <REGX52.H>
- /******数据变量定义*******/
- typedef unsigned char uchar;
- typedef unsigned int uint;
- /******数据变量定义*******/
- /******硬件接口定义*******/
- sbit dula = P2^6;
- sbit wela = P2^7;
- sbit beep = P2^3;
- /******硬件接口定义*******/
- /******使用到的变量定义*******/
- uchar old1,old2,old3,old4,old5,old6;//旧密码,000000
- uchar new1,new2,new3,new4,new5,new6;//单片机所接受到的新密码
- uchar wei,temp,keyvalue;//wei的增加可以让我们去控制对应的数码管,temp读取P3口的状态,keyvalue为矩阵键盘的键值
- uchar a=16;b=16;c=16;d=16;e=16;f=16;//作用于数码管显示函数中的变量,刚开始为不亮
- uchar code table[]=
- {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
- 0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};//共阴数码管,0x00:关闭数码管 0x40:数码管显示'-'这个字样
- uchar code we[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//数码管对应的位码
- bit finish,ok,close,allow,change,reinput;
- // change表示s16按键为修改密码键
- // finish表示密码全部输完的标志
- // ok表示s17确认键按下,密码锁的密码已经更改完毕
- // close表示密码锁关闭,灯也会跟着数码管关闭,由s19按键负责
- // allow表示只有密码锁密码正确的情况下,才能进行修改密码的操作
- // reinput表示密码重新输入,主要用在密码输错或者中途改密码时觉得输错密码的情况下
- /******使用到的变量定义*******/
- /******延时函数*******/
- void delay(unsigned char i)
- {
- uchar j,k;
- for(j=i;j>0;j--)
- for(k=125;k>0;k--);
- }
- /******延时函数*******/
- /******看起来方便的函数*******/
- /*我看了很多关于74HC573级联驱动数码管的代码
- 代码看起来挺长的,我感觉我这种写法会方便一点
- 不用写这么多*/
- void convenience(uchar duan,uchar wei)
- {
- dula = 0;//不懂的可以去看74HC573的芯片手册或者这个芯片驱动数码管的视频看一下
- P0 = table[duan];//传递段码
- dula = 1;
- dula = 0;
-
- wela = 0;
- P0 = we[wei];//传递位码
- wela = 1;
- wela = 0;
- delay(5);
- }
- /******看起来方便的函数*******/
- /******数码管显示函数*******/
- //此处abcdef为形参与上面的abcdef不同,上面的abcdef为实参,用来让六位数码管显示想要的符号/数字
- void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f)
- {
- convenience(a,0);
- convenience(b,1);
- convenience(c,2);
- convenience(d,3);
- convenience(e,4);
- convenience(f,5);
- }
- /******数码管显示函数*******/
- /******按键松手检测函数******/
- //仿真的我不清楚但是实物的话,松手检测是必须的
- //感觉矩阵按键的写法不能跟单个按键一样————可以不加松手检测
- //我就曾经因为没加矩阵按键松手检测导致效果有问题
- //所以我觉得应该要加
- void keyRelease()
- {
- while(temp!=0xf0)
- {
- temp = P3;
- temp = temp & 0xf0;
- beep = 0;//按一下蜂鸣器就响
- }
- beep = 1;//蜂鸣器关掉
- }
- /******按键松手检测函数******/
- /******按键扫描函数*******/
- void keyscan()
- {
- P3 = 0xfe;temp = P3;temp = temp & 0xf0;//检测第一行按键是否有被按下的
- if(temp!=0xf0)//与独立按键写法类似
- {
- delay(10);//延时
- if(temp!=0xf0)
- {
- temp = P3;//读取P3状态看看是哪个按键被按下
- switch(temp)
- {//wei++是干什么用的呢,我会在下面的函数中告诉你
- case 0xee:keyvalue=0;wei++;break;//看不懂键值的,先去看看矩阵按键的知识
- case 0xde:keyvalue=1;wei++;break;
- case 0xbe:keyvalue=2;wei++;break;
- case 0x7e:keyvalue=3;wei++;break;
- default:break;
- }
- keyRelease();//松手检测
- }
- }
- P3 = 0xfd;temp = P3;temp = temp & 0xf0;//检测第二行按键是否有被按下的
- if(temp!=0xf0)//与独立按键写法类似
- {
- delay(10);//延时
- if(temp!=0xf0)
- {
- temp = P3;//读取P3状态看看是哪个按键被按下
- switch(temp)
- {
- case 0xed:keyvalue=4;wei++;break;//看不懂键值的,先去看看矩阵按键的知识
- case 0xdd:keyvalue=5;wei++;break;
- case 0xbd:keyvalue=6;wei++;break;
- case 0x7d:keyvalue=7;wei++;break;
- default:break;
- }
- keyRelease();//松手检测
- }
- }
- P3 = 0xfb;temp = P3;temp = temp & 0xf0;//检测第三行按键是否有被按下的
- if(temp!=0xf0)//与独立按键写法类似
- {
- delay(10);//延时
- if(temp!=0xf0)
- {
- temp = P3;//读取P3状态看看是哪个按键被按下
- switch(temp)
- {
- case 0xeb:keyvalue=8;wei++;break;//看不懂键值的,先去看看矩阵按键的知识
- case 0xdb:keyvalue=9;wei++;break;
- case 0xbb:change=1;wei=0;break;//s16按键,修改密码
- case 0x7b:
- if(allow)//只有密码正确,allow才会为1
- {
- ok = 1;//确认密码修改完毕
- }
- break;//s17按键 密码修改完毕确认键
- default:break;
- }
- keyRelease();//松手检测
- }
- }
- P3 = 0xf7;temp = P3;temp = temp & 0xf0;//检测第四行按键是否有被按下的
- if(temp!=0xf0)//与独立按键写法类似
- {
- delay(10);//延时
- if(temp!=0xf0)
- {
- temp = P3;//读取P3状态看看是哪个按键被按下
- switch(temp)
- {
- case 0xe7:reinput=1;break;//s18 重新修改或输入密码
- case 0xd7:close=1;break;//s19 关闭密码锁和灯
- default:break;
- }
- keyRelease();//松手检测
- }
- }
- }
- /******按键扫描函数*******/
- /******输入密码函数*******/
- void InputPassword()
- {
- if(!finish)//finish为1表示密码全部输入完毕,为0表示密码没输完
- {
- //wei=0,就是不操控数码管 wei=1就是操控第一个数码管,wei=2就是操控第二个数码管,依此类推,这就是wei的作用
- switch(wei)
- {
- case 1:new1=keyvalue;//第一个数码管接收矩阵按键的密码信息
- if(!allow)//在密码没输入正确前,每按一次按键数码管依次显示'-',相当于隐藏密码吧
- a=17;//如果密码错误,则数码管显示'-'字符
- else//allow为1,一般就是说可以改密码了,这个时候每按一次按键,数码管依次显示对应的数字
- a=keyvalue;//将键值赋给a,a再传递到数码管显示函数
- break;
- case 2:new2=keyvalue;//照猫画虎更上面类似
- if(a==17)
- b=17;//如果第一个数码管显示'-'那么接下来的数码管也要显示'-'
- else
- b=keyvalue;
- break;
- case 3:new3=keyvalue;
- if(a==17)
- c=17;//如果第一个数码管显示'-'那么接下来的数码管也要显示'-'
- else
- c=keyvalue;
- break;
- case 4:new4=keyvalue;
- if(a==17)
- d=17;//如果第一个数码管显示'-'那么接下来的数码管也要显示'-'
- else
- d=keyvalue;
- break;
- case 5:new5=keyvalue;
- if(a==17)
- e=17;//如果第一个数码管显示'-'那么接下来的数码管也要显示'-'
- else
- e=keyvalue;
- break;
- case 6:new6=keyvalue;
- if(a==17)
- f=17;//如果第一个数码管显示'-'那么接下来的数码管也要显示'-'
- else
- f=keyvalue;
- finish = 1;//就此,六位数码管密码全部输完
- break;
- }
- }
- }
- /******输入密码函数*******/
- /******验证密码正确函数*******/
- void CheckPassword()
- {
- if(finish)
- {
- //新旧密码对比,正确就allow=1
- if((new1==old1)&(new2==old2)&(new3==old3)&(new4==old4)&(new5==old5)&(new6==old6))
- {
- allow = 1;//只有原始密码正确才可以进行下面的修改密码的操作
- }
- }
- }
- /******验证密码正确函数*******/
- /******主函数******/
- void main()
- {
- while(1)
- {
- keyscan();//按键扫描
- InputPassword();//输入密码
- CheckPassword();//确认密码
- if(allow)
- {
- P1=0x00;//灯全亮
- if(!change)//没有进行修改密码操作时,应把finish置零
- finish = 0;
- }
- if(change)//进行修改密码操作时
- {
- if(allow)//原始密码正确才能进行操作
- {
- while(!finish)//只有密码全部输完才能退出循环
- {
- keyscan();//因为卡在这里的while循环,不能再返回到上面的扫描语句,故要加上去
- InputPassword();//与上同理
- if(reinput|close)//如果重新修改密码或者关闭密码锁
- {
- finish = 1;//退出循环
- break;
- }
- display(a,b,c,d,e,f);//显示修改密码的数字
- }
- }
- }
- if(ok)//密码修改完毕
- {
- ok = 0;//不用多说
- wei = 0;//从头开始输密码啦
- change = 0;//不用再改啦
- old1=new1;old2=new2;old3=new3; //此时,旧的密码将被代替
- old4=new4;old5=new5;old6=new6;
- a=b=c=e=f=d=16;//数码管不亮,你可以理解为视觉效果更好看一点把
- }
- if(reinput)//重新输入密码
- {
- reinput = 0;//这个肯定要等于0吧,不然就一直逃不出这个if了
- wei = 0;//这个肯定也要0吧,不然一直wei++就超过了数码管的位数啦
- finish = 0;//你重新输入密码,是不是密码没输完,那么这个肯定也要0吧
- new1=new2=new3=new4=new5=new6=0;//把我们之前输错的密码全清零了
- a=b=c=e=f=d=16;//你重新输入密码,数码管不亮
- }
- if(close)//关闭密码锁
- {
- close = 0;//关闭数码管,万物皆0
- allow = 0;
- wei = 0;
- finish = 0;
- change = 0;
- P1 = 0xff;//灯要关啦
- new1=new2=new3=new4=new5=new6=0;//把我们之前输错的密码全清零了
- a=b=c=e=f=d=16;//你重新输入密码,数码管不亮
- }
- display(a,b,c,d,e,f);//不属于任何一个if,实时显示
- }
- }
- /******主函数******/
复制代码 原本想发一个演示的视频但是容量有点大,就不发了
|