要求:用单片机实现一个电子密码锁的功能,一开始设置密码,设置从0-f,任意多少位密码(只要不超过十位),设置成功,蜂鸣器响一下;接着是验证密码,如果输入错误三次,则暂停一段时间,不允许使用,如果输入成功(F键确认),则密码解锁,步进电机转动,如果按下E键,则停止转动。
连线:P0键盘,P2倒着接数码管,P3.0接蜂鸣器,P1接步进电机
/*****************************键盘码的顺序**********************************/
/* 0xee,0xde,0xbe,0x7e 0-3 */
/* 0xed,0xdd,0xbd,0x7d 4-7 */
/* 0xeb,0xdb,0xbb,0x7b 8-b */
/* 0xe7,0xd7,0xb7,0x77 c-f */
/* 密码输入0-d;e,f 作为保留,f暂时用作确认 */
/* 连线:P0接键盘, P2接数码管(p2.7接H) */
/*************************************************************************/
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit P30=P3^0;
uint a;
uint fre;//控制频率
uint flag;
uint time=0; //控制中断时间
uchar count=0;//控制多少秒
uint t;
uint ff=0; //判断是否验证成功
uint fff=3;//判断用户输入次数
uint kaiguan=0;//判断电机是否开关的
/***********************步进电机****************************/
void delay(unsigned int t);
unsigned char code RUN[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9}; //步进电机相序表
//步进电机驱动
void motor_ffw()
{
if(kaiguan==1)
{
unsigned char i;
for (i=0; i<8; i++) //一个周期转3.75*8=30度
{
P1 = RUN[i]&0x1f; //取数据
delay(15); //调节转速
}
}
}
/***********************************************************/
//八段管显示码
code unsigned char LEDMAP[]={
~0x3f, ~0x06, ~0x5b, ~0x4f, ~0x66, ~0x6d, ~0x7d, ~0x07,
~0x7f, ~0x6f, ~0x77, ~0x7c, ~0x39, ~0x5e, ~0x79, ~0x71
};
uchar key;//键盘返回的一个码
uint i=0;//i用作数组循环
//存放初始密码
unsigned char mima[10]={0};
//存放缓冲密码
unsigned char shuru[10];
//存放×××数组
uint shuruz[10];
uint kaiguanz[10];//保存开关的
//延时函数
void delay(uint i)//延时函数
{
uint j=0;
while(i--)
{
for (j;j<100;j++){}
}
}
//键盘扫描
uchar keyscan()//键盘扫描函数,返回一个键盘码
{
uchar cord_h,cord_l;//行列值
P0=0x0f; //行线输出全为0
cord_h=P0&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下
{
delay(100); //去抖
cord_h=P0&0x0f; //读入列线值
if(cord_h!=0x0f)
{
P0=cord_h|0xf0; //输出当前列线值
cord_l=P0&0xf0; //读入行线值
return(cord_h+cord_l);//键盘最后组合码值
}
}return(0xff); //返回该值
}
//将键盘码转化成0-f存放到缓冲区数组中
void inputBuf(uchar shuru[10])
{
key=keyscan();//调用一次扫描键盘函数,获取返回的一个键码
delay(500); //延时去抖动
switch(key)
{
case 0xee://0
{
i=i%10;
shuru[i]='0';
shuruz[i]=0;
P2=LEDMAP[shuruz[i]];
delay(30000);
i++;
break;
}
case 0xde://1
{
i=i%10;
shuru[i]='1';
shuruz[i]=1;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break;
}
case 0xbe://2
{
i=i%10;
shuru[i]='2';
shuruz[i]=2;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break;
}
case 0x7e://3
{
i=i%10;
shuru[i]='3';
shuruz[i]=3;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break;
}
case 0xed://4
{
i=i%10;
shuru[i]='4';
shuruz[i]=4;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break;
}
case 0xdd://5
{
i=i%10;
shuru[i]='5';
shuruz[i]=5;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break;
}
case 0xbd://6
{
i=i%10;
shuru[i]='6';
shuruz[i]=6;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break;
}
case 0x7d://7
{
i=i%10;
shuru[i]='7';
shuruz[i]=7;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break;
}
case 0xeb://8
{
i=i%10;
shuru[i]='8';
shuruz[i]=8;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break;
}
case 0xdb://9
{
i=i%10;
shuru[i]='9';
shuruz[i]=9;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break;
}
case 0xbb://a
{
i=i%10;
shuru[i]='a';
shuruz[i]=10;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break;
}
case 0x7b://b
{
i=i%10;
shuru[i]='b';
shuruz[i]=11;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break;
}
case 0xe7://c
{
i=i%10;
shuru[i]='c';
shuruz[i]=12;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break;
}
case 0xd7://d
{
i=i%10;
shuru[i]='d';
shuruz[i]=13;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break;
}
case 0xb7://e
{
i=i%10;
shuru[i]='e';
shuruz[i]=14;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break;
}
case 0x77://f
{
i=i%10;
shuru[i]='f';
shuruz[i]=15;
P2=LEDMAP[shuruz[i]];
delay(20000);
i++;
break; //密码都是以f结尾的
}
}
}
//蜂鸣器响
void beep(uint t)
{
time=0;
for(time;time<t;time++)
{
P30=1;
delay(100);
P30=0;
delay(100);
}
}
//密码输入错误报警
void cuowubaojin()
{
uint k=3;
uint i;
while(k--)
{
i=50;
while(i--)
{
P30=1;
delay(200);
P30=0;
delay(200);
}
i=50;
while(i--)
delay(400);
}
}
//检查密码成功电机转动
void chenggongzhuandong()
{
//j=0;
while(1)
{
kaiguan=1;//打开电机
inputBuf(kaiguanz); //监听键盘
if(key==0xb7)
{
kaiguan=0;//关闭电动机
delay(10);
P2=0xff;//关闭数码管显示
delay(10);
break;
}
motor_ffw(); //调用旋转处理函数
delay(20);
}
}
//主函数
void main()
{
uint j=0,n=3; //i用于输入密码的次数
P2=0xff;
///////////设置密码,保存在mima[10]数组中/////////////////////////////////////////
while (1)
{
inputBuf(mima);
if(key==0x77)
{
P2=0xff;
break;
}
}
//设置成功蜂鸣器响一下
j=0;
for(j;j<5;j++)
{
beep(8);
}
////////////验证密码,保存在shuru[10]中/////////////////////////////////////////////
i=0;//从头开始输入
//密码验证,错误不能超过三次
while(1)
{
inputBuf(shuru);
if(key==0x77&&n>0) //fff判断输入密码的次数
{
P2=0xff;//关闭数码管
j=0;
ff=1; //ff判断是否验证成功
//比较mima[]和shuru[],如果不对,则继续比较
for(j;j<10;j++)
{
if(mima[j]!=shuru[j])
{
ff=0;
cuowubaojin();//失败蜂鸣器响
i=0;//从头开始输入到数组里
break;
}
}
if(j==10)
{
ff=1;//将标志位设为true;
n=1;
}
n--;
}
if(n==0)
{
break;
}
}
if(ff==1)
{
chenggongzhuandong(); //电动机转动
}
P2=0xff;
j=0; //密码输入错误暂停使用
if(ff==0)
{
for(j;j<250;j++)
{
delay(1000);
}
}
}