开篇先说一句废话····
本旺名字叫萨摩耶,,Please 叫我旺财,,,哈哈,招财进宝嘛!

智能门锁

  • 开篇
  • 项目要求
  • 项目分析
    • 3.2初始状态说明
    • 3.3设置按键功能即对应处理
      • 按键检测和按键处理
      • 输入模式设置
      • 判断密码与对应处理
      • 修改函数步骤
      • 删除函数步骤
      • 结尾
  • 总结

开篇

其实这个项目很早之前就想做的,当时有个新闻上讲有个学校的同学在自家宿舍门上安装了电子密码锁,当时就想着等自己学习了一定要做出来玩玩,之前看到蓝桥杯单片机组有一道试题和那个新闻差不多,也就是这篇文章写的《智能门锁》。

项目要求

直接上图。

以下内容都截取自模拟试题文件,完整内容和工程文件会打包上传,键总结处。阅读建议,先滑到最后下载上传文件,阅读完整项目要求后再阅读此篇,效果会更好。还要注意的就是说明过程中代码都是拼接到一起的,使用的时候一定要注意。

项目分析

完成项目的每一步在那个试题文件里都告诉了,咱干的事就是按照它说的每一步完成对应功能即可。

3.2初始状态说明

  • 指示灯全部熄灭
  • 数码管全部熄灭
  • 继电器关闭

指示灯就是led,继电器的使用和led差不多,本篇中继电器原本由直流电机代替,后来由于引脚冲突,也换为led。所以指示灯熄灭和继电器关闭就是给对应引脚给高电平(led共阳极)。而数码管全部熄灭也就是给每个数码管段选信号为0x00.(数码管共阴极)

u8 DisPlay[8];       //数码管显示数组
u8 j;
//数码管全灭
for(j=0;j<8;j++)DisPlay[j]=0x00;
//指示灯全灭
led1=1;
led7=1;
led8=1;
//电机关闭
moto=1;//数码管显示
void Showsmg(){u8 i;for(i=0;i<8;i++){switch(i){case 0: LSA=0;LSB=0;LSC=0;break;case 1: LSA=1;LSB=0;LSC=0;break;case 2: LSA=0;LSB=1;LSC=0;break;case 3: LSA=1;LSB=1;LSC=0;break;case 4: LSA=0;LSB=0;LSC=1;break;case 5: LSA=1;LSB=0;LSC=1;break;case 6: LSA=0;LSB=1;LSC=1;break;case 7: LSA=1;LSB=1;LSC=1;break;}P0=DisPlay[i];Delay(1);P0=0x00;}
}

3.3设置按键功能即对应处理

按键检测和按键处理

既然有了按键功能,按一定有按键检测和按键处理了。

#define GPIO_KEY P1
u8 KeyVal;
bit flag;//按键检测,检测是否有按键按下void KeyDown(){char a=0;GPIO_KEY=0x0f;if(GPIO_KEY!=0x0f){Delay(10);if(GPIO_KEY!=0x0f){GPIO_KEY=0x0f;switch(GPIO_KEY){case 0x07:KeyVal=0;flag=1;break;case 0x0b:KeyVal=1;flag=1;break;case 0x0d:KeyVal=2;flag=1;break;case 0x0e:KeyVal=3;flag=1;break;}GPIO_KEY=0xf0;switch(GPIO_KEY){case 0x70:KeyVal=KeyVal;break;case 0xb0:KeyVal=KeyVal+4;break;case 0xd0:KeyVal=KeyVal+8;break;case 0xe0:KeyVal=KeyVal+12;break;}}while((a<150)&&(GPIO_KEY!=0xf0)){Delay(1);a++;}}
}//按键处理
void Keypross(){if(flag==1){switch(KeyVal){case 0:Numpross(0);break;      case 1:Numpross(1);break;   case 2:Numpross(2);break;case 3:Numpross(3);break;case 4:Numpross(4);break;case 5:Numpross(5);break;case 6:Numpross(6);break;case 7:Numpross(7);break;case 8:Numpross(8);break;case 9:Numpross(9);break;case 10:break;case 11:break;case 12:break;case 13:Delpross();break;     //进入删除函数设置case 14:Modpross();break;     //进入修改函数设置case 15:Pripross();break;     //进入输入模式函数}}
}

输入模式设置

按照文件步骤,接下来是输入模式设置
这块有三个part,一个是进入密码输入模式,也就是Pripross()函数设置 首先是页面显示 – ,还有就是要设置一个标志位,来允许数字按键输入的有效与无效。

u8 PassFlag; //密码标志
//输入功能处理
void Pripross(){u8 j;KeyVal=0xff;DisPlay[7]=0x40; // 显示“-”for(j=0;j<7;j++)DisPlay[j]=0x00;PassFlag=1; //允许输入密码
}

第二就是数字按键的处理,如果允许数字按键输入有效,首先把密码存放在用户输入密码数组中,接着就是数码管的显示,因为数码管显示最后是根据一个数组DisPlay[]的,所以只需控制DisPlay[]的元素即可。

因为每按下一个按键,新的数据显示在最后面,之前的数据依次往左移一位,也就是先把前一个数组的数据传给后面的数组(DisPlay[0]是最前面,DisPlay[7]是最后)而传多少次也就是PassPriFlag这个标志位来控制,最后就是把新的数据存放到最前面的数组中。

其实这个数码管显示数组和蛇的移动差不多,蛇移动的过程分解开的话,就是蛇头在不断添加新的数据,(它来控制新的位置信息),而蛇身的运动就是除了蛇头意外,其他的每一节都走前一节的位置(除蛇头以外,每一节都保存前一节的数据),和数码管数组作比较,蛇身的运动,就是除了蛇头外,其他的是把一个数组的数据传给后一个数组中;蛇头就是DisPlay[0],用来保存新的数据,而循环的次数,对于蛇是它的节数,对于数码管就是输入的位数PassPriFlag

三是如果输入完得给一个标志位来判断密码是否输完,注意这里只是是否输完,不是密码是否正确。如果输完,不能接着输入密码,也就是数字按键输入是无效.

u8 PassFlag; //密码标志
u8 PassPriFlag; //密码自加标志
u8 PrintFlag;   //输入结束标志u8 UserPassword[6];     //用户输入的密码数组
u8 AdminPassword[6];    //系统保存的密码数组
//数字按键处理
void Numpross(u8 dat){u8 i,j;KeyVal=0xff;if(PassFlag==1){UserPassword[PassPriFlag]=dat;for(i=PassPriFlag;i>0;i--){      //先传蛇身的数据DisPlay[i]=DisPlay[i-1];}DisPlay[i]=smgduan[dat];        //传完后加载蛇头的数据PassPriFlag++;if(PassPriFlag==6){PassPriFlag=0;PassFlag=0;        //如果接着输入,数字按键输入失效PrintFlag=1;}}
}

判断密码与对应处理

密码输入完成后就是回到主函数中判断密码正确与否和对应的处理了。

首先就是密码判断,直接循环6次,判断用户输入密码数组和系统密码数组是否正确,如果正确,给一个标志位,,如果不正确,给一个标志位并退出判断循环。

if(PrintFlag==1){      //输入结束开始判断密码是否正确PrintFlag=0;for(i=0;i<6;i++){if(UserPassword[i]==AdminPassword[i]){PassRE=1;}else{PassRE=2;break;    //密码错误退出}}
}

根据要求,密码正确或者密码错误都有一个相同点就是倒计时5s,首先就是定时器的设置,要注意的是初始化的时候要关闭定时器。

//定时器0初始化
void Time0Init(){TMOD=0x01;TH0=(65536-9174)/256;  //10msTL0=(65536-9174)%256;EA=1;ET0=1;TR0=0;
}
void Time0() interrupt 1{TH0=(65536-9174)/256; //10msTL0=(65536-9174)%256;tt++;if(tt==100){tt=0;time++;}
}

接着,因为都有倒计时,所以无论密码正确与否,都开启定时器,并把按键标志归零,来判断密码正确时是否有按键操作。

flag=0;     //检测是否有按键按下
TR0=1;

然后就是,密码正确或者密码错误的分别处理了

  • 密码正确 :继电器打开,然后就是数码管的显示,直接赋给段选信号即可。因为密码正确或者错误后5s后结果不同,还要设置一个标志位来区别。
  • 密码错误 :L1指示灯亮,同样,设置一个标志位。
u8 PassRE;       //密码正确错误标志
u8 DoLapFlag;   //门或灯状态标志if(PassRE==1){moto=0;       //开启电机DisPlay[7]=smgduan[0];       //第一位显示ODisPlay[6]=0x00;DisPlay[5]=0x00;DisPlay[4]=0x00;DisPlay[3]=smgduan[0];      //显示ODisPlay[2]=smgduan[16];       //显示PDisPlay[1]=smgduan[14];       //显示EDisPlay[0]=smgduan[17];       //显示NDoLapFlag=1;
}
if(PassRE==2){led1=0;        //L1指示灯亮DoLapFlag=2;
}

不同的结果处理完就要处理定时5s后的操作了

  • 门状态,如果5s到了,而且没有按键按下,进入初始化状态,如果有按键按下,标志归零,(因为有按键的话,在按键处理中就进入功能了)
  • 等状态,如果5s到了,指示灯熄灭,进入初始化状态等待
    因为最后除了有按键按下时进入函数了,其他情况都是进入初始化状态,所以分别把定时器关闭。
if(DoLapFlag==1){if(time==5){if(flag==0){time=0;TR0=0;Init();        //进入初始化状态}else{flag=0;     //归零time=0;}}}if(DoLapFlag==2){if(time==5){time=0;TR0=0;led1=1;Init();      //进入初始化状态}}

修改函数步骤

接着按照步骤,密码正确的情况下,按S12按键可以修改,这是修改函数即可。
在修改函数中,首先就是页面的显示,对数码管显示函数赋对应的段选信号。设置一个标志位,允许修改密码,要注意的就是,因为输入密码和修改密码处理不同的数组(用户输入密码数组和系统密码数组),所以当修改密码就不能输入密码,输入密码就不能修改密码。

//修改功能处理
void Modpross(){u8 j;KeyVal=0xff;if((PassRE==1)){PassRE=0;DisPlay[7]=smgduan[12];for(j=0;j<7;j++)DisPlay[j]=0x00;ModFlag=1;        //允许修改密码PassFlag=0;        //不允许输入密码DoLapFlag=0;  //既不是门状态也不是灯状态,避免在修改密码数字按键过程中进入if条件恢复初始化状态TR0=0;            //关闭定时器time=0;}
}

接着就是数字按键,这里数字按键控制系统密码数组
保存到数组后,也是数码管显示,和输入密码差不多,如果密码输入六位,保存密码到AT24C02中,退出修改密码界面,也就是数码管显示数组修改为别的数据,这里全部关闭,要求又要计时5s,那启动定时器,重新计算时间(门状态,因为5s没操作门关闭)

if(ModFlag==1){AdminPassword[PassPriFlag]=dat;for(i=PassPriFlag;i>0;i--){DisPlay[i]=DisPlay[i-1];}DisPlay[i]=smgduan[dat];PassPriFlag++;if(PassPriFlag==6){PassPriFlag=0;ModFlag=0;//写入AT24C02for(j=0;j<6;j++)Write(j,AdminPassword[j]);DoLapFlag=1;   //重新计算时间TR0=1;moto=0;         //开启电机for(j=0;j<8;j++)DisPlay[j]=0x00;}
}

删除函数步骤

修改完,就是清除密码了,对删除函数处理
删除处理,有两部分,

  • 第一就是输入密码模式下,首先先恢复密码输入状态,并重新统计密码位数(没有初始化用户输入密码数组,直接重新输入赋值)
  • 第二就是修改密码下,这里因为数组被改变,必须重新从AT24c02中读取系统密码,数码管显示数组复位。

//清除功能处理
void Delpross(){u8 k;KeyVal=0xff;if(PassFlag==1){        //输入密码模式下允许清除//重新恢复输入密码状态Pripross();PassPriFlag=0; //重新统计密码位数}if(ModFlag==1){        //修改密码模式下允许清除for(k=0;k<6;k++){AdminPassword[k]=Read(i);DisPlay[k]=0x00;}PassPriFlag=0; //重新统计密码位数DisPlay[6]=0x00;DisPlay[7]=smgduan[12];}
}

结尾

最后剩下一些结尾。
led1指示灯功能已经设置了(在密码错误处)
led7指示灯是密码输入状态亮,其余不亮,led8指示灯是修改密码状态下亮,其余不亮,那结合起来,在参数设置的时候外加led即可

//输入模式
PassFlag=1;    //允许输入密码
led7=0;
ModFlag=0; //不允许修改密码
led8=1;
//修改密码下
ModFlag=1;     //允许修改密码
led8=0;
PassFlag=0;        //不允许输入密码
led7=1;

最后就是主函数中的一些设置了

第一次烧录程序之前,先的往AT24c02中写入密码(888888),以后就把这些都注释了即可。

u8 AdminPassword[6]={8,8,8,8,8,8};
for(i=0;i<6;i++)Write(i,AdminPassword[i]);

首先初始化和读取At24c02中的密码,不断地按键检测,按键处理,数码管显示,如果输入结束开始判断密码是否正确,最后就是5s计时后不同的处理了。

总结

大致步骤就是这样啦,因为我的水平有限,所以一定要下载pdf文件,先自己阅读一遍项目对项目有所了解,然后在根据步骤阅读这篇文章,这样效果会好点。

同样,完整代码和完整项目要求贴在这不方便,所以我打包上传了,链接在下面,为了避免掏钱,我设置了粉丝可下载,如果你觉得我写的还不错,还看得过去,就点个赞关注一下,就可以下载了;如果不想这样,也可以先关注然后下载后取关就好,都是为了学习知识。谢谢各位。

智能门锁

51单片机应用篇-- --智能门锁相关推荐

  1. 学习笔记之51单片机键盘篇(非编码键盘与编码键盘、非编码键盘的扫描方式、独立键盘、矩阵键盘)

    这篇博文主要记录51单片机键盘篇(非编码键盘与编码键盘.非编码键盘的扫描方式.独立键盘.矩阵键盘.键盘消抖等)包含原理图.代码等 (一)基础补充 1.键盘的任务 2.键盘的识别 3.如何消除按键的抖动 ...

  2. 51单片机定时器中断怎么用-------51单片机基础篇

    首先,什么时定时器,简单来说可以比喻为一个闹钟,当你把他打开以后,他就会每秒动一下,+1,+1,+1,+1,如果你设置了某一个时间点闹钟会向以后,那么当闹钟的时间点+1,+1,+1,+到了你设置的时间 ...

  3. 51单片机学习篇-- --红外通信(PPM脉时)笔记

    开篇先说一句废话···· 本旺名字叫萨摩耶,,Please 叫我旺财,,,哈哈,招财进宝嘛! 开篇 从学完帮网友写完<倒计时数字钟–矩阵按键可调>然后在CSDN上总结完之后,学习了剩下的模 ...

  4. 51单片机存储篇:EEPROM(I2C)

    先认识I2C通信 基本概述  IIC(Inter-Integrated Circuit)其实是IICBus简称,所以中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构,由飞利浦公司在1980 ...

  5. 第一篇 51单片机入门篇

    目录 一.开发环境 1.Keil5和STC-ISP (1)keil5创建工程并设置生成.hex文件 (2)STC-ISP烧写keil编译生成的程序到单片机 二.点亮单片机的LED灯 1.关于sbit. ...

  6. 51单片机学习篇-- --基于51单片机的串口通信协议

    开篇先说一句废话···· 本旺名字叫萨摩耶,,Please 叫我旺财,,,哈哈,招财进宝嘛! 开篇 计算机按照下行数据通信协议,串口发送数据,地址为自己的学号(十六进制),单片机收到后(收到的是数据, ...

  7. 51单片机外设篇:点阵式LCD

    什么是LCD LCD(Liquid Crystal Display)俗称液晶. 液晶是一种材料,液晶这种材料具有一种特点:可以在电信号的驱动下液晶分子进行旋转,旋转时会影响透光性,因此我们可以在整个液 ...

  8. 51单片机学习篇-- --超声波测距(HC--SR04)笔记

    开篇先说一句废话···· 本旺名字叫萨摩耶,,Please 叫我旺财,,,哈哈,招财进宝嘛! 开篇 本单片机购买的时候带的超声波模块是HC-SR04,根据好多材料都说用这个的原因是便宜,,,不过没关系 ...

  9. 51单片机外设篇:蜂鸣器

    蜂鸣器 蜂鸣器是一种将电信号转换为声音信号的器件,常用来产生设备的按键音.报警音等提示信号. 蜂鸣器按驱动方式可分为有源蜂鸣器和无源蜂鸣器: 有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发 ...

最新文章

  1. ArcGIS for Desktop入门教程_第二章_Desktop简介 - ArcGIS知乎-新一代ArcGIS问答社区
  2. Kubernetes故障问题
  3. golang post get 请求 简介
  4. 浅谈MySQL数据库中的锁与事务
  5. 介绍一个非常实用的Visual Studio Code扩展 - indent-rainbow
  6. 疯子的算法总结(三) STL Ⅱ迭代器(iterator) + 容器
  7. 计算机专业联考335分,联考专业分、文化分达到多少能过本科线(附2019年美术高考分数线汇总...
  8. es6 import 命令
  9. delta对冲策略_股票基础知识—Delta中性理论
  10. python假如输入错误重新输入_认识python之输入(4)
  11. angular input_可视化的 Angular 响应式编程
  12. 2、数字,字符串,列表,字典,集合
  13. 人工智能撰稿将代替人工写作?我们拭目以待
  14. 墙面有几种装修方法_卧室装修静音环保攻略,赶紧收藏起
  15. 实例详解机器学习如何解决问题
  16. 如何将txt中的数据整理到Matlab中画图
  17. 新浪微博发布文章html,微博网页版如何发布头条文章
  18. 飞Young任意路由器连接[破解路由器限制]
  19. 第二章课后习题 华氏温度与摄氏温度的java简单转换
  20. 10款热门的企业报表工具软件,该如何选择?

热门文章

  1. 34. 在排序数组中查找元素的第一个和最后一个位置——二分法的魔鬼细节 小记
  2. 机器学习--基础算法--机器学习基础
  3. iris web框架无法加载静态文件
  4. 收藏能力升级,支付宝版「小程序桌面」初现!
  5. JS进阶 Day1 作用域 函数进阶 结构赋值(学习笔记)
  6. 码农:听新来领导说桌面乱的代码也肯定不整洁,我偷偷收拾了工位
  7. 《Counting Out Time: Class Agnostic Video Repetition Counting in the Wild》论文笔记
  8. Android之低功耗蓝牙的基本使用
  9. 牛市最容易亏钱而熊市才是真正的开始
  10. CHIL-ORACLE-循环 语法