要求:用单片机实现一个电子密码锁的功能,一开始设置密码,设置从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); } } }