天天看点

基于单片机的电子密码锁的实现

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

            shuru[i]='1';

            shuruz[i]=1;

            delay(20000);

        case 0xbe://2

            shuru[i]='2';

            shuruz[i]=2;

        case 0x7e://3

            shuru[i]='3';

            shuruz[i]=3;

        case 0xed://4

            shuru[i]='4';

            shuruz[i]=4;

        case 0xdd://5

            shuru[i]='5';

            shuruz[i]=5;

        case 0xbd://6

            shuru[i]='6';

            shuruz[i]=6;

        case 0x7d://7

            shuru[i]='7';

            shuruz[i]=7;

        case 0xeb://8

            shuru[i]='8';

            shuruz[i]=8;

        case 0xdb://9

            shuru[i]='9';

            shuruz[i]=9;

        case 0xbb://a

            shuru[i]='a';

            shuruz[i]=10;

        case 0x7b://b

            shuru[i]='b';

            shuruz[i]=11;

        case 0xe7://c

            shuru[i]='c';

            shuruz[i]=12;

        case 0xd7://d

            shuru[i]='d';

            shuruz[i]=13;

        case 0xb7://e

            shuru[i]='e';

            shuruz[i]=14;

        case 0x77://f

            shuru[i]='f';

            shuruz[i]=15;

            break; //密码都是以f结尾的

 //蜂鸣器响

 void beep(uint t)

     time=0;

      for(time;time<t;time++)

   {

           P30=1;

        delay(100);

        P30=0;

   }

//密码输入错误报警

void cuowubaojin()

     uint k=3;

    uint i;

    while(k--)

        i=50;

        while(i--)

        P30=1;

        delay(200);

            delay(400);

  //检查密码成功电机转动

 void chenggongzhuandong()

    //j=0;

    while(1)

      kaiguan=1;//打开电机

      inputBuf(kaiguanz);  //监听键盘

      if(key==0xb7)

      {

           kaiguan=0;//关闭电动机

        delay(10);

        P2=0xff;//关闭数码管显示

        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;//从头开始输入

    //密码验证,错误不能超过三次

         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)

    if(ff==1)

         chenggongzhuandong();  //电动机转动

    j=0;    //密码输入错误暂停使用

    if(ff==0)

        for(j;j<250;j++)

             delay(1000);

    }    

继续阅读