为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

电子密码锁

2011-02-27 16页 pdf 759KB 190阅读

用户头像

is_281461

暂无简介

举报
电子密码锁 电子密码锁的设计 一、 系统方案 本系统由单片机系统、矩阵键盘和报警系统组成。系统能完成开锁、修改用户密码和报 警三种基本的密码锁的功能。         AT89C51  键盘电路  图 1 系统框图 二、 系统基本原理 使用者输入 6 位密码后按下 Enter 键,单片机将输入数据与密码逐个比较,如果输入的 6 位密码与设定的密码一致,绿灯(开锁模拟灯)亮。若输入的 6 位密码与设定密码不同, 则按下 Enter 键后,红灯亮且刚...
电子密码锁
电子密码锁的设计 一、 系统 本系统由单片机系统、矩阵键盘和报警系统组成。系统能完成开锁、修改用户密码和报 警三种基本的密码锁的功能。         AT89C51  键盘电路  图 1 系统框图 二、 系统基本原理 使用者输入 6 位密码后按下 Enter 键,单片机将输入数据与密码逐个比较,如果输入的 6 位密码与设定的密码一致,绿灯(开锁模拟灯)亮。若输入的 6 位密码与设定密码不同, 则按下 Enter 键后,红灯亮且刚才输入数据被清除,等待下次输入。当密码错误次数超过三 次时蜂鸣器发出警报,且键盘被锁定。按下 SET 键,黄灯亮,此时可开始进行密码重置。 三、 电路功能单元设计 1、键盘输入电路 图 2 键盘电路 时钟电路  警报系统  模拟灯  复位电路  键盘是最常用的单片机输入设备,大致可以分为独立连接式键盘和矩阵式。  独立连接式键盘是最简单的键盘电路,每个键独立接入一根数据线。这种键盘结构简单, 使用方便,但是占用的 I/O 口线较多。矩阵式键盘由行线和列线组成,按键位于行列的交叉 点上,行线通过上拉电阻接到高电平。行列式键盘可节省 I/O 口,适合按键数较多的场合。 所以本例的 4X4 键盘采用行列式键盘。   通过行列键盘扫描的方法可获取键盘输入的键值,从而知道按下的是哪个键,具体过 程如下: (1) 查询是否键按下。单片机向行扫描口输出全为“0”的扫描码,然后检测列线 信号,只要有一列信号不为“1”,则表示有键按下,且不为“1”的列即是按 下的键的所在列。 。 (2) 查询按下键所在具体位置。用逐行扫描的方法确定按下键所在的行号。单片机 先使第一行为“0”,其余行为“1”,接着进行信号检测,若全为“1”则按下 键不再第一行;然后是第二行为“0”,其余行为“1”,在进行列信号检测,若 全为“1”,则按下键不再第二行;往下依次类推 (3) 将得到的行号列号译码。本例中,将直接的高 4 为表示列号,低 4 位表示行号。 2、警报电路 图 3 LM386 LM386 是一种音频集成功放,具有自身功耗低、电压增益可调整、电源电压范围大、外 接元件少和总谐波失真小等优点,广泛应用于录音机和收音机之中。  LM386 的外形和引脚的排列如图 3所示。引脚 2 为反相输入端,3 为同相输入端;引脚 5 为输出端;引脚 6 和 4分别为电源和地;引脚 1 和 8 为电压增益设定端;使用时在引脚 7 和地之间接旁路电容,通常取 10μF。LM386 的电源电压 4‐12V或 5‐18V(LM386N‐4);静态消 耗电流为 4mA;电压增益为 20‐200dB;在 1、8 脚开路时,带宽为 300KHz;输入阻抗为 50K; 音频功率 0.5W。  下图为音频放大电路。单片机输出的信号经 LM386 放大后,驱动扬声器以发出警报。 图 4 音频放大电路 3、 单片机最小系统 单片机最小系统由单片机、时钟电路和复位电路组成。 复位电路:当单片机系统在运行中,受到环境干扰出现程序跑飞的时候,按下复位按钮 内部的程序自动从头开始执行。 时钟电路:对系统提供 12MHZ 的时钟。   图 5    单片机最小系统    四、 软件设计                                                            图 6      键盘扫描流程图  键盘扫描函数:  uchar keyscan(void)  {    uchar scancode,tmpcode;    P1 = 0xf0;                            //  发全 0 行扫描码    if ((P1&0xf0)!=0xf0)          //  若有键按下    {        delay(700);                                //  延时去抖动            if ((P1&0xf0)!=0xf0)        //  延时后再判断一次,去除抖动影响            {                scancode = 0xfe;                    //扫描第一行                while((scancode&0x10)!=0)    //  逐行扫描  返回特征码  Yes  P1=0xf0  有键按下? 延时  No  有键按下? 返回 0  Yes No  Yes P1=0xfe  本行有键按下?  No  P1 左移 1 位  No  行扫描结束 Yes                {                    P1 = scancode;              //  输出行扫描码                    if ((P1&0xf0)!=0xf0)    //  若本行有键按下                    {                        tmpcode = (P1&0xf0)|0x0f;                        return((~scancode)+(~tmpcode)); //返回特征字节码,为 1 的位即对应的行和列                    }                    else scancode = (scancode<<1)|0x01;    //  行扫描码左移一位                }          }      }    return(0);                //  无键按下,返回值为 0      }                                                            图 7      整体程序流程图    N  未过 3 次 过 3 次  开始  系统初始化  输入密码  蜂鸣器警报  红灯亮判断密码?  输入次数  Y  N  Y N 绿灯亮  重置密码?  设置结束? 设置密码  结束  Y    五、 软件仿真 此次设计使用 Keil C 软件进行调试。 调试软件介绍:Keil C51 是美国 Keil Software 公司出品的 51 系列兼容单片机 C 语言 软件开发系统。Keil C51 软件提供丰富的库函数和功能强大的集成开发调试工具,全 Windows 界面。另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到 Keil C51 生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。在 开发大型软件时更能体现高级语言的优势。 程序调试界面如下图所示:   调试步骤: 1) 打开 Keil C 软件,Project->New uVision Project,新建。File->New, 新建并添加源程序文件,保存时使用扩展名.c。 2) 在 Project Workspace 中,左击 Source Group 1,选择 Add Files to Group ‘Source Group 1‘,然后选择相应源文件。 3) 参数设置。选中项目文件,右击“Target 1”,在弹出的菜单中进行有关的参 数设置。 4) 编译。单击 Project 菜单下的 Build Target 或 Rebuild all target files 菜单,对源文件进行编译。当源文件有语法错误时,输出窗口会有提示。 5) 仿真调试。单击 Debug 菜单下的 Start/Stop Debug Session 子菜单,单击 Peripherals 可打开单片机的 I/O 端口、定时器及中断等功能部件。单击 View 菜单下 的子菜单,可打开反汇编、存储器、堆栈、代码等窗口,进行有关数据的观察。   六、 参考文献  1、 《单片机 C语言轻松入门》    周坚    北航出版社  2、 《51 单片机 C语言应用程序设计实例精讲》    戴佳  戴卫恒  电子工业出版社  3、 《8051 单片机实践与应用》  吴金戎  沈庆国  郭庭吉  清华大学出版社  4、 《单片机实验与实践教程》  万光毅  严义  邢春香  北航出版社  5、 《单片机原理及应用技术》  范力昱  电子工业出版社                                                            七、 附录  附录 A:                  附录 B:程序清单  #include   #include   #include     #include               //头文件    #define uchar unsigned char  #define uint unsigned int              //宏定义    uchar count;          //  密码位计数  uchar errorcount;      //密码错误次数  uchar pw[6];          //  初始密码存储区  uchar pwbuf[6];          //  输入密码存储区  uchar STH0;  uchar STL0;    bit enterflag;          //  确认键按下与否标志  bit pwflag;            //  密码正确与否标志  uchar old;                  //在密码重置时,是否已经输入过旧密码,old=1 则已输入过旧密码  sbit P2_0=P2^0;  sbit yellow=P2^3;      //黄灯亮,提示旧密码已输入正确,开始重置密码  sbit green=P2^2;  sbit red=P2^1;    /*延时函数*/  void delay(uint i)  {      while(‐‐i);  }    /*清除函数*/  void clear()  {      int j;      for(j=0;j<6;j++)          pwbuf[j]=0;  }      /*键盘扫描函数*/  uchar keyscan(void)  {    uchar scancode,tmpcode;    P1 = 0xf0;                            //  发全 0 行扫描码    if ((P1&0xf0)!=0xf0)          //  若有键按下    {        delay(700);                                //  延时去抖动            if ((P1&0xf0)!=0xf0)        //  延时后再判断一次,去除抖动影响            {                scancode = 0xfe;                    //扫描第一行                while((scancode&0x10)!=0)    //  逐行扫描                {                    P1 = scancode;              //  输出行扫描码                    if ((P1&0xf0)!=0xf0)    //  若本行有键按下                    {                        tmpcode = (P1&0xf0)|0x0f;                        return((~scancode)+(~tmpcode)); //返回特征字节码,为 1 的位即对应的行和列                    }                    else scancode = (scancode<<1)|0x01;    //  行扫描码左移一位                }          }      }    return(0);                //  无键按下,返回值为 0      }      /*  密码比较函数  */  bit pwcmp(void)  {        bit flag;        //flag密码是否正确的标志位        uchar i;        for (i=0;i<6;i++)        {              if (pw[i]==pwbuf[i])    flag = 1;              else                  {                      flag = 0;                      i = 6;                  }        }        return(flag);      //flag=1 时,密码相    }      /*定时器 0中断服务子程序*/  void time0_int(void) interrupt 1 using 0    //定时器 0 中断,在该终端程序中使用第 1 组寄存器  {      TH0=STH0;      TL0=STL0;      P2_0=~P2_0;  }      /*主程序*/    void main()  {      uchar n,m,k,key;      count=0;                //初始未输入密码,密码位数计数器置 0      enterflag=0;          //未按下确认键      pwflag=0;                  //密码正确标志置 0      green=0;              //绿灯不亮      red=0;                  //红灯不亮      yellow=0;            //黄灯不亮        old=0;        TMOD=0x01;          //设置工作方式      ET0=1;      EA=1;        /*假定内置密码 123456*/  pw[0]=1;  pw[1]=2;  pw[2]=3;  pw[3]=4;  pw[4]=5;  pw[5]=6;    while(errorcount<3)  {      key=keyscan();        //调用键盘扫描函数      switch(key)      {          case 0x11: if(count<6)          //1 行 1 列,数字 1                                {                                    pwbuf[count]=1;                                    count++;                                }                                break;          case 0x21: if(count<6)        //1行 2列,数字 2                                {                                    pwbuf[count]=2;                                    count++;                                }                                  break;          case 0x41: if(count<6)        //1行 3列,数字 3                                {                                    pwbuf[count]=3;                                    count++;                                }                            break;          case 0x12: if(count<6)        //2行 1列,数字 4                                {                                        pwbuf[count]=4;                                    count++;                                  }                                  break;          case 0x22: if(count<6)        //2行 2列,数字 5                                {                                    pwbuf[count]=5;                                    count++;                                }                                break;          case 0x42: if(count<6)        //2行 3列,数字 6                                {                                    pwbuf[count]=6;                                    count++;                                }                                break;          case 0x14: if(count<6)        //3行 1列,数字 7                                {                                    pwbuf[count]=7;                                    count++;                                }                                break;          case 0x24: if(count<6)        //3行 2列,数字 8                                {                                    pwbuf[count]=8;                                    count++;                                }                                break;          case 0x44: if(count<6)        //3行 3列,数字 9                                {                                      pwbuf[count]=9;                                    count++;                                }                                break;          case 0x18: if(count<6)        //4行 1列,数字 0                                {                                    pwbuf[count]=0;                                    count++;                                }                                break;          case 0x28: enterflag=1;        //4 行 2列,enter键                                if(count==6)                                {                                    if(yellow==0)    //黄灯不亮                                        pwflag=pwcmp();                                    else                          //黄灯亮,重置密码                                        {if(old==1)          //已输入过旧密码                                            {for(k=0;k<6;k++)                                                  pw[k]=pwbuf[k];                                                  yellow=0;                      green=0;                                                  old=0;}                                          else                                              {pwflag=pwcmp();                                                old=1;}                                          }                                  }                                  else                                    pwflag=0;                                  break;          case 0x48: count=0;                  //4行 3 列,清除键按下                                  clear();          //用 0清除已输入的密码                                  break;          case 0x81:          case 0x82:          case 0x84:          case 0x88:    count=0;          //密码重置键被按下                                  yellow=1;        //黄灯亮,提示开始进行密码重置                                  break;          default:break;      }      if(enterflag==1)      //按下确认键          {              enterflag=0;        //标志位清零              count=0;              //计数位清零              if(pwflag==1)                  {green=1;          //绿灯亮                    if(yellow==1)    //之前按下重置密码                      {                        clear();          //清除之前输入的数据                        for(m=0;m<6;m++)                          pw[m]=0;        //清除旧密码,等待数入新密码                      }                    else                          old=1;                    errorcount=0;            }              else                  { if(errorcount<3)                      {                        errorcount=errorcount+1;    //密码错误次数加 1                        red=1;              //红灯亮                        clear();              //清除输入数据,等待下次输入                        }                      else                      {                          red=1;                          P2_0=~P2_0;      //蜂鸣器发出警报(警报时间)                          STH0=64820/256;                                STL0=64820%256;      //赋计数初值                          TR0=1;                //开始计数                          for(n=0;n<50;n++)                              delay(60000);                          TR0=0;          //关闭                      }                }                }      }  } 
/
本文档为【电子密码锁】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索