标题:
基于清翔单片机的简易数码管密码锁程序
[打印本页]
作者:
电子浪人
时间:
2022-1-28 18:26
标题:
基于清翔单片机的简易数码管密码锁程序
程序功能: 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)
2022-1-28 18:25 上传
点击文件名下载附件
单片机源程序如下:
#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,实时显示
}
}
/******主函数******/
复制代码
原本想发一个演示的视频但是容量有点大,就不发了
作者:
快乐眼泪
时间:
2022-3-26 22:00
这个程序断电后不能记忆新密码吧?
作者:
suqianfu
时间:
2022-3-31 22:20
快乐眼泪 发表于 2022-3-26 22:00
这个程序断电后不能记忆新密码吧?
加上EEPROM程序就可以断电记忆了。在主程序那里读取一下设置的密码。
作者:
xianfajushi
时间:
2023-2-24 13:50
刚刚出炉的普中板子密码锁8位不用数组,三次错误显示ERROR演示。
数码管驱动138-573,错误有蜂鸣,正确LED显示,单按键确认密码。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1