单片机项目:基于单片机的蓝牙无线密码锁设计

主要介绍

  在基于单片机的蓝牙无线密码锁设计中,将蓝牙技术作为本次设计的核心内容,通过运用STC89C52单片机,加上LCD液晶显示器模块,以及多种类的相关零件,可以提供多种较为便利的设定,成功帮助用户解决开锁以及闭锁等诸多方面的内容,且将整个过程科学合理化,最大程度地保障人们的安全。
经实验验证,相比于传统机械锁,蓝牙无线密码锁具有安全便捷成本低等优点,可普遍应用于家庭、宾馆、办公大楼、银行等地方。这样安全便捷的开锁方式给人们的日常生活和工作提供了保障,保护了人员和财产的安全,大大提高了安全系数。

关键词:单片机;蓝牙模块;LCD1602;密码锁

一、系统总体设计

  为了实现远程开锁,保护人们财产和信息安全,本文设计了一个具有报警、远程控制、修改密码、虚假密码等功能于一体的基于单片机的蓝牙无线密码锁系统,以此来对锁的安全性进行改善。

1.1 系统设计要求

(1)采用AT24C02芯片,用于储存设置的密码,并具有掉电之后保存密码功能;
(2)用户可以自行设定对应的密码,想要更换成新密码,必须要重新输入原有密码两次才可以通过系统的审核;
(3)密码输入错误3次,蜂鸣器响,报警锁死,屏幕显示ERROR;
(4)输入正确的密码继电器吸合,开锁指示灯亮,屏幕显示OPEN;
(5) 4×4矩阵键盘包括0~9的数字键和A~D的功能键以及*、#按键;
(6)液晶屏幕采用了新型的光学感应系统,能够成功地对应天气进行相应的屏幕转变,从而最大程度的节约电能;
(7)可以使用虚假密码,开锁时可以随意输入虚假密码掩人耳目,防止他人窃取密码;
(8)采用蓝牙模块,可以实现远程开锁。

1.2 系统设计思路

在总体方案的选定上,最初考虑了两种方案,一种是利用数字电路来实现密码锁的功能,配合其他主控芯片,结合蓝牙模块来实现预期的功能,另一种是使用单片机作为主控芯片[4],利用其可编程性,来实现密码锁功能,同时兼顾了蓝牙模块的使用。
方案一:用数字电路控制系统
运用触发器构成的数字逻辑电路作为密码锁的核心控制,当用户想要避免自己的信息泄露时,只需要按下对应的干扰按键,就能够成功的终止当前的密码输入行为,而且如果该用户在进行密码输入时,使用了过长的时间那么系统会判定此次输入无效并发出警报,通过这种方式能够使整个系统的操作较为便捷,易操作,缺点就是灵活性太差,容易给用户带来不必要的麻烦,并且在加入蓝牙模块时,还要额外加入主控芯片,实行起来复杂且成本高,使用效果也不是很好。因此,这种方案没有得到实际的应用。
方案二:用单片机控制系统
运用单片机作为主要控制系统,单片机是一种虽然小但很完整的芯片,应用在集成电路中,也可以称之为微型计算机系统。它很稳定并且能够对接收的数据进行实时反应,常运用在工业环境中。再外接液晶显示器、蓝牙模块、矩阵键盘、存储芯片等器件,单片机通过I/O口控制外接设备。用户可以有两种方式输入密码,可以使用矩阵键盘输入密码也可以使用蓝牙APP输入密码。如果成功的输入正确的密码,继电器就会吸合,开锁指示灯亮,屏幕会显示为打开状态。如果并没有输入正确的密码,那么蜂鸣器会发出对应的警报。如果输入三次错误内容,那么蜂器将会一直保持警报状态,整个体统进入锁死状态。
通过两种方案相比较,方案二比较好。其最大的优点就是灵活度高、性能高、价格低廉,所以本设计采用单片机控制系统的方案。

二、系统硬件设计

2.1 设计原理

本设计的主要硬件由单片机[5]、显示模块、驱动模块等硬件组成。在整个系统运转时,单片机会依照用户实际输入的对应内容,在此过程中,单片机判断用户输入密码的正确性。如果成功的输入正确的密码,继电器就会吸合,开锁指示灯亮,屏幕会显示为打开状态。如果并没有输入正确的密码,那么蜂鸣器会发出对应的警报。如果多次回答错误内容,系统会根据这一情况,判定为他人盗用,整个体统进入锁死状态。蓝牙无线密码锁硬件原理框图如图2.1所示。

在这里插入图片描述

图2.1 蓝牙无线密码锁硬件原理框图

2.2 主控模块

单片机在本次毕业设计中起到了至关重要的角色,它是整个设计方案的核心。本项目拟采用单片机作为主要控制系统,拟采用STC89C52单片机和STM32单片机,两种单片机对比如下所示。
方案一:STC89C52单片机
STC89C52单片机拥有着诸多方面的优点,例如运转速度极快,而且对能源的需求不高,可以有效抵抗外部的干扰等诸多方面,而且其指令代码能够与传统的五一单片机进行很好的衔接。STC89C52单片机内部存在完整操作处理器,处理的对象单位并非字或者字节,而是位。采用51Core内核,拥有64KB空间。同时由于自带的双地址区间,使得STC89C52单片机使用方式更加多样化。
方案二:STM32单片机
STM32单片机主要服务于Cortex-M内核,含有1μs的双12位ADC,4兆位/秒的UART,18兆位/秒的SPI等等,但由于性能优异,使用起来比STC89C52单片机复杂的多,因此本次设计不准备使用STM32单片机。
通过两种方案相比较,方案一比较好。其要求低、功能齐全,在较小的范围内可以实现全方面的功能,所以本设计选择STC89C52单片机作为主控芯片。
STC89C52单片机在进入工作后能够一直保持稳定的工作状态,对于电压的需求需要在5.5V到2.0V之间,进入工作状态后,它的工作频率始终保持在48Hz以下,对于STC89C52单片机而言,它拥有以下几个特征:首先它拥有着把给自己的内部程序储存空间,其次它拥有着三个定时器帮助其工作,最后它拥有着较强的抗干扰性,能够成功地显示当前的工作状态。STC89C52单片机原理图如图2.2所示。
在这里插入图片描述

图2.2 STC89C52单片机原理图

本设计运用最少的零部件组成的单片机可以工作的系统,可以被称为最小系统[6]。对于STC89C52单片机而言,最小系统必须要拥有单片机、晶振电路、复位电路。晶振电路和复位电路是单片机运行的必要条件,并且能使单片机一直处于正常工作状态。通常情况下,最小系统往往是整个系统中最重要的部分。通过对其进行相应的操作以及改善,能够帮助我们完成许多复杂的工作。单片机最小系统原理图如图2.3所示。
在这里插入图片描述

图2.3 单片机最小系统原理图

三、系统软件设计

3.3 程序流程图

本次设计的总体软件较为简单,主要分为主程序和子程序以及对密码进行相关设定的程序。首先,初始化每个模块,检测是否有按键按下,如果按下,确定哪个按键被按下,然后判断是否调用相应的子程序。主程序流程图如图3.2所示。
在这里插入图片描述

图3.2 主程序流程图

实物

在这里插入图片描述

原理图

在这里插入图片描述
在这里插入图片描述

程序

//包含头文件
#include <REG52.h>
#include<intrins.h>
//宏定义
#define LCM_Data  P0		  //将P0口定义为LCM_Data
#define uchar unsigned char 
#define uint  unsigned int
#define w 6				//定义密码位数
//1602的控制脚

sbit lcd1602_rs=P2^5;
sbit lcd1602_rw=P2^6;
sbit lcd1602_en=P2^7;

sbit Scl=P3^4;			//24C02串行时钟
sbit Sda=P3^5;			//24C02串行数据

sbit ALAM = P2^1;		//报警	
sbit KEY = P3^6;		//开锁
 

bit  operation=0;		//操作标志位
bit  pass=0;			//密码正确标志
bit  ReInputEn=0;		//重置输入允许标志	
bit  s3_keydown=0;		//3秒按键标志位
bit  key_disable=0;		//锁定键盘标志
bit  flag_REC =0;       //串口接受标志位
unsigned char buff[5]=0;
unsigned char countt0,second;	//t0中断计数器,秒计数器

void Delay5Ms(void);		//声明延时函数

unsigned char code a[]={0xFE,0xFD,0xFB,0xF7}; 				//控盘扫描控制表
//液晶显示数据数组
unsigned char code start_line[]	= {"password:       "};
unsigned char code name[] 	 	= { "===Coded Lock==="};	//显示名称
unsigned char code Correct[] 	= {"     correct    "};		//输入正确
unsigned char code Error[]   	= {"      error     "};  	//输入错误
unsigned char code codepass[]	= {"      pass      "}; 
unsigned char code LockOpen[]	= {"      open      "};		//OPEN
unsigned char code SetNew[] 	= {"SetNewWordEnable"};
unsigned char code Input[]   	= {"input:          "};		//INPUT
unsigned char code ResetOK[] 	= {"ResetPasswordOK "};
unsigned char code initword[]	= {"Init password..."};
unsigned char code Er_try[]		= {"error,try again!"};
unsigned char code again[]		= {"input again     "};

unsigned char InputData[16];									//输入密码暂存区
unsigned char CurrentPassword[16]={1,3,1,4,2,0}; 			//管理员密码(只可在程序中修改)
unsigned char TempPassword[16];
unsigned char N=0,M=0,flag=0;				//密码输入位数记数
unsigned char ErrorCont;			//错误次数计数
unsigned char CorrectCont;			//正确输入计数
unsigned char ReInputCont; 			//重新输入计数
unsigned char code initpassword[16]={0,0,0,0,0,0};			//输入管理员密码后将密码初始为000000
unsigned char  MM[2]={0,0};

//=====================5ms延时==============================
void Delay5Ms(void)
{
	unsigned int TempCyc = 5552;
	while(TempCyc--);
}

//===================400ms延时==============================
void Delay400Ms(void)
{
 unsigned char TempCycA = 5;
 unsigned int TempCycB;
 while(TempCycA--)
 {
  TempCycB=7269;
  while(TempCycB--);
 }
}

//==============================主函数===============================
void main(void)
{
 	unsigned char KEY,NUM;
	unsigned char i,j;
 	P1=0xFF; 				   //P1口复位
	TMOD=0x12;				   //定义工作方式
 	TH0=0xB0;
 	TL0=0x3C;				   //定时器赋初值
 	EA=1;					   //打开中断总开关
 	ET0=1;					   //打开中断允许开关
 	TR0=0;					   //打开定时器开关
	TH1=0Xfd;
	TL1=0Xfd;	    //9600
	TR1=1; 		    // 定时器1启动  
	SM0=1;	    // 设置串口的工作模式
	SM1=1; 	    //方式1
	REN=1; 		 // 允许串口接收数据 	 
	ES=1; 	     // 串口中断应许 
 	
 	Delay400Ms(); 	//启动等待,等LCM讲入工作状态
 	lcd_init(); 	//LCD初始化
	write_1602com(yi);//日历显示固定符号从第一行第0个位置之后开始显示
	for(i=0;i<16;i++)
	{
		write_1602dat(name[i]);//向液晶屏写开机画面
	}
	write_1602com(er);
	for(i=0;i<16;i++)
	{
		write_1602dat(start_line[i]);//写输入密码等待界面
	}
	write_1602com(er+9);	//设置光标位置
	write_1602com(0x0f);	//设置光标为闪烁
 	Delay5Ms(); //延时片刻(可不要)

 	N=0;														//初始化数据输入位数
	RdFromROM(MM,17,1);
	M=MM[0];
		if(M==0||M>16)
	{
	 M=6;
	 MM[0]=6;
	 WrToROM(MM,17,1);
	}
 	while(1)		 //进入循环
 	{
		if(key_disable==1)						//锁定键盘标志为1时
			Alam_KeyUnable();					//报警键盘锁
		else
			ALAM=1;								//关报警

		KEY=keynum();							//读按键的位置码
		if(KEY!=0)								//当有按键按下时
		{	
			if(key_disable==1)					//锁定键盘标志为1时
			{
				second=0;						//秒清零
			}
			else								//没有锁定键盘时
			{
				NUM=coding(KEY);				//根据按键的位置将其编码,编码值赋值给NUM
				{
					switch(NUM)					//判断按键值
					{
						case ('A'): 	; 					break;
						case ('B'):		;     				break;
						case ('C'): 
								write_1602com(yi);//日历显示固定符号从第一行第0个位置之后开始显示
								for(i=0;i<16;i++)
								{
									write_1602dat(name[i]);//向液晶屏写开机画面
								}
						       if(N>=1) N--;	OneAlam();								//按键提示音						
								//DisplayOneChar(6+N,1,'*');
							   for(j=N;j<16;j++)
							  {
							  write_1602com(er+j);
							       write_1602dat(' ');
							  }
						 	  for(j=0;j<N;j++)
							  {
									write_1602com(er+j);				//显示位数随输入增加而增加
									write_1602dat('*');					//但不显示实际数字,用*代替
								}  
									InputData[N]=N+6;
											break;		//ABC是无定义按键
						case ('D'): ResetPassword();		break;      //重新设置密码
						case ('*'): Cancel();				break;      //取消当前输入
						case ('#'): Ensure(); 				break;   	//确认键,
						default: 										//如果不是功能键按下时,就是数字键按下
						{	
							//DisplayListChar(0,1,Input);
							write_1602com(yi);
							for(i=0;i<16;i++)
							{
								write_1602dat(Input[i]);				//显示输入画面
							}
						    operation=0;								//操作标志清零
							if(N<16)                   					//当输入的密码少于6位时,接受输入并保存,大于6位时则无效。
							{  
								OneAlam();								//按键提示音						
								//DisplayOneChar(6+N,1,'*');
						 		for(j=0;j<16;j++)
								{
								    if(j>N)
									{
									  write_1602com(er+j);
									  write_1602dat(' ');
									}
								    if(j<=N)
									{
									write_1602com(er+j);				//显示位数随输入增加而增加
									write_1602dat('*');					//但不显示实际数字,用*代替	  
									}
								}
								InputData[N]=NUM;						//将数字键的码赋值给InputData[]数组暂存
								N++;									//密码位数加
							}
							else										//输入数据位数大于6后,忽略输入
							{
								N=16;									//密码输入大于6位时,不接受输入
						 		break;
							}
							write_1602com(er+N);
							if(ReInputEn==1&&ReInputCont==0)
							M=N;
						}
					}
				}
			}
	 	} 
	}
}

//***************************中断服务函数**************************************
void  time0_int(void) interrupt 1 		   //定时器T0
{
 	TH0=0xB0;
 	TL0=0x3C;		  //定时器重新赋初值
 	//TR0=1;
 	countt0++;			   //计时变量加,加1次时50ms
  	if(countt0==20)		   //加到20次就是1s
   	{
		countt0=0;		   //变量清零
		second++;		   //秒加
		if(pass==1)		   //开锁状态时
		{
			if(second==1)			//秒加到1s时
			{
			 
				TR0=0;				//关定时器
				TH0=0xB0;
 				TL0=0x3C;			//再次赋初值
				second=0;			//秒清零
			}
		}
		else						//不在开锁状态时
		{
			if(second==3)			//秒加到3时
			{
				TR0=0;				//关闭定时器
				second=0;			//秒清零
				key_disable=0;		//锁定键盘清零
				s3_keydown=0;	
				TH0=0xB0;
				TL0=0x3C;			//重新赋初值
			}
			else
			    TR0=1;				//打开定时器
		}
			
   	}
}

//  通讯中断接收程序   中断函数无返回值
  void uart_rx(void)  interrupt 4	using 3	  //放在这里 和放在main()里面是一样的
 {

   	unsigned char i;
	unsigned char flag;
	unsigned char dat;
    if(RI)	                 //是否接收中断
    {
       RI=0;
       dat=SBUF;
       if(dat=='O'&&(i==0)) //接收数据第一帧
       {
            buff[i]=dat;
            flag=1;        //开始接收数据
       }
       else
	      if(flag==1)
	      {
		      i++;
		      buff[i]=dat;
		      if(i>=2)
	          {
			   i=0;
			   flag=0;
			   flag_REC=1 ;
		      }  // 停止接收
	      }
	 }

 }

总结

  本次设计用单片机STC89C52作为主控芯片,再外接液晶显示器LCD1602、蓝牙模块、矩阵键盘、存储芯片AT24C02等器件,研制了一款具有蓝牙无线功能的电子密码锁。在单片机的选择上,本次设计选择了STC89C52单片机,相较于其他的单片机来说该单片机具有高性能、低功耗、超强抗干扰等优点,使系统的安全性更强,可在长期的使用中减少成本,提高推广性。
对设备进行相关的调试之后,最终实现了蓝牙无线远程开锁的功能。蓝牙无线密码锁的出现,为人们的日常生活提供了便捷和安全的保障,让越来越多的现代人感到技术的重要性。任何新技术或新产品的推出都不是一步之遥,只有不断的技术进步和改进,才能以完美的形式向全世界展示。蓝牙无线密码锁是继电子产品和家用产品在技术上相结合之后产生的密码锁行业的一项科技成就。

目录

目 录
摘 要 Ⅰ
Abstract Ⅱ
引 言 1
1 系统总体设计 3
1.1 系统设计要求 3
1.2 系统设计思路 3
2 系统硬件设计 5
2.1 设计原理 5
2.2 主控模块 5
2.3 芯片模块 8
2.4 矩阵键盘模块 9
2.5 液晶显示模块 10
2.6 继电器驱动模块 12
2.7 蜂鸣器模块 13
2.8 蓝牙模块 14
3 系统软件设计 16
3.1 软件设计开发环境 16
3.2 编程语言选择 16
3.3 程序流程图 17
4 系统调试 20
4.1 硬件调试 20
4.2 软件调试 20
4.3 问题及解决方法 21
结 论 23
参考文献 24
附录1 硬件原理图 26
附录2 源程序清单 27
致 谢 34

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值