51单片机控制的万能密码锁(附仿真文件+源代码)
前几天有小伙伴留言说想知道单片机是怎么样控制密码锁的,正好做过一个类似的实验,下面我分享出来,希望对你们有所帮助。
51单片机控制的万能密码锁系统,PROTEUS仿真文件
初始密码:12345678
此程序用51单片机控制74LS164锁存器来实现
单片机与存储器之间通过IIC 通过通讯来建立密码系统通讯
仿真启动开始设置密码
万能密码锁参考程序源代码:
#include<AT89x51.h>
#include"intrins.h"
#include"key.h"
#include"xsh.h"
#include"24c02.h"
#define ulong unsigned long
bit BJCB=0;//报警标志
XG=0,//修改密码标志位
BJ=0,//报警标志位
SJ=0;//锁键盘标志位
// xg=0;//修改密码标志位
uchar PSWD0_0[16]={0};//密码输入缓存存储单元
//uchar code PSWD0_1[16]={1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8};//用户初始密码存储单元
//uchar PSWD1_0[16]={0};//读出密码缓存存储单元
uchar PSWD1_1[16]={1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8};////管理员初始密码存储单元
sbit OUT=P3^5;//输出端口
sbit L1=P0^2;//上电指示
sbit L2=P0^1;//开锁指示
sbit L3=P0^0;//报警指示
uint mg=0,//密码个数
KSC=0,//开锁次数
BJC=0,//报警次数
TCNTY=0,//用户按键定时次数累加
TCNTG=0,//管理员输入密码定时次数
yhsh,//用户输入标志位
glsh,//管理员输标志位
shw;//密码输入标志位
void yhmimaxig();//密码修改程序
void glmimaxig();//管理员修改程序
void bjyin(ulong t)
{
ulong c;
uint n;
for(c=0;c<t;c++)
{
for(n=0;n<50;n++); //延时
BEEP=~BEEP; //取反输出到喇叭的信号
}
}
void delay_10ms(void)
{
uint i = 1000;
while(i--);
}
//////////////定时中断服务函数//////////////////////////////////////
void timer0() interrupt 1
{
uint i;
TH0=(65536-50000)/256; //对TH0 TL0赋值50MS定时
TL0=(65536-50000)%256; //重装计数初值
if(yhsh==1)
{
TCNTY++;//用户定时计数
if(shw==1)
{
TR0=0;
TCNTY=0;
}
if(TCNTY==400)
{
TR0=0;//关闭T0定时器
TCNTY=0;
mg=0;//密码个数清零
L1=1;
for(i=0;i<2;i++)//声光报警电路
{
L3=0;
bjyin(1000);
L3=1;
delay(1000);
}
L1=0;
}
}
else if(glsh==1)
{
TCNTG++;//管理员定时计数
if(shw==1)
{
TR0=0;
TCNTG=0;
}
if(TCNTG==400)
{
TR0=0;//关闭T0定时器
TCNTG=0;
mg=0;//密码个数清零
L1=1;
for(i=0;i<2;i++)//声光报警电路
{
L3=0;
bjyin(1000);
L3=1;
delay(1000);
}
L1=0;
}
}
}
void main()
{
uint i;
TMOD=0x01; //定时器工作在方式1
ET0=1;
EA=1;
TH0=(65536-50000)/256; //对TH0 TL0赋值
TL0=(65536-50000)%256; //使定时器0.05秒中断一次
//Read_page24c02(0x00,PSWD1_1,16);//向24c02里读用户初始密码
//i2cWrite24LC16B(0,0X20);
/////////////第一次向24c02里写入初始管理员密码、用户密码、开锁次数/////////////////////
for(i=0;i<16;i++) //用一次写一个向24c02里写
{
i2cWrite24LC16B(PSWD1_1[i],i);
delay_10ms;
}
for(i=0;i<16;i++) //用一次写一个向24c02里写
{
i2cWrite24LC16B(PSWD1_1[i],0x10+i);
delay_10ms;
} //proteus仿真时用,烧程序时,第一次用,第二次不用。
KSC=i2cRead24LC16B(0X20);
loop: L1=0;//上电红灯亮
L2=1;//开锁成功后绿灯亮
L3=1;//输错时黄灯亮报警
OUT=0;//开信号关闭
display_0(KSC);//开锁前显示
///////////密码输入/////////////////
if(SJ==0)//锁键盘标志位为0
{
do
{
flag=0;//键盘标志位
key();
if(flag==1&&num==12) //判断是否为管理员功能键按下
{
goto gl;
}
if(flag==1&&num<=9)
{
PSWD0_0[mg]=num;
mg++;//密码个数
}
if(flag==1&&num==14&&mg>=1)//输入错误删除
{
mg=mg-1;
}
if(mg==1) //有密码键按下开定时器限时
{
TR0=1;
yhsh=1;
}
}
while(num!=15);
if(mg!=16)
{
for(i=mg;i<16;i++)
{
PSWD0_0[i]=0;
}
}
/////////////////密码比较电路////////////////////////////
if(flag==1&&num==15)
{ flag=0;
yhsh=0;
shw=1;
num=0;
for(i=0;i<16;i++) //从24c02里读出16个密码
{
PSWD1_1[i]=i2cRead24LC16B(i);
delay_10ms;
}
for(i=0;i<16;i++)
{
if(PSWD1_1[i]!=PSWD0_0[i])
{
BJCB=1;
break;
}
else
BJCB=0;
}
}
if(BJCB!=0)
{
BJC++;
if(BJC!=3)
{
BJCB=0; //第一次和第二次报警
delay(500);
mg=0;//密码个数清零
L1=1;
for(i=0;i<3;i++)//声光报警电路
{
L3=0;
display_3();
bjyin(1000);
L3=1;
delay(1000);
}
goto loop;
}
else if(BJC==3)
{
BJC=0;
BJCB=0;
display_5();//三次输入密码失败,自锁
SJ=1;//锁键盘标志位
mg=0;//密码个数清零
L1=1;
for(i=0;i<2;i++)//声光报警电路
{
L3=0;
bjyin(1000);
L3=1;
delay(1000);
}
goto loop;
}
}
else
if(BJCB==0)
{
KSC++;
display_1(KSC);
i2cWrite24LC16B(KSC,0X20);
if(KSC==100)
{
SJ=1;
}
L2=0;
L1=1;
OUT=1;
mg=0;//密码个数清零
loop1:do //键盘扫描等待功能键按下
{
flag=0;
key();
if(flag)
{
flag=0;
switch(num)
{
case 13:
{
display_2();
do
{
flag=0;//键盘标志位
key();
if(flag==1&&num<=9)
{
PSWD0_0[mg]=num;
mg++;//密码个数
}
if(flag==1&&num==14&&mg>=1)//输入错误删除
{
mg=mg-1;
}
if(mg==16)
{
do //键盘扫描等待功能键按下
{
flag=0;
key();
}
while(num!=15);
}
}
while(num!=15);
if(mg!=16&&num==15)
{
for(i=mg;i<16;i++)
{
PSWD0_0[i]=0;
}
}
if(flag==1&&num==15)
{
flag=0;
mg=0;
for(i=0;i<16;i++) //用一次写一个向24c02里写
{
i2cWrite24LC16B(PSWD0_0[i],i);
delay_10ms;
}
display_1(KSC);
do //键盘扫描等待功能键按下
{
flag=0;
key();
}
while(num!=11); //按下返回键,锁锁返回
{
goto loop;
}
}
};break;
case 11: {
goto loop;
//break;
}
}
}
}
while(flag!=0);//如果设置密码键按下
goto loop1;
// i2cWrite24c02_page(0x00,PSWD1_1,mg);
}
}
else
{
do
{
flag=0;
key();
}
while(num!=12);//判断是否为管理员功能键按下
gl:do//管理员输入密码
{
flag=0;
key();
if(flag==1&&num<=9)
{
PSWD0_0[mg]=num;
mg++;//密码个数
}
if(flag==1&&num==14&&mg>=1)//删除键按下
{
mg=mg-1;
}
if(mg==1)
{
TR0=1;
}//开定时器TO限5秒开锁
}
while(num!=15);
if(mg!=16&&num==15)
{
for(i=mg;i<16;i++)
{
PSWD0_0[i]=0;
}
}
//////////管理员密码比较///////////////////////
//Read_page24c02(0x10,PSWD0_1,16)
for(i=0;i<16;i++) //从24c02里读出16个密码
{
PSWD1_1[i]=i2cRead24LC16B((0x10+i));
delay_10ms;
}
if(flag==1&&num==15)
{ flag=0;
shw=1;
num=0;
for(i=0;i<mg;i++)
{
if(PSWD1_1[i]!=PSWD0_0[i])
{ BJCB=1;
break;
}
else
BJCB=0;
}
}
if(BJCB!=0)
{
BJC++;
if(BJC!=3)
{
BJCB=0; //第一次和第二次报警
mg=0;//密码个数清零
L1=1;
for(i=0;i<2;i++)//声光报警电路
{
L3=0;
display_3();
bjyin(1000);
L3=1;
delay(1000);
}
display_1(KSC);
goto loop;
}
else
{
BJCB=0;
display_5();//三次输入密码失败,自锁
mg=0;//密码个数清零
delay(10000);
display_1(KSC);
goto loop;
}
}
else
{
SJ=0;
display_4();//管理员开锁显示
mg=0;
L2=0;
L1=1;
L3=0;//密码个数清零
do //键盘扫描等待功能键按下
{
flag=0;
key();
}
while(flag==0); //如果设置密码键按下
if(flag==1&&num==13)
{
flag=0;
display_2();
do
{
flag=0;//键盘标志位
key();
if(flag==1&&num<=9)
{
PSWD0_0[mg]=num;
mg++;//密码个数
}
if(flag==1&&num==14&&mg>=1)//输入错误删除
{
mg=mg-1;
}
if(mg==16)
{
do //键盘扫描等待功能键按下
{
flag=0;
key();
}
while(num!=15);
}
}
while(num!=15);
if(mg!=16&&num==15)
{
for(i=mg;i<16;i++)
{
PSWD0_0[i]=0;
}
}
if(flag==1&&num==15)
{
flag=0;
mg=0;
for(i=0;i<16;i++) //用一次写一个向24c02里写
{
i2cWrite24LC16B(PSWD0_0[i],(0x10+i));
delay_10ms;
}
display_4();
do //键盘扫描等待功能键按下
{
flag=0;
key();
}
while(num!=11); //按下返回键,锁锁返回
{
goto loop;
}
}
}
if(flag==1&&num==10)
{
KSC=0;
i2cWrite24LC16B(KSC,0X20);
display_1(KSC);
do //键盘扫描等待功能键按下
{
flag=0;
key();
}
while(num!=11);//按下返回键,锁锁返回
goto loop;
}
if(flag==1&&num==11)//按下返回键,锁锁返回
{
goto loop;
}
}
}
}
最后,如果有什么意见或者建议欢迎您留言给我,让我们共同学习一起进步,
如果需要 完整代码或设计文件,请在下方留言或者私信我,看到后会第一时间回复。
谢谢大家!
如果喜欢我的文章请评论转发加关注哦。
51单片机 ESP8266模块 APP控制继电器,物联网DIY入门新手指南
题目
大家好,超子能力有限,技术不高,有什么错误的地方,欢迎批评指正。超子之前写过一篇STM32单片机配合ESP8266的WiFi模块接入阿里云生活物联网平台的DIY实验,有小伙伴问我51单片机能不能实现,答案是能。那么今天超子就给大家介绍下51单片机的实现方法。
程序设计中,我们使用的软件是Keil集成开发环境,C语言编写。如果大家想要程序源码的话,可以私信我,超子不是专业的程序员,水平不高,大家不嫌弃就行。
一说到51单片机的型号那就太多了,因为我们要使用MQTT协议对接阿里云生活物联网平台,所以对RAM空间要求比较多,一些常见的型号比如89C51,89C52,因为RAM空间太少不能用,所以我们本次DIY程序设计使用的单片机型号是STC12LE5A60S2。
ESP8266模块是通过串口AT指令控制的那种,网上有很多,价格也比较便宜,非常适合我们做DIY。
虽然我们前面使用STM32单片机做了第一个DIY设计,但是考虑到有些小伙伴,没有看过,所以超子还是说的详细一点,把每一个步骤再重新走一遍。
图1
首先进入我们自己的阿里云生活物联网平台,然后创建项目,我们就创建一个51单片机DIY项目吧,以后所有51单片机相关的DIY设计,我们都加入到这个项目内。
图2
项目建立完毕后,可以在项目列表中,看到51单片机DIY项目,旁边的第一个DIY设计项目,是上次STM32单片机DIY设计时建立的。然后我们点击51单片机DIY项目,进入项目管理界面。
图3
接下来,我们需要创建新产品。
图4
产品名称就叫51单片机插座,大家也可以起自己喜欢的名字。然后所属品类选择电工照明下的插座。节点类型选择设备,不接入网关,因为ESP8266可以连接WiFi路由器,直接具备接云的能力,所以是直连设备,不需要网关。连网方式一定要注意,虽然ESP8266是WiFi模块,但是不能选择WiFi连网,因为我们使用的是通用的,AT指令控制的ESP8266,没有在阿里云生活物联网平台认证,不兼容阿里云生活物联网平台APP的配网协议,如果我们选择WiFi方式的话,配网过不去,程序设计就无法进行了。所以我们取个巧,使用蜂窝连接方式,跳过阿里云生活物联网平台APP的配网,我们可以用ESP8266模块自己的APP配网或是直接把WiFi的SSID以及密码写在程序里。然后数据格式选择JSON,不适用ID2认证,最后点击完成就行了。
图5
产品建立完成后,我们要先进行第1步的功能定义的设置,我们选择的是电工照明分类下的插座,所以阿里云生活物联网平台自动帮我们添加了电源开关的功能属性。所以这一步我们不需要做什么额外的设置,直接点击下一步:设备调试。
图6
我们新建设备的时候,为了跳过配网协议,所以故意选择了蜂窝的连接方式,所以我们随便选一个通过认证的模组就行,选哪个型号都不会影响我们的DIY设计。
图7
选好模组后,我们点击新增测试设备,每个产品下可以添加最多50个免费的测试设备,我们做DIY程序设计,50个足够我们用了。
图8
新增测试设备时,我们要输入设备名称,就叫D001吧,超子喜欢用这种编号命名设备,大家可以根据喜好自己设置设备名称,然后点击确定就行。
图9
然后会弹出激活凭证,也就是三元组信息,这个是登录阿里云生活物联网平台的认证信息,稍后我们修改51单片机C语言程序时要用到这些重要信息。然后我们点击下一步:人机交互。
图10
和使用STM32单片机做DIY设计时一样,我们使用阿里云生活物联网平台的公版APP,也就是云智能APP。我们打开上图中红圈所示的开关。
图11
然后我们点击未设置,选择一个界面。
图12
自己喜欢哪个,选一个就行,然后点击确认。
图13
然后页面下方,我们要配置APP功能,同STM32单片机DIY时一样,我们主要设置多语言管理,填写品牌名称,设备名称,产品编号等等,大家根据喜好自己填一个就。最下方我们看到了天猫精灵,插座是天猫精灵支持的品类,所以可以直接绑定天猫精灵的账号,用天猫精灵控制开关,非常方便。然后我们点击下一步:批量投产。
图14
我们勾选上充分了解的对勾,然后点击开发完成,到此我们整个项目的配置就算完成了,就下来我们要修改51单片机的程序了。
图15
首先看esp8266.c源文件,wifi_mode变量用于设置使用哪种方式进行配网,大家根据注释自行选择就行,如果选择0的话,SSID和密码要在esp8266.h头文件中设置。
图16
然后我们需要修改mqtt.h头文件中的6个字符串,最麻烦的就是第3个,也就是MQTT协议中CONNECT报文中的包含的密码信息。我们一个一个来,讲一下怎么修改。
我们先看第6个需要修改的字符串,服务器的域名,格式如下所示:
*.iot-as-mqtt.cn-shanghai.aliyuncs.com
我们把*号替换成我们自己设备的ProductKey,这个ProductKey就是我们新建设备时弹出的3元组信息,图9所示,以我新建的设备作为例子,我们修改一下,最终结果如下:
a1jWDQfzbVB.iot-as-mqtt.cn-shanghai.aliyuncs.com
然后看第4和第5个字符串, 都是Topic主题,第4个set是用来接收控制开关命令推送的Topic,我们需要订阅它,第5个post是用来往服务器上传数据的,这次的实验post不是关键点。那么这两个Topic再那找呢?看下图。
图17
测试设备点击红圈圈中的查看。
图18
然后在Topic列表下,可以看到post和set,根据自己设备的实际内容,修改程序中第4和第5个字符串即可。
接下来看第1个字符串,也就是MQTT协议中CONNECT报文中包含的客户端ID信息,格式如下:
*|securemode=3,signmethod=hmacsha1|
其中*号是设备名称,以我的设备为例,修改一下,结果如下:
D001|securemode=3,signmethod=hmacsha1|
然后再看第2个字符串,也就是MQTT协议中CONNECT报文中包含的用户名信息,格式如下:
*
其中*号是设备名称 ,#号是ProductKey,都是图9中的三元组信息,就以我的设备为例,修改一下,结果如下:
D001&a1jWDQfzbVB
最后再看最麻烦的第3个字符串,也就是MQTT协议中CONNECT报文中包含的密码信息,需要经过一步加密,我们先要构建待加密的明文字符串,格式如下:
clientId*deviceName*productKey#
其中*号是设备名称 ,#号是ProductKey,以我的设备为例,修改一下,结果如下:
clientIdD001deviceNameD001productKey a1jWDQfzbVB
加密用的秘钥是图9中,三元组信息里的DeviceSecret,我们网上找一个加密算法的网站。
图19
我们复制待加密的字符串和密钥的时候,一定要多检查,不要多空格,不要多回车,错一点加密后的结果都不会正确的,所以大家一定要小心。加密后的结果就是第3个字符串的内容,到此6个需要修改的字符串我们都修改完毕了,重新编译程序,下载到开发板就行了。然后我们再回到阿里云生活物联网平台。
图20
我们进入第3步,人机交互设置页面,我们点击红圈所示的内容,然后弹出页面,需要我们填写设备名称,以我的为例,填上D001,然后就可以生成我们需要的,添加设备的二维码,因为文章中不能出现二维码,所以超子就不展示了。到此我们本次51单片机的DIY程序设计,基本就完成了。
大家如果有什么想做的,或者有什么想法,都可以评论区留言告诉超子哦~~~想要程序的小伙伴,可以举手哦~~~
相关问答
multisim怎么使用 51单片机 的头文件?1.利用multisim建立一个Design,放置一个51单片机,根据向导建立一个51单片机的源代码工程,并选择生成一个main.c文件。2.在生成的main.c中有一个main函数,输...1....
如何将程序导入 51单片机 ?使用串口线接到电脑的9针串口,然后使用STC软件可以将HEX文件下载到单片机中去。如果你的程序只是源代码,那么必须用keil编译成HEX文件,才能使用STC软件。使用...
51单片机 将模拟信号转数字信号 - OSCHINA - 中文开源技术交...单片机自带AD转换歪,这都是我8年前干的事情,单片机本身就支持模拟信号转数字信号,你只需要接收数字信号进行处理就行。51单片机将模拟信号转数字信号,谁有类似...
51单片机 编写程序时如何将两个不同功能的程序连在一起以达到...我用51单片机做的智能小车有遥控,循迹,避障三个功能,用什么样的程序能够达到功能切换我用51单片机做的智能小车有遥控,循迹,避障三个功能,用什么样的程序能够...
单片机 原码怎么计算?使用keil软件,自带统计源码和编译后的二进制代码大小功能。使用keil软件,自带统计源码和编译后的二进制代码大小功能。
自带LCD驱动的 单片机 ?这种现象很正常,可能是每一个嵌入式从业者都可能遇到,因为嵌入式软件的难度不是线性增加,而是陡然提升的。对于接触过51单片机的开发者来说,在学习STM过程中...
单片机 流水灯C语言程序(8个灯,依次点亮每个灯,延时500MS)?单片机流水灯C语言程序(8个灯,依次点亮每个灯,延时500MS)源代码如下:#include单片机流水灯C语言程序(8个灯,依次点亮每个灯,延时500MS)源代码如下:#include
怎么把手机电容屏的引脚连出来,改成 单片机 可以用的?去官方下载查看对应屏幕的线序和时序,只要时序对应该就可以,不过单片机主频有些慢哦,刷新图像会很卡的,我以前试过.不过我发现淘宝上有专门的电容触摸屏模块...
单片机 是10位的AD如何通过程序的方法达到12位的分辨率?单片机是10位ADC,是能用软件扩成12位结果的。方法其实很简单,但却是伪12位的结果。下面通过实例进行扩位演算,看看伪12位结果,在使用上的局限性。10位二进...
Java具体是做什么的?Java的起源Java源自Sun公司的一个叫Green的项目,其初始目的是为家用消费电子产品开发一个分布式代码系统,让人们可以通过这个技术,把E-mail发送给电冰箱、电...