本文章是基于51单片机的简易密码锁,无掉电保护,所以没有用到I^C总线协议,仅用到数码管显示,矩阵键盘扫描,led显示。
本例程主要实现功能为:定义一个六位数的初始密码,用矩阵输入,输入正确后led被点亮,错误不点亮;摁下任意一个按键蜂鸣器发出声音,松下按键蜂鸣器关闭;按下更改按键可以改密码,改密码时数码管实时显示。按下重试键可以重新输入密码,按下关闭键所有数据清零。
使用步骤,打开电源,输入6位数初始密码,输入正确锁打开,led亮起;输入正确后,按下更改键后,可以更改密码,改密码时数码管会显示所要更改的密码,更改完成过后按下ok键,新密码被记住,按下close键,重新输入新密码,输入正确后会开锁并且可以重新更改密码。
(参考自清翔51单片机)
文章来源:https://www.toymoban.com/news/detail-507236.html
下面来看一下程序,在程序里有相应的注释文章来源地址https://www.toymoban.com/news/detail-507236.html
#include<reg52.h> //定义头文件
#define uchar unsigned char //定义两个数据类型
#define uint unsigned int
uchar old1=0,old2=1,old3=2,old4=3,old5=4,old6=5; //原始密码,可以任意设置0~9
uchar new1,new2,new3,new4,new5,new6; //定义new,是每次按键按下的数值
uchar a=16,b=16,c=16,d=16,e=16,f=16; //送入数码管显示的变量
uchar wei,key,temp; //定义三个变量,在后面引用
bit allow,genggai,ok,wanbi,retry,close; //定义六个非零即一的状态位
sbit dula=P2^6; //定义段选端口
sbit wela=P2^7; //定义位选端口
sbit beep=P2^3; //定义蜂鸣器端口
unsigned char code table[]= //声明段选数据
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};
void delay(unsigned char i) //定义延时函数,以便后面直接引用
{
uchar j,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f) //数码管显示函数,对数码管进行赋值
{
dula=0;
P0=table[a];
dula=1;
dula=0;
wela=0;
P0=0xfe;
wela=1;
wela=0;
delay(5);
P0=table[b];
dula=1;
dula=0;
P0=0xfd;
wela=1;
wela=0;
delay(5);
P0=table[c];
dula=1;
dula=0;
P0=0xfb;
wela=1;
wela=0;
delay(5);
P0=table[d];
dula=1;
dula=0;
P0=0xf7;
wela=1;
wela=0;
delay(5);
P0=table[e];
dula=1;
dula=0;
P0=0xef;
wela=1;
wela=0;
delay(5);
P0=table[f];
dula=1;
dula=0;
P0=0xdf;
wela=1;
wela=0;
delay(5);
}
void keyscan() //矩阵键盘扫描函数
{
{
P3=0xfe; //对第一行赋0,即低电平
temp=P3; //定义P3口即矩阵口为temp
temp=temp&0xf0; //将temp和0xf0进行“与”运算后再次赋予temp
if(temp!=0xf0) /*如果temp不等于0xf0时,说明第一行有按键被按下,
下面的检测第一行哪一个被按下的检测函数*/
{
delay(10); //按键消抖
if(temp!=0xf0) //再次检测,确保第一行确实有被摁下的按键
{
temp=P3; //将P3口的状态赋值给temp
switch(temp) //把temp和下面case后的数值进行比较,如果相同执行相应操作
{
case 0xee: //如果temp=0xee,那么
key=0; //那木key=0,
wei++; //wei加一
break; //退出,再次扫描
case 0xde:
key=1;
wei++;
break;
case 0xbe:
key=2; //同上
wei++;
break;
case 0x7e:
key=3;
wei++;
break;
}
while(temp!=0xf0) //松手检测,只有当temp不等于0xf0时进入,持续扫描
{
temp=P3;
temp=temp&0xf0;
beep=0; //在不松手时蜂鸣器响起
}
beep=1; //松手后蜂鸣器关闭
}
}
P3=0xfd; //对矩阵扫描第二行,方法同第一行
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:
key=4;
wei++;
break;
case 0xdd:
key=5;
wei++;
break;
case 0xbd:
key=6;
wei++;
break;
case 0x7d:
key=7;
wei++;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
beep=0;
}
beep=1;
}
}
P3=0xfb; //对矩阵扫描第三行,方法同第一行
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:
key=8;
wei++;
break;
case 0xdb:
key=9;
wei++;
break;
到现在为止0~9十个键已经扫描完成,接下来配置四个功能按键
case 0xbb: //如果第三行第3个键被按下,
genggai=1; //genggai=1
wei=0; //将wei归零
break;
case 0x7b: //如果第三行第四个键被按下
if(allow) //并且allow等于1时
ok=1; //将ok=1
break;
}
while(temp!=0xf0) //松手检测
{
temp=P3;
temp=temp&0xf0;
beep=0;
}
beep=1;
}
}
P3=0xf7; //对第四行进行扫描
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7: //如果第四行第一个按键被按下
retry=1; //那木retry=1
break;
case 0xd7: //如果第四行第二个按键被按下,
close=1; //那么close=1
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
beep=0;
}
beep=1;
}
}
}
}
void shumima() //对按键采集来的数据进行分配
{ //这个子函数分析密码是否输入完成,并且让数码管逐渐亮起来
if(!wanbi) //如果wanbi不等于一,进入这个if循环
{
switch(wei) //将wei和下面的数值比较,完成相应程序
{
case 1:new1=key; //如果等于一,将key赋值new1,即刚刚按下的值,
if(!allow) a=17; //如果密码没有输入完成且正确,那么将a赋值17
else a=key; break; //如果没有完成上面的操作,那木让a=key,这一步是改密码的操作
case 2:new2=key; //同上
if(a==17) b=17;
else b=key; break;
case 3:new3=key;
if(a==17) c=17;
else c=key; break;
case 4:new4=key;
if(a==17) d=17;
else d=key; break;
case 5:new5=key;
if(a==17) e=17;
else e=key; break;
case 6:new6=key;
if(a==17) f=17;
else f=key;
wanbi=1; break; //完成后wanbi=1,所以可以跳出这个while循环
}
}
}
void yanzheng() //验证密码是否正确
{
if(wanbi) //只有当六位密码均输入完毕后方进行验证
{
if((new1==old1)&(new2==old2)&(new3==old3)&(new4==old4)&(new5==old5)&(new6==old6))
allow=1; //当上面全部成立,证明输入的密码正确,会得到allowe=1
}
}
void main() //主函数
{
while(1) //大循环
{
keyscan(); //不停的扫描矩阵键盘
shumima(); //数码管显示子函数
yanzheng(); //验证密码是否输入正确
if(allow) //验证完后,若allow为1,则开锁
{
P1=0x00; //开锁后的指令,让所有led都亮起来
if(!genggai) //如果没有按下更改键,wanbi会被置0
wanbi=0;
}
if(genggai) //当更改密码键被按下,genggai会被置一
{
if(allow) //判断密码锁是否打开,如果打开,才有更改密码的权限
{
while(!wanbi) //当新的六位密码没有设定完,则一直在这里循环
{
keyscan(); //持续扫描
shumima();
if(retry|close) //当检测到retry或close任意一个被按下,那木会让wanbi=1,即跳出数码管显示子函数
{ wanbi=1;
break;
}
display(a,b,c,d,e,f); //更改密码时数码管显示要更改的密码
}
}
}
if(ok) ///更改完成后,按下ok,结束并保存
{ //其他时间按下此键无效
ok=0; wei=0;
genggai=0;
old1=new1;old2=new2;old3=new3; //此时,旧的密码将被代替
old4=new4;old5=new5;old6=new6;
a=16;b=16;c=16;d=16;e=16;f=16;
}
if(retry) //当retry被按下,相当于重新输入密码,无论是在改密码还是输密码时
{
retry=0; wei=0;wanbi=0;
a=16;b=16;c=16;d=16;e=16;f=16;
new1=0;new2=0;new3=0;new4=0;new5=0;new6=0;
}
if(close) //当close被摁下时,所有密码清零
{
close=0;genggai=0;//所有变量均被清零。
wei=0; wanbi=0;
allow=0;
P1=0xff;
a=16;b=16;c=16;d=16;e=16;f=16;
new1=0;new2=0;new3=0;new4=0;new5=0;new6=0;
}
display(a,b,c,d,e,f); //实时显示
}
}
到了这里,关于基于51单片机的简易6位密码锁(数码管 led 矩阵)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!