功能描述

1、采用51/52单片机(通用)作为主控芯片;
2、采用1602液晶显示使用过程及状态,液晶屏亮度会随光线自动调整;
3、按键输入6位密码,输入密码正确则锁打开,显示open!输入密码错误次数超过3次,蜂鸣器报警并且锁定键盘;
4、密码可以自己修改,必须是锁打开时才能改密,为防止误操作,修改密码得输入两次;
5、采用24C02保存密码,掉电不丢失;
6、可通过手机蓝牙软件输入密码操作锁的状态;

电路设计

采用Altium Designer作为电路设计工具。Altium Designer通过把原理图设计、PCB绘制编辑、拓扑逻辑自动布线、信号完整性分析和设计输出等技术的完美融合,为设计者提供了全新的设计解决方案,使设计者可以轻松进行设计,熟练使用这一软件必将使电路设计的质量和效率大大提高。

基于单片机的蓝牙密码锁系统设计(#0532)_上拉电阻

单片机管脚说明:

P0端口(P0.0-P0.7):P0口为一个8位漏极开路双向I/O口,每个引脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。

P1端口(P1.0-P1.7):P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高电平,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。

P2端口(P2.0-P2.7):P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口,用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。

P3端口(P3.0-P3.7):P3口管脚是一个带有内部上拉电阻的8位的双向I/O端口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入端时,由于外部下拉为低电平,P3口将输出电流(ILL)。P3口同时为闪烁编程和编程校验接收一些控制信号。

仿真设计

采用Proteus作为仿真设计工具。Proteus是一款著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。

基于单片机的蓝牙密码锁系统设计(#0532)_嵌入式硬件_02

主程序设计

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;				//打开定时器
		}
			
   	}
}

源文件获取

关注公众号-电子开发圈,首页发送 “密码锁” 获取;