基于51单片机蓝牙密码锁

目录

一、项目需求

二、原理图

三、设计思路

 四、实物

 五、代码


资料下载地址:基于51单片机蓝牙密码锁-单片机文档类资源-CSDN下载

一、项目需求

1、采用DS1302时钟模块,通过该模块可检测当前的时间;

2、采用AT24C02芯片,存储按键输入的信息;

3、采用DS18B20温度检测模块,通过该模块可检测当前的温度;

4、采用4*4矩阵键盘,按键主要功能有一键关门、显示时间、重新设置密码、取消键、确认键、输入密码;

二、原理图

 

三、设计思路

本设计以STC89C52单片机为核心控制器,加上其他的模块一起组成蓝牙密码锁的整个系统,其中包含中控部分、输入部分和输出部分。中控部分采用了STC89C52单片机,其主要作用是获取输入部分数据,经过内部处理,控制输出部分。输入由五部分组成,第一部分是DS1302时钟模块,通过该模块可检测当前的时间;第二部分是储存模块,采用AT24C02芯片,存储按键输入的信息;第三部分是DS18B20温度检测模块,通过该模块可检测当前的温度;第四部分是4*4矩阵键盘,按键主要功能有一键关门、显示时间、重新设置密码、取消键、确认键、输入密码;第五部分是供电电路,给整个系统进行供电。输出由三部分组成,第一部分是LCD1602显示模块, 通过该模块可以显示门的开关状态、输入的密码显示、重置密码时的显示等;第二部分是蓝牙模块,通过该模块可连接手机;第三部分是蜂鸣器,当键盘锁定且有按键按下时,蜂鸣器作为按键音提醒。

 四、实物

 五、代码

主程序代码


#include "main.h"
#include "lcd1602.h"
#include "key.h"
#include "IIC.h"
#include "ds18b20.h"
#include "ds1302.h"
#include "uart.h"
/**********************************
变量定义
**********************************/
extern char time_buf[8];
extern uchar uart_num;
uint temp_value;
uint randdata;
uint randdata1;
uchar TimeOutCounter = 0;
uchar LeftOrRight = 0;
uchar key_bianma = 0;													//按键编码标志位变量
uchar key_num = 0;														//按键扫描标志位变量
uchar flag_key_en = 1;												//按键使能标志位变量
uchar flag_reset_password = 0;								//重置密码标志位变量
uchar flag_reset_adminpassword = 0;
uchar flag_stat_door = 0;                     //门状态标志位
uchar flag_reset_password_num = 0;						//重置密码次数标志位变量
uchar flag_error_num = 0;											//密码错误次数标志位变量
uchar flag_error_time = 180;									//密码错误时间标志位变量
uchar password[6] = {1,2,3,4,5,6};						//初始密码数组
uchar adminpassword[6] = {1,2,3,4,5,6};				//初始管理员密码数组
uchar password_input[6] = {0,0,0,0,0,0};			//输入密码数组
uchar password_reset[6] = {0,0,0,0,0,0};			//重置密码数组
uchar password_num = 0;												//密码数量标志位变量
uint time_jishi = 0;													//10ms计时变量


/**********************************
函数声明
**********************************/
void Delay_function(uint x);									//延时函数
void Key_function(void);											//按键函数
void Ensure_function(void);										//确定函数
void Reset_password_function(void);						//重置密码函数
void Write_init_EEPROM();
void Timer0Init();
/****
*******	主函数 
*****/
void main()
{

	Timer0Init();
	Uart_Init();
	Ds1302_Init();
	Lcd1602_Init();		 													//LCD1602初始化
	Delay_function(50);													//延时50ms
	lcd1602_clean();														//清屏
	Delay_function(50);													//延时50ms
	Init_IIC();                                 //总线初始化,拉高释放总线
	Delay_function(50);													//延时50ms
	//写过一次后关闭,无需重复写初值
//	Write_init_EEPROM();                      //写入初始密码123456到E2PROM
//	ds1302_write_time();
	lcd1602_display_str(1,0,"===Coded Lock===");//初始化界面
	lcd1602_display_str(2,0,"Password:");
	while(1)
	{
		//将密码从24C02中读出来,包括管理员密码以及使用密码
		password[0]=read_add(1);
		password[1]=read_add(2);
		password[2]=read_add(3);
		password[3]=read_add(4);
		password[4]=read_add(5);
		password[5]=read_add(6);
		adminpassword[0]=read_add(7);
		adminpassword[1]=read_add(8);
		adminpassword[2]=read_add(9);
		adminpassword[3]=read_add(10);
		adminpassword[4]=read_add(11);
		adminpassword[5]=read_add(12);
		Key_function();							   //按键函数
		Reset_password_function();	   //重置密码函数
		//输入密码三次错误后执行如下程序
		if(flag_error_num == 3)
		{
			flag_key_en = 0;
			if(time_jishi % 40 == 0)
			{
				flag_error_time--;
			}
			lcd1602_display_str(1,0,"===Coded Lock===");
			lcd1602_display_time(2,0,flag_error_time);
			
			if(flag_error_time == 0)
			{
				flag_key_en = 1;
				flag_error_time = 180;
				flag_error_num = 0;
				lcd1602_display_str(2,0,"Password:       ");
			}
		}
		if(time_jishi % 50 == 0)											//500ms检测一次
		{
			ds1302_read_time();
			temp_value = Ds18b20_Read_Temp();
			randdata=rand()%(9999-1000+1)+1000;       //获得1000~9999之间的随机数,函数rand()在stdlib.h
			randdata1=rand()%(55-33+1)+10;
		}
		
		if(uart_num == 1)//一键关门
		{
			lcd1602_display_str(1,0,"===Coded Lock===");
			lcd1602_display_str(2,0,"   Door Close   ");
			LeftOrRight = Stop;
			RELAY = 1;
			LED = 1;
			Delay_function(1000);
			lcd1602_display_str(2,0,"Password:       ");
			flag_stat_door = 0;
			uart_num=0;
		}
		if(uart_num == 2)
		{
			lcd1602_display_str(1,0,"===Coded Lock===");
			lcd1602_display_str(2,0,"   Door Open    ");
			LeftOrRight = Left;
			RELAY = 0;
			LED = 0;
			flag_error_num = 0;
			memset(password_input,0,6);
			Delay_function(1000);
			lcd1602_display_str(1,0,"==Lock : open===");
			lcd1602_display_str(2,0,"                ");
			flag_stat_door = 1;
			uart_num=0;
		}
		if(uart_num == 3)
		{
			
			password[0]=randdata/1000%10;
			password[1]=randdata/100%10;
			password[2]=randdata/10%10;
			password[3]=randdata/1%10;
			password[4]=randdata1/10%10;
			password[5]=randdata1/1%10;
			write_add(1,password[0]); 
			Delay_function(5);
			write_add(2,password[1]); 
			Delay_function(5);
			write_add(3,password[2]);
			Delay_function(5);			
			write_add(4,password[3]);
			Delay_function(5);
			write_add(5,password[4]);
			Delay_function(5);			
			write_add(6,password[5]); 
			Delay_function(5);
			Uart_Sent_Char(read_add(1)+'0');
			Uart_Sent_Char(read_add(2)+'0');
			Uart_Sent_Char(read_add(3)+'0');
			Uart_Sent_Char(read_add(4)+'0');
			Uart_Sent_Char(read_add(5)+'0');
			Uart_Sent_Char(read_add(6)+'0');
			uart_num=0;
		}
		Delay_function(10);					//延时10ms
		time_jishi++;								//计时变量+1
		if(time_jishi == 5000)
		{
			time_jishi = 0;
		}
	}
}

/****
*******	延时函数
*****/
void Delay_function(uint x)
{
	uint m,n;
	for(m=x;m>0;m--)
	for(n=110;n>0;n--);
}
/****************************
******初始向EEPROM写数据*****
******************************/
void Write_init_EEPROM()
{
	//写入初始密码123456到E2PROM
	write_add(1,password[0]);   
	Delay_function(5);
	write_add(2,password[1]);
	Delay_function(5);
	write_add(3,password[2]);
	Delay_function(5);
	write_add(4,password[3]);
	Delay_function(5);
	write_add(5,password[4]);   
	Delay_function(5);
	write_add(6,password[5]);
	Delay_function(5);
	//写入初始管理员密码123456到E2PROM
	write_add(7,adminpassword[0]);   
	Delay_function(5);
	write_add(8,adminpassword[1]);
	Delay_function(5);
	write_add(9,adminpassword[2]);
	Delay_function(5);
	write_add(10,adminpassword[3]);
	Delay_function(5);
	write_add(11,adminpassword[4]);   
	Delay_function(5);
	write_add(12,adminpassword[5]);
	Delay_function(5);
}
/****
*******按键函数
*****/
void Key_function(void)
{
	uchar i;
	key_bianma = matrix_keyboard_scan();							//读按键的位置码
	if(key_bianma != 0)								                //当有按键按下时
	{
		if(flag_key_en == 0)					                  //按键使能标志为0时,锁3分钟
		{
			BEEP = 0;
			Delay_function(50);
			BEEP = 1;
		}
		else								//没有锁定键盘时
		{
			key_num = matrix_keyboard_coding(key_bianma);				//根据按键的位置将其编码,编码值赋值给NUM
			{
				switch(key_num)					//判断按键值
				{
					case ('C'):		//无作用
//						flag_reset_adminpassword = 1;
					break;

					case ('A'):		//一键关门
						lcd1602_display_str(1,0,"===Coded Lock===");
						lcd1602_display_str(2,0,"   Door Close   ");
						LeftOrRight = Stop;
						RELAY = 1;
						LED = 1;
						Delay_function(1000);
						lcd1602_display_str(2,0,"Password:       ");
						flag_stat_door = 0;
					break;

					
					case ('B'):		//显示时间
						lcd1602_clean();		
						lcd_display_alltime(time_buf); 	
						lcd1602_display_temp(2,10,temp_value);
						
						Delay_function(1000);
						lcd1602_display_str(1,0,"===Coded Lock===");
						lcd1602_display_str(2,0,"Password:       ");
					break;

					
					case ('D'):   //重新设置密码
						flag_reset_password = 1;
						lcd1602_clean();
					break;

					
					case ('*'):   //取消键
						if(password_num != 0)
						{
							password_num--;
							lcd1602_display_char(2,9+password_num,' ');
						}
					break;

					
					case ('#'):   //确认键
						if(flag_reset_password_num >= 1)
							flag_reset_password_num++;
						Ensure_function();
					break;

					default: 										//如果不是功能键按下时,就是数字键按下
						lcd1602_display_str(1,0,"                ");
						lcd1602_display_str(2,0,"                ");
						if(flag_reset_password == 0)
						{
							lcd1602_display_str(1,0,"===Coded Lock===");
							lcd1602_display_str(2,0,"Password:       ");
						}

						if(password_num < 6)                   					//当输入的密码少于6位时,接受输入并保存,大于6位时则无效。
						{
							for(i = 0;i < password_num+1;i++)
								lcd1602_display_char(2,9+i,'*');
							if(flag_reset_password == 0  || flag_reset_password_num == 1 || flag_reset_password_num == 0)
								password_input[password_num++] = key_num;			//将数字键的码赋值给password_input[]数组暂存
							else if(flag_reset_password_num == 2)
								password_reset[password_num++] = key_num;			//将数字键的码赋值给password_reset[]数组暂存
						}
						else										//输入数据位数大于6后,忽略输入
						{
							password_num = 6;
							lcd1602_display_str(2,9,"******");
						}
							
					break;
				}
			}
		}
	}
}

/****
*******确认函数
*****/
void Ensure_function(void)
{
	lcd1602_display_str(1,0,"                ");
	lcd1602_display_str(2,0,"                ");
  //不在设置密码时,并且门是关着在执行如下函数
	if(flag_reset_password == 0 && flag_stat_door == 0)
	{
		//键入密码进行比对将输入密码与存储的密码对比,正确则开门
		if((password[0] == password_input[0]) && (password[1] == password_input[1]) && 
			 (password[2] == password_input[2]) && (password[3] == password_input[3]) && 
			 (password[4] == password_input[4]) && (password[5] == password_input[5]))
		{	
			lcd1602_display_str(1,0,"===Coded Lock===");
			lcd1602_display_str(2,0,"   Door Open    ");
			LeftOrRight = Left;
			RELAY = 0;
			LED = 0;
			flag_error_num = 0;
			memset(password_input,0,6);
			Delay_function(1000);
			lcd1602_display_str(2,0,"Password:       ");
			flag_stat_door = 1;
		}
		//键入密码进行比对将输入密码与存储的密码对比,错误则不开门,显示密码错误。
		else
		{
			lcd1602_display_str(1,0,"===Coded Lock===");
			lcd1602_display_str(2,0," password error ");
			memset(password_input,0,6);
			flag_error_num++;
			Delay_function(1000);
			lcd1602_display_str(2,0,"Password:       ");
		}
	}
	//不在设置密码时,并且门是开着在执行如下函数
	if(flag_reset_password == 0 && flag_stat_door == 1)
	{
		lcd1602_display_str(1,0,"==Lock : open===");
		lcd1602_display_str(2,0,"                ");
	}
	//当设置密码时执行如下程序
	 if((flag_reset_password == 1 && flag_reset_password_num == 0))
	 {
		 //对比管理员密码与输入密码
		if((adminpassword[0] == password_input[0]) && (adminpassword[1] == password_input[1]) && 
			 (adminpassword[2] == password_input[2]) && (adminpassword[3] == password_input[3]) && 
			 (adminpassword[4] == password_input[4]) && (adminpassword[5] == password_input[5]))
		{

			if(flag_reset_password)
				flag_reset_password_num++;
		}
		else
		{
			lcd1602_display_str(1,0,"===Coded Lock===");
			lcd1602_display_str(2,0," password error ");
			memset(password_input,0,6);
			flag_error_num++;
			Delay_function(1000);
			lcd1602_display_str(2,0,"Password:       ");
		}
	 }
	password_num = 0;
}

/****
*******重置密码函数
*****/
void Reset_password_function(void)
{
	uchar i;
	if(flag_reset_password == 1 && flag_reset_password_num == 0)
	{
		lcd1602_display_str(1,0,"=Reset Password=");
		lcd1602_display_str(2,0,"adm_Pswd:");
	}

	if(flag_reset_password_num == 1)
	{
		lcd1602_display_str(1,0,"=Reset Password=");
		lcd1602_display_str(2,0,"New_Pswd:");
	}
	
	if(flag_reset_password_num == 2)
	{
		lcd1602_display_str(1,0,"=Reset Password=");
		lcd1602_display_str(2,0,"Ned_Pswd:");
	}
	
	if(flag_reset_password_num == 3)
	{
		//对比两次输入的密码
		if((password_input[0] == password_reset[0]) && (password_input[1] == password_reset[1]) && 
		   (password_input[2] == password_reset[2]) && (password_input[3] == password_reset[3]) && 
			 (password_input[4] == password_reset[4]) && (password_input[5] == password_reset[5]))
		{
			for(i=0;i<6;i++)
			{
				password[i] = password_reset[i];
				//写入更改后密码密码到E2PROM
				write_add(i+1,password[i]);   
				Delay_function(5);
			}
			lcd1602_display_str(1,0,"=Reset Password=");
			lcd1602_display_str(2,0,"    reset ok    ");
			Delay_function(1000);
			lcd1602_display_str(1,0,"===Coded Lock===");
			lcd1602_display_str(2,0,"Password:       ");
			flag_reset_password = 0;
			flag_reset_password_num = 0;
		}
		else
		{
			lcd1602_display_str(1,0,"=Reset Password=");
			lcd1602_display_str(2,0,"   reset fail   ");
			Delay_function(1000);
			lcd1602_display_str(1,0,"===Coded Lock===");
			lcd1602_display_str(2,0,"Password:       ");
			flag_reset_password = 0;
			flag_reset_password_num = 0;
		}
	}
}


/****
*******定时器1初使化函数
*****/
void Timer0Init()
{
	TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。

	TL0 = 0xAE;		//设置定时初值
	TH0 = 0xFB;		//设置定时初值
	ET0=1;//打开定时器0中断允许
	EA=1;//打开总中断
	TR0=1;//打开定时器			
}

void Time0(void) interrupt 1    //3:为定时器1的中断号;  1:定时器0的中断号; 0:外部中断1的中断号; 2 外部中断2的中断号; 4 串口中断的中断号;
{ 
	TL0 = 0xAE;		//设置定时初值
	TH0 = 0xFB;		//设置定时初值
	TimeOutCounter ++;
	switch ( LeftOrRight )
	{
		case 0 :          //为0时,舵机归位,脉宽1.5ms
		{
			if( TimeOutCounter <= 2 )
			{
				ControlPort = 1;
			}
			else
			{
				ControlPort = 0;
			}
		break;
		}
		case 1 :     //为1时,舵机左转,脉宽1ms(理论值),实际可以调试得出
		{
			if( TimeOutCounter <= 1 )
			{
				ControlPort = 1;
			}
			else
			{
				ControlPort = 0;
			}
			break;
		}
		default : break;
	}
	if( TimeOutCounter == 30 )         //周期20ms(理论值)
	{
		TimeOutCounter = 0;
	}
}

六、资料清单

 

  • 0
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

森旺电子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值