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