• 设计采用AT89S52单片机作为核心控制单元,配以相应的硬件电路,完成开锁密码的设置、存储、校对、提醒和报警功能。
  • 硬件结构

  • 整体电路

  • 软件结构

  • 液晶驱动12864.c
  1 /*  ****************************************************
  2                     程序参考地址
  3       http://blog.chinaunix.net/uid-21658993-id-1819849.html
  4                       图片显示
  5        http://www.51hei.com/mcu/4161.html
  6 ********************************************************/
  7 #ifndef _12864_H_
  8 #define _12864_H_
  9 #define LCD_DATA P0
 10 sbit RS = P2^4;         //并行的指令/数据选择信号: 1数据, 0命令
 11 sbit RW = P2^5;         //并行读写选择信号:1读, 0写
 12 sbit E = P2^6;          //并行使能端:1有效
 13 sbit PSB = P2^1;        //并/串接口选择:1并,0串
 14 sbit RET = P2^3;        //复位:0有效
 15
 16 bit checkBusy()
 17 {   bit busy;
 18     RS = 0;
 19     RW = 1;
 20     E = 1;
 21     delayUs();
 22     busy = (bit)(LCD_DATA&0x80);
 23     E = 0;
 24     return busy;
 25 }
 26 void wait()
 27 {
 28     while(checkBusy());
 29 }
 30 void writeCmd(uchar cmd)
 31 {
 32     wait();
 33     RS = 0;
 34     RW = 0;
 35     E = 0;
 36     delayUs();
 37     LCD_DATA = cmd;
 38     delayUs();
 39     E = 1;
 40     delayUs();
 41     E = 0;
 42 }
 43 void writeData(uchar dat)
 44 {
 45     wait();
 46     RS = 1;
 47     RW = 0;
 48     E = 0;
 49     delayUs();
 50     LCD_DATA = dat;
 51     delayUs();
 52     E = 1;
 53     delayUs();
 54     E = 0;
 55 }
 56
 57 void setPosition(uchar x, uchar y)             //4*8
 58 {   uchar p;
 59     switch(x%4)
 60     {
 61         case 0: p = 0x80; break; //第0行
 62         case 1: p = 0x90; break; //第1行
 63         case 2: p = 0x88; break; //第2行
 64         case 3: p = 0x98; break; //第3行
 65     }
 66     p += y;
 67     writeCmd(p);
 68 }
 69 void lcd_mesg(uchar * str)
 70 {   uchar n = 0;
 71     while(str[n] != '\0')
 72     {
 73         writeData(str[n++]);
 74     }
 75 }
 76 void lcd_draw(unsigned char code *pic)
 77 {
 78     unsigned i,j,k;
 79     writeCmd(0x34);//扩充指令集
 80     for(i=0;i<2;i++)//上半屏和下半屏
 81     {
 82         for(j=0;j<32;j++)//上下半屏各32行
 83         {
 84             writeCmd(0x80+j);//写行地址(y地址)
 85             if(i==0)
 86             {
 87                 writeCmd(0x80);//写列地址(x地址),上半屏列地址为0x80,下半屏列地址为0x88
 88             }
 89             else
 90             {
 91                 writeCmd(0x88);
 92             }
 93             for(k=0;k<16;k++)//写入列数据
 94             {
 95                 writeData(*pic++);
 96             }
 97         }
 98     }
 99     writeCmd(0x36);//显示图形
100     writeCmd(0x30);//基本指令集
101 }
102 void init_lcd()
103 {
104     PSB = 1;            //并口方式
105     writeCmd(0x30);     //基本指令, 扩充指令为34H
106     delayMs(10);
107     writeCmd(0x0c);     //显示开, 关光标
108     delayMs(10);
109     writeCmd(0x01);     //清屏
110     delayMs(10);
111 }
112
113 #endif

  • 存储驱动24c02.c
#ifndef _24C02_H_
#define _24C02_H_
uchar flag_lock;          //键盘锁定标识,1有效
uchar userpsw[6];
uchar adminpsw[6];
/*24C02读写驱程序*/
sbit scl=P1^1;
sbit sda=P1^2;
sbit  wp=P1^0;    //写保护//应答函数:在SCL保持高电平期间,拉低SDA,且保持4us以上,再拉高
void iic_ack()
{scl=0;        //默认初值为0scl=1;        //SCL保持高电平
    delay_5us();sda=1;        delay_5us();sda=0;delay_5us();scl=0;        //SCL结束保持高sda=1;        //SDA返回原值
}void iic_start()        //开始信号,上升沿
{sda=1;    //发送起始条件的数据信号scl=1;     //发送起始条件的时钟信号
    delay_5us(); sda=0;    //发送起始信号
    delay_5us(); scl=0;    //钳住IIC总线,准备发送或接收数据
    delay_5us();
}void iic_stop()         //结束信号,下降沿
{sda=0;    //发送结束条件的数据信号 scl=1;    //发送结束条件的时钟信号
    delay_5us(); sda=1;    //发送结束信号
    delay_5us();
}void writex(unsigned char x)  //写一个字节
{unsigned char i;for(i=0;i<8;i++)        //循环8次,由高到低赋给SDA
    {scl=0;                //允许更改SDAdelay_5us();        //存在边沿时间,需等5ussda=x&0x80;     //SDA = 数据和10000000按位与; 串口SDA只送最高位x=x<<1;delay_5us();scl=1;delay_5us();scl=0;        }
}unsigned char readx()   //读一个字节
{unsigned char i,value;    for(i=0;i<8;i++)    //8次读取1个字节
    {scl=0;delay_5us();scl=1;            //保持着SDA的值,以便读出从机数据
        delay_5us();if(sda==1){value=(value<<1)|1;    }if(sda==0){value=(value<<1)|0;    }delay_5us();}return value;
}
//向24C02的地址address中写入一个字节的数据info
void write_24c02(unsigned char address,unsigned char info)
{iic_start(); writex(0xae);       //24c02芯片地址为111,写方向位0:1010 1110
    iic_ack();writex(address);iic_ack(); writex(info);iic_ack(); iic_stop();
}
//从24C02的地址address中读取一个字节的数据
unsigned char read_24c02(unsigned char address)
{unsigned char value;iic_start(); writex(0xae);iic_ack();writex(address);iic_ack();iic_start();writex(0xaf);        //24c02芯片地址为111,读方向位1:1010 1111
    iic_ack();value=readx(); iic_stop();return(value);
}void initset_read()
{uchar tmp;flag_lock=read_24c02(20);       //读出键盘锁定标识并显示,地址20,出厂状态为0delay_ms(50);for(tmp=0;tmp<6;tmp++){adminpsw[tmp]=read_24c02(10+tmp);   }delay_ms(50); for(tmp=0;tmp<6;tmp++){userpsw[tmp]=read_24c02(tmp);}delay_ms(50);
}void init_24c02()  //总线初始化,拉高释放总线,并读出错误计数和密码
{wp=1;scl=1; delay_5us(); sda=1; delay_5us(); initset_read();                      //将外部存储器中的密码读入缓存区
}
#endif

  • 日历/时钟驱动ds1302.c
/*  ****************************************************                程序参考地址http://www.51hei.com/mcu/1730.html
********************************************************/
#ifndef _DS1302_H_
#define _DS1302_H_
sbit CLK=P3^6;        //DS1302引脚定义
sbit IO=P3^4;
sbit CE=P3^5;         //RST
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
extern uchar timer_cnt;
void Input_1byte(uchar TD)        //DS1302输入一字节数据
{uchar i;ACC=TD;for(i=8;i>0;i--){IO=ACC0;CLK=1;CLK=0;ACC=ACC>>1;}
}
uchar Output_1byte(void)       //DS1302输出一字节数据
{uchar i;for(i=8;i>0;i--){ACC=ACC>>1;ACC7=IO;CLK=1;CLK=0;}return(ACC);
}void Write_DS1302(uchar add,uchar dat)//向DS1302写
{CE=0;CLK=0;CE=1;Input_1byte(add);Input_1byte(dat);CE=0;
}uchar Read_DS1302(uchar add)    //从DS1302读
{uchar inf;      //信息临时存储变量CE=0;CLK=0;CE=1;Input_1byte(add);inf=Output_1byte();CE=0;return(inf);
}/**********************DS1302初始化*****************************/
void init_1302()
{if(Read_DS1302(0xd1)==0x55)               //判断内存单元的内容,是否进行初始化       return;      else {Write_DS1302(0x8e,0x00); //关闭写保护Write_DS1302(0x90,0x00); //电池充电设置Write_DS1302(0x80,0x00); //秒Write_DS1302(0x82,0x51); //分Write_DS1302(0x84,0x17); //时Write_DS1302(0x86,0x17); //日Write_DS1302(0x88,0x04); //月Write_DS1302(0x8c,0x16); //年Write_DS1302(0xd0,0x55); //写RAMWrite_DS1302(0x8e,0x80); //打开写保护
    }
}/*********************************************************
*                      DS1302显示                        *
**********************************************************/
void disp_ds1302()
{uchar min,min1,min2;uchar hour,hour1,hour2;uchar date,date1,date2;uchar mon,mon1,mon2;uchar year,year1,year2;
//******读出1302的日期******/min=Read_DS1302(0x83);      //读分:min1=十位,min2=个位min2=min&0x0f;    min1=min>>4;    hour=Read_DS1302(0x85);     //读时:hour1=十位,hour2=个位hour2=hour&0x0f;hour1=hour>>4;    date=Read_DS1302(0x87);     //读日期:date1=十位,date2=个位date2=date&0x0f;date1=date>>4;    mon=Read_DS1302(0x89);      //读月份:mon1=十位,mon2=个位mon2=mon&0x0f;mon1=mon>>4;year=Read_DS1302(0x8d);     //读年份:year1=十位,year2=个位year2=year&0x0f;    year1=year>>4;
//******显示1302的日期******/           setPosition(0,0);writeData(2+0x30);writeData(0+0x30);writeData(year1+0x30);          //年writeData(year2+0x30); writeData('-');                 //-writeData(mon1+0x30);           //月writeData(mon2+0x30);writeData('-');                 //-writeData(date1+0x30);          //日writeData(date2+0x30);writeData(' ');                 //空格writeData(hour1+0x30);          //时writeData(hour2+0x30); if(timer_cnt<18)   writeData(':'); else    writeData(' ');writeData(min1+0x30);           //分writeData(min2+0x30);
}#endif

  • 键盘扫描keyscan.c
#ifndef _KEYSCAN_H_
#define _KEYSCAN_H_
#define keyport P3
uchar key=0; //按键值
/*------------------------------------------------
按键扫描函数,返回扫描键值
------------------------------------------------*/
unsigned char key_scan(void)//键盘扫描函数,使用行列反转扫描法
{uchar cord_h,cord_l;            //行列值中间变量keyport=0xf0;                   //行线输出全为0,P3=1111 0000cord_h=keyport&0xf0;            //读入列线值if(cord_h!=0xf0)                //有键按下
    {delay_ms(5);                //去抖if(cord_h!=0xf0){cord_h=keyport&0xf0;    //读入列线值keyport=cord_h|0x0f;    //输出当前列线值delay_ms(5);cord_l=keyport&0x0f;    //读入行线值while((keyport&0x0f)!=0x0f);//等待松开并输出return(cord_h+cord_l);  //键盘最后组合码值
        }}return(0xff);                   //返回"无键按下",键盘不起作用
}/*------------------------------------------------
键值处理函数,返回扫键值
------------------------------------------------*/
unsigned char key_value(void) //按下相应的键显示相对应的码值
{switch(key_scan()){case 0xee:return  0;break;      //0    1110 1110case 0xde:return  1;break;      //1case 0xbe:return  2;break;      //2case 0x7e:return  3;break;      //3case 0xed:return  4;break;      //4case 0xdd:return  5;break;      //5case 0xbd:return  6;break;      //6case 0x7d:return  7;break;      //7case 0xeb:return  8;break;      //8case 0xdb:return  9;break;      //9case 0xbb:return 10;break;      //a    * 键case 0x7b:return 11;break;      //b    # 键case 0xe7:return 12;break;      //c  管理/退出键case 0xd7:return 13;break;      //d  删除键case 0xb7:return 14;break;      //e  清空键case 0x77:return 15;break;      //f  确认键default:return 0xff;break;}
}#endif

  • 软件仿真

转载于:https://www.cnblogs.com/Afterwork/p/5899344.html

【51项目】电子密码锁设计相关推荐

  1. 11-基于单片机的电子密码锁设计(原理图+仿真工程+答辩论文+答辩PPT)

    11-基于单片机的电子密码锁设计(原理图+仿真工程+答辩论文+答辩PPT) 文章目录 11-基于单片机的电子密码锁设计(原理图+仿真工程+答辩论文+答辩PPT) 资料 任务书 设计说明书 摘要 设计框 ...

  2. 【设计方案分享】基于单片机温度监测监控报警系统设计-基于单片机钞票自动智能识别系统设计-基于单片机乒乓球游戏机控制系统设计-基于单片机温度监测监控报警系统设计-基于单片机矩阵键盘的电子密码锁设计

    820基于单片机温度监测监控报警系统设计-设计资料 温度监测器功能描述: 1.主控芯片用的是51单片机(STC89C51). 2.使用温度传感器DS18b20采集温度. 3.用1602液晶显示显示温度 ...

  3. 基于单片机乒乓球游戏机控制系统设计-基于单片机矩阵键盘的电子密码锁设计-基于单片机温度监测监控报警系统设计-基于单片机钞票自动智能识别系统设计-设计资料【转发分享】

    819基于单片机乒乓球游戏机控制系统设计-设计资料下载 乒乓球游戏机设计任务为: (1)使用乒乓游戏机的甲乙双方各在不同的位置发球或击球. (2)乒乓球的位置和移动方向由灯亮及依次点燃的方向决定,球移 ...

  4. 基于stm32的c语言程序设计,基于stm32的电子密码锁设计 main.c 代码奉上,做课设的直接用...

    电子密码锁设计 **功能:支持3~20位的密码设置,初始密码为123456:若要重设密码,需先输入正确密码开锁. ** 正常显示情况下,按下确认键上锁:按下密码键,开始输入密码. **接线:PE[0. ...

  5. 51单片机——电子密码锁

    51单片机--电子密码锁 链接: link. 图片: !protues仿真 ,下面展示同样高亮的 代码片. #include<reg51.h> unsigned char zt=1; un ...

  6. 基于51单片机的带记忆功能的电子密码锁设计

    设计要求: 1.利用51系列单片机为核心,矩阵键盘与LCD1602液晶显示屏组成硬件系统,设计一款电子密码锁: 2.该密码锁具有设置.修改六位用户密码.超次报警.超次锁定.密码错误报警等功能: 3.通 ...

  7. php中怎么判断输入密码与原密码一致_「每周FPGA案例」电子密码锁设计

    至简设计系列_电子密码锁 --作者:肖肖肖 --案例作者:WB_Yih 本文为明德扬原创及录用文章,转载请注明出处! 1.1 总体设计1.1.1 概述 随着生活质量的不断提高,加强家庭防盗安全变得非常 ...

  8. 51单片机50个实例代码_【附代码】51单片机电子密码锁教程

    简介 大家好,这篇文章的内容是关于如何用51单片机来制作一个电子密码锁的教程,通过这篇教程可以让刚入门的朋友了解矩阵键盘.LCD1602的使用方法,以及密码输入和修改的程序介绍,我会对每个部分进行详细 ...

  9. VHDL电子密码锁设计

    主要内容: 采用先进的EDA技术,利用MAX+PLUSⅡ工作平台和VHDL语言,设计一种新型的电子密码锁.该密码锁具有密码预置和误码报警等功能,用一片FPGA芯片实现. 摘要 本文介绍一种利用EDA技 ...

最新文章

  1. 运行时权限框架YPermission开源
  2. HTTP协议中Content-Length的详细解读。
  3. oracle 创建数据库 表空间 用户 授权和toad导入导出数据库
  4. Linux下安装zookeeper集群(奇数个)
  5. 什么是堆栈?内存中划分出按FIL0方式操作的特殊区域,叫做堆栈
  6. android 代码 lut,Android BitmapFactory.decodeResource()错误或用于加载大LUT的替代选项...
  7. Android 初级探讨 OOM问题 以及解决优化之道
  8. java反射 反射构造函数 报 wrong number of arguments 错误
  9. android 图片合成pdf文件,如何在Android上将多个图像合并到PDF文件中 | MOS86
  10. java松鼠大战代码_松鼠大战2金手指版
  11. Unity Kinect添加自定义姿势识别
  12. Vue中Class和Style几种v-bind绑定的用法-详解案例
  13. mysql面试题总结_mysql面试题小结
  14. SharePlex for oracle on linux安装步骤
  15. 如何查看当前域名的注册信息?
  16. 交叉编译ortp、osip2、eXosip2、mediastreamer2及其附带的库实现SIP软电话
  17. 工业镜头倍率及视场范围、焦距的计算方法
  18. 高级程序员必会的程序设计原则 —— 墨菲定律及防呆设计
  19. C语言及程序设计 套餐 课程主页
  20. MATLAB 手把手带你制作第一个APP designer程序(电子词典)

热门文章

  1. 几个常用的CSS3样式代码以及不兼容的解决办法
  2. spring邮件发送(转)
  3. 使用asp.net mvc开发应用程序,页面中的page.IsPostback还有用处吗?
  4. 安装中文VS2008 SP1 和.NETFRAMEWORK 3.5SP1后智能提示是英文的解决办法
  5. Microsoft Office 企业记分卡管理服务器
  6. 对TCP/IP网络协议的浅出归纳
  7. 大数据之-Hadoop3.x_MapReduce_Combiner案例---大数据之hadoop3.x工作笔记0119
  8. 大数据之-Hadoop伪分布式_配置日志聚集---大数据之hadoop工作笔记0028
  9. mycat集群_HA高可用架构_验证高可用---MyCat分布式数据库集群架构工作笔记0030
  10. ImportError: No module named _caffe