资源描述
级电子信息工程专业单片机课程设计
※※※※※※※※※
※※
※※
※※
※※※※※※※※※
单片机课程设计报告书
课题名称
基于89C51单片机
无线电子密码锁设计
姓 名
刘武
学 号
学 院
通信与电子工程学院
专 业
电子信息工程
指引教师
祝秋香 讲师
12月20日
一、设计任务及规定
设计任务:
设计一种六位密码无线电子密码锁。
要 求:
(1)通过无线方式进行远程开关密码锁;
(2)通过无线方式更改密码;
(3)实现密码掉电存储。
指引教师签名:
年 月 日
二、指引教师评语
指引教师签名:
年 月 日
三、成绩
验收盖章
年 月 日
基于89C51单片机无线电子密码锁设计
1 设计目
(1)理解MCS-51单片机用法和熟悉蓝牙模块;
(2)掌握AT89C51芯片用法及蓝牙模块连接与使用;
(3)熟悉单片机程序仿真软件Proteus使用;
(4)理解MCS-51单片机开发板工作原理以及芯片组合;
(5)熟悉无线电子密码锁设计及实现。
2 设计思路
2.1 选取设计电路
设计51单片机与蓝牙连接电路。
2.2 所选设计电路因素
(1)由于无线电子密码锁设计需要用到蓝牙模块,用到单片机资源并不是诸多,而51单片机资源有8位CPU、4KBROM、128BRAM、2个16位定期/计数器、4组8位I/O、1个串口和5个中断源,可以更有效率运用到51单片机资源。
(2)可现实无线功能模块有:蓝牙模块、无线模块、红外遥控模块,由于相对之下,蓝牙模块更容易实现,更容易操作,最后选取蓝牙模块实现手机远程控制。
(3)为了提高效率,可以运用51单片机开发板硬件,用LED灯模仿密码锁开关,当LED灯亮起时代表锁已经启动,熄灭则代表密码锁被关闭。应用在实际中可用继电器代替LED亮灭去控制强电开关。
3 设计过程
3.1 设计总框图
无线电子密码锁分为两个重要功能模块:51单片机模块,蓝牙实现模块。这两个模块共同工作完毕本电路功能实现。其中运用AT89C51芯片来实现51单片机模块功能,完毕数码管、发光二极管实现,同步运用HC06蓝牙模块来实现手机远程控制功能。其设计总框图如图1所示:
图1 总体方框图
3.2 单元模块设计
3.2.1. 总电路
其设计总电路如图2所示:
图2 总电路图
其工作原理如下:
通过在51单片机开发板对AT89C52芯片写入程序,建立单片机与蓝牙模块之间串口通信,并通过手机输入指令输入到蓝牙模块之中,通过程序运用单片机串口将蓝牙与51单片机进行通信,并控制单片机引脚,从而控制外围电路LED灯亮灭和数码管功能实现。
3.2.2 51单片机系统
单片机最小系统是在以MCS-51单片机为基本上扩展,使其能更以便地运用于测试系统中,不但具备控制以便、组态简朴和灵活性大等长处,并且可以大幅度提高被测试技术指标,从而可以大大提高产品质量和数量。单片机以其功能强、体积小、可靠性高、造价低和开发周期短等长处,称为在实时检测和自动控制领域中广泛应用器件,在工业生产中称为必不可少器件,特别是在寻常生活中发挥作用也越来越大。本课题设计重要在MCS-51单片机上扩展I/O口,扩展定期器定期范畴,扩展键盘显示接口。
下图为AT89C51芯片引脚图如图3所示:
图3 89C51芯片引脚图
3.2.3 复位及振荡电路
单片机中复位及振荡电路如图4所示:
图4 复位及振荡电路图
复位电路由按键复位和上电复位两某些构成。按键复位就是在复位电容上并联一种开关,当开关按下时电容被放电、RST也被拉到高电平,并且由于电容充电,会保持一段时间高电平来使单片机复位。MCS51使用11.0592MHz晶体振荡器作为振荡源,由于单片机内部带有振荡电路,因此外部只要连接一种晶振和两个电容即可,电容容量普通在15pF至50pF之间。
3.2.4 八段数码显示管
单片机中数码管实现与显示电路如图5所示:
图5 数码管电路图
MCS-51单片机包括六个共阴极8段数码管显示屏,可以使用动态扫描或者静态显示方式驱动。八位段选在通过330Ω限流后连接在单片机P0口上。
3.2.5 按键及LED电路
单片机中LED灯与按键电路如图6所示:
图6 按键及LED电路图
开发板上提供了8个独立LED,由P2口控制,同样采用共阳级接法,因此只有当P2口输出低电平时LED才会点亮。这样做重要因素是由于单片机低电平驱动能力高。
3.2.6 蓝牙模块
HC-06是主从一体化蓝牙串口模块,主从可指令切换,指令少于HC-05,使用简朴。(供电电压 3.3V~3.6V)主机:用来搜索从设备,不能被其她设备搜索。(带白点蓝牙模块)从机:用来被搜索设备,不能积极搜索其她设备。主从连上后来就相称于一根串口线使用,这个时候就不分主从,也就是透传模式。蓝牙透传模块可以让你本来使用串口设备挣脱线缆束缚在10米范畴内实现无线串口通信。
4 系统设计
4.1 主程序流程图
系统总流程图如图7所示,流程图分析:一方面系统初始化,系统开始运营,当手机输入数字密码时,数码管会以加密方式显示输入状态,若是6位密码输入对的,则LED亮起(代表锁打开),否则熄灭。在LED灯亮起前提下,可以输入命令’c’进入更改密码模式,然后重新输入新密码,此时数码管显示是不加密明文。输入新密码完毕之后输入命令’d’对新密码进行确认,所有操作均在手机端APP中完毕。在手机按键操作之下点击’close’可以直接关闭密码锁,点击’retry’可以重新开始输入密码。本密码锁能实现掉电密码保存功能,虽然断电重启也不会重新恢复初始密码,大大提高了电子密码锁实用性和安全性。而更改密码这一功能是在高档模式下更改,普通人虽然懂得了密码但是不懂得更改密码命令是无法更改密码,安全保障更上一层。
注:更改密码为此密码锁高档模式,普通权限下使用是“键盘模式”。
图7 程序流程图
4.2 硬件测试
(1)用手机连上HC06模块蓝牙之后,在手机APP中键盘模式里面输入初始密码‘012345’并观测单片机变化,显示成果如图8所示:
图8 输入初始密码测试成果图
数码管上显示输入密码状态,6位密码均被用‘—’进行加密,从手机APP图上面可以看出输入密码为‘012345’,密码输入对的,数码管下方一排LED灯亮起。
(2)在手机APP命令模式中输入‘c’(在开锁状态下),设立新密码为‘321654’,此时新密码设立过程为明文在数码管上显示。然后输入‘d’对新密码进行确认。显示成果如图9所示:
图9 设立新密码
(3)进入APP键盘模式,点击’close’按钮,关闭密码锁,然后重新掉电启动密码锁,输入’012345’旧密码,显示成果如图10所示:
图10 密码更新之后输入旧密码
可见数码管右下方LED灯没有亮起,阐明输入密码错误。
(4)点击APP键盘模式里面‘retry’重新输入密码。输入密码为‘321654’显示成果如图11所示:
图11 输入新密码测试图
由成果可知输入对的新密码之后可以成功启动密码锁,而原始密码则不能。阐明密码更改成功。
4.3测试成果分析与结论
在编写程序时候,需要一定逻辑思维,同步需要有耐心同步又要细心。在编译成功后,产生以 “*.hex”和“*.bin” 后缀目的文献。
在下载程序时候,需要注意是,先要将程序下载到AT89C51中再将蓝牙与单片机用杜邦线连接起来。
从硬件测试成果可以懂得,显示功能与所写程序实现功能基本符合,基本完毕了基本无线电子密码锁设计。
5 设计体会
通过多次重复测试与分析,对电路原理及功能更加熟悉,同步提高了设计能力与及对电路分析能力。同步在软件编程方面得到更到提高,对编程能力得到加强,同步对所学知识得到很大提高与巩固。
总之,在这次课程设计过程中,我收获了诸多,不但对我后来学习有很大协助,也为将来人生之路坐了一种较好铺垫。
参照文献
[1] 黄辉先. 单片机原理及应用[M]. 湘潭:湘潭大学出版社,.
附录 程序设计
/********************************************************************
无线电子密码锁 1312203-30 刘武
*********************************************************************
与P1相连8位发光LED点亮代表锁被打开;熄灭代表锁被锁上。
程序功能: 本程序结合了24C02存储器存储功能,可以掉电保存密码。运用HC-06无线蓝牙模块与手机端蓝牙进行通信,再通过HC-06串口与51单片机进行串口通信 ,从而达到远程开关锁功能。远程距离可达5~10米(视场地空旷限度而定)
1、 开锁:启动设备,从手机端输入密码,当6位密码对的时点亮8位发光LED。 2、更改密码:只有当开锁(LED亮)后,该功能方可使用。从手机app进入实时命令模式,输入'c'(change)之后再输入想要更改密码,最后输入'd'确认密码。 3、重试密码:手机端app“键盘模式”中点击“retry”,或者进入实时命令模式输入'a',当设立密码时,设立半途想更改密码,也可按下此键重新设立。
4、关闭密码锁:手机端app"键盘模式"中点击“close”,或者进入实时命令模式下输入'b'。
注:更改密码为此密码锁高档模式,普通权限下使用是“键盘模式”。
*******************************************************************/
#include<reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar old1,old2,old3,old4,old5,old6;
uchar new1,new2,new3,new4,new5,new6; //新采集密码
uchar a=16,b=16,c=16,d=16,e=16,f=16;//送入数码管显示变量
uchar wei,key,temp,input;
bit allow,genggai,ok,wanbi,retry,close,on; //各个状态位
sbit dula=P2^6;
sbit wela=P2^7;
sbit beep=P2^3;
sbit sda=P2^0; //IO口定义
sbit scl=P2^1;
unsigned char code table[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};
/*****************IIC芯片24C02存储器驱动程序**************/
void nop()
{
_nop_();
_nop_();
}
/////////24C02读写驱动程序////////////////////
void delay1(unsigned int m)
{ unsigned int n;
for(n=0;n<m;n++);
}
void init() //24c02初始化子程序
{
scl=1;
nop();
sda=1;
nop();
}
void start() //启动I2C总线
{
sda=1;
nop();
scl=1;
nop();
sda=0;
nop();
scl=0;
nop();
}
void stop() //停止I2C总线
{
sda=0;
nop();
scl=1;
nop();
sda=1;
nop();
}
void writebyte(unsigned char j) //写一种字节
{
unsigned char i,temp;
temp=j;
for (i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
nop();
sda=CY; //temp左移时,移出值放入了CY中
nop();
scl=1; //待sda线上数据稳定后,将scl拉高
nop();
}
scl=0;
nop();
sda=1;
nop();
}
unsigned char readbyte() //读一种字节
{
unsigned char i,j,k=0;
scl=0;nop();sda=1;
for (i=0;i<8;i++)
{
nop();scl=1;nop();
if(sda==1)
j=1;
else
j=0;
k=(k<<1)|j;
scl=0;
}
nop();
return(k);
}
void clock() //I2C总线时钟
{
unsigned char i=0;
scl=1;
nop();
while((sda==1)&&(i<255))
i++;
scl=0;
nop();
}
////////从24c02地址address中读取一种字节数据/////
unsigned char read24c02(unsigned char address)
{
unsigned char i;
start();
writebyte(0xa0);
clock();
writebyte(address);
clock();
start();
writebyte(0xa1);
clock();
i=readbyte();
stop();
delay1(100);
return(i);
}
//////向24c02address地址中写入一字节数据info/////
void write24c02(unsigned char address,unsigned char info)
{
start();
writebyte(0xa0);
clock();
writebyte(address);
clock();
writebyte(info);
clock();
stop();
delay1(5000);
}
/****************密码锁程序模块*********************/
void delay(unsigned char i)
{
uchar j,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f)
{
dula=0;
P0=table[a];
dula=1;
dula=0;
wela=0;
P0=0xfe;
wela=1;
wela=0;
delay(5);
P0=table[b];
dula=1;
dula=0;
P0=0xfd;
wela=1;
wela=0;
delay(5);
P0=table[c];
dula=1;
dula=0;
P0=0xfb;
wela=1;
wela=0;
delay(5);
P0=table[d];
dula=1;
dula=0;
P0=0xf7;
wela=1;
wela=0;
delay(5);
P0=table[e];
dula=1;
dula=0;
P0=0xef;
wela=1;
wela=0;
delay(5);
P0=table[f];
dula=1;
dula=0;
P0=0xdf;
wela=1;
wela=0;
delay(5);
}
void keyscan()//输入按键扫描模块
{
if(on)
{
switch(input)
{
case '0':
key=0;
wei++;
break;
case '1':
key=1;
wei++;
break;
case '2':
key=2;
wei++;
break;
case '3':
key=3;
wei++;
break;
case '4':
key=4;
wei++;
break;
case '5':
key=5;
wei++;
break;
case '6':
key=6;
wei++;
break;
case '7':
key=7;
wei++;
break;
case '8':
key=3;
wei++;
break;
case '9':
key=3;
wei++;
break;
case 'a':
retry=1;
break;
case 'b':
close=1;
break;
case 'c':
genggai=1;
wei=0;
break;
case 'd':
if(allow)
ok=1;
break;
}
beep=0;
}
//delay(500);
beep=1;
on=0;
}
void shumima() //对按键采集来数据进行分派
{
if(!wanbi)
{
switch(wei)
{
case 1:new1=key;
if(!allow) a=17;
else a=key; break;
case 2:new2=key;
if(a==17) b=17;
else b=key; break;
case 3:new3=key;
if(a==17) c=17;
else c=key; break;
case 4:new4=key;
if(a==17) d=17;
else d=key; break;
case 5:new5=key;
if(a==17) e=17;
else e=key; break;
case 6:new6=key;
if(a==17) f=17;
else f=key;
wanbi=1; break;
}
}
}
void yanzheng() //验证密码与否对的
{
if(wanbi) //只有当六位密码均输入完毕后方进行验证
{
if((new1==old1)&(new2==old2)&(new3==old3)&(new4==old4)&(new5==old5)&(new6==old6))
allow=1; //当输入密码对的,会得到allowe置1
}
}
void serial_init()
{
SCON=0X50;
TMOD=0X20;
TH1=0XFD;
TL1=0XFD;
TR1=1;
EA=1;
ES=1;
}
void main()
{
init(); //初始化24C02
old1=read24c02(110);
old2=read24c02(111);
old3=read24c02(112);
old4=read24c02(113);
old5=read24c02(114);
old6=read24c02(115);
serial_init();//初始化串口中断
while(1)
{
keyscan();
shumima();
yanzheng();
if(allow) //验证完后,若allow为1,则开锁
{
P1=0x00;
if(!genggai)
wanbi=0;
}
if(genggai) //当更改密码键('c')被按下,genggai会被置1
{
if(allow) //若已经把锁打开,才有更改密码权限
{
while(!wanbi) //当新六位密码没有设定完则始终在这里循环
{
keyscan();
shumima();
if(retry|close) //而当探测到重试键或者关闭密码锁键被按下时,则跳出
{ wanbi=1;
break;
}
display(a,b,c,d,e,f);
}
}
}
if(ok) //更改密码时,当所有六位新密码均被按下时,可以按下此键,结束密码更改('d')
{ //其她时间按下此键无效
ok=0;wei=0;
genggai=0;
old1=new1;old2=new2;old3=new3;//此时,旧密码将被代替
old4=new4;old5=new5;old6=new6;
//新密码写入存储区。
write24c02(110,old1);
write24c02(111,old2);
write24c02(112,old3);
write24c02(113,old4);
write24c02(114,old5);
write24c02(115,old6);
a=16;b=16;c=16;d=16;e=16;f=16;
}
if(retry) //当重试按键被按下,retry会被置位
{
retry=0;wei=0;wanbi=0;
a=16;b=16;c=16;d=16;e=16;f=16;
new1=0;new2=0;new3=0;new4=0;new5=0;new6=0;
}
if(close) //当关闭密码锁按键被按下,close会被置位
{
close=0;genggai=0;//所有变量均被清零。
wei=0; wanbi=0;
allow=0;
P1=0xff;
a=16;b=16;c=16;d=16;e=16;f=16;
new1=0;new2=0;new3=0;new4=0;new5=0;new6=0;
}
display(a,b,c,d,e,f);//实时显示
}
}
void serial_interrpt(void) interrupt 4
{
if(RI==1)
{
RI=0;
input=SBUF;
on=1;//输入数据标志位
}
}
展开阅读全文