基于51单片机的语音控制GSM短信报警密码锁proteus仿真原理图PCB

功能介绍:
0.本系统采用STC89C52作为单片机
1.输入密码正确,屏幕提示OK;输入密码错误,蜂鸣器LED声光报警
2.连续三次输入密码错误,屏幕提示LOCK锁住,并通过GSM发送报警短信
3.设置密码,首先按B关锁,然后按A进入设置
屏幕提示OLD,输入旧密码,屏幕提示NEW,输入新密码
4.采用DC002作为电源接口可直接输入5V给整个系统供电

原理图:
在这里插入图片描述
在这里插入图片描述

PCB:
在这里插入图片描述

主程序:

#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include "lcd1602.h"
#include "at24c02.h"
#include <stdio.h>

#define ON 0
#define OFF 1

sbit RELAY = P1 ^ 2;	 //继电器控制引脚
sbit BUZZER = P3 ^ 7;	 //蜂鸣器控制引脚
sbit VOICE_PIN = P1 ^ 3; //语音模块IO引脚
sbit GMS_EN = P3 ^ 2;	 // GSM模块使能引脚

#define KEY_PORT P2 // 4X4矩阵键盘输入
unsigned char isNew;
unsigned char keyValue;								 //用来存放读取到的键值
unsigned char saved_Value[4] = {'0', '0', '0', '0'}; //初始密码
unsigned char input_Value[4];
unsigned char errorFlag = 0;
unsigned char setFlag = 0, lockFlag = 0;
unsigned char errorCnt = 0;
unsigned int delayBuzzer, delayTime;
bit rekey = 0;
bit refreshFlag = 0;

void TimerConfiguration(void); //定时中断
unsigned char KeyDown(void);   //检测按键函数
void KeyProsess(void);
void UART_Init(void);
void UartSendByte(unsigned char dat);
void UartSendStr(unsigned char *s, unsigned char length);

//====主函数入口======
void main()
{

	EEPROM_Init();
	LCD_Init(); //液晶初始化
	LCD_Clear();

	TimerConfiguration(); //初始化定时器
	DelayMs(200);		  //延时有助于稳定

	UART_Init();
	UartSendStr("AT+CMGF=1\r\n", 11); //配置GSM
									  // DelayS(5);

	LCD_DispStr(0, 0, "Password:");

	RELAY = OFF;
	BUZZER = OFF;

	while (1)
	{

		if (VOICE_PIN == 0) //语音控制管脚
		{
			delayTime = 2+1;
			errorCnt = 0;
			RELAY = ON; //打开继电器
			LCD_DispStr(9, 0, "OK   ");
		}

		if (refreshFlag == 1)
		{
			refreshFlag = 0;
			if (delayBuzzer > 0)
			{
				delayBuzzer--;
			}
			if (delayBuzzer == 1)
			{
				BUZZER = OFF;
				delayBuzzer = 0;
				if (lockFlag == 0)
				{
					LCD_DispStr(9, 0, "     ");
				}
			}

			if (delayTime > 0)
			{
				delayTime--;
			}
			if (delayTime == 1)
			{
				RELAY = OFF;
				delayTime = 0;
				lockFlag = 0;
				LCD_DispStr(9, 0, "     ");
			}
		}
		=============================================
		DelayMs(1);

		KeyProsess();
	}
}

void KeyProsess(void)
{
	static char i = 0, j = 0;
	static char k = 0;
	unsigned char keyValue;

	keyValue = KeyDown(); //按键扫描

	///===========正常输入密码操作======================
	if (((keyValue >= '0') && (keyValue <= '9')) && !setFlag && !lockFlag) //有按键按下
	{
		input_Value[i] = keyValue;
		if (i == 0)
		{
			LCD_DispStr(9, 0, "     ");
		}
		LCD_DispOneChar(9 + i, 0, input_Value[i]);
		// LCD_DispOneChar(9+i, 0, '*');

		i++;
		if (i >= 4) //判断
		{
			errorFlag = 0;
			for (j = 0; j < 4; j++)
			{
				if (input_Value[j] != saved_Value[j])
					errorFlag = 1;
			}
			if (!errorFlag) //密码输入正确
			{
				delayTime = 2+1;
				errorCnt = 0;
				RELAY = ON; //打开继电器
				LCD_DispStr(9, 0, "OK   ");
				EEPROM_WriteByte(PASSWORD_ADDR + 4, errorCnt); //清除错误输入次数
			}
			else
			{
				RELAY = OFF; //关闭继电器
				BUZZER = ON; //声音报警
				delayBuzzer = 2+1;
				LCD_DispStr(9, 0, "ERROR");

				errorCnt = EEPROM_ReadByte(PASSWORD_ADDR + 4);
				if (errorCnt >= 2) //连续输入错误超过3次
				{
					lockFlag = 1;
					// delayTime = 1800+1; //1800秒即30min
					delayTime = 10+1; //延时10s
					LCD_DispStr(9, 0, "LOCK ");
					UartSendStr("AT+CMGF=1\r\n", 11);
					DelayS(2);
					UartSendStr("AT+CSCS=\"GSM\"\r\n", 15);
					DelayS(2);
					UartSendStr("AT+CMGS=\"+86xxxxxxxxxxx\"\r\n", 26); //可以修改电话号码
					DelayS(2);
					UartSendStr("Please pay attention to your house.\x1a", 36); //可以修改短信内容,不可以发汉字,如果发汉字的话,需要转化为特定的码
					DelayS(2);
				}
				errorCnt++;
				EEPROM_WriteByte(PASSWORD_ADDR + 4, errorCnt); //存储输入错误次数
			}

			i = 0;
		}
	}
	///===========正常输入密码操作 end======================

	///===========修改密码操作======================
	if (((keyValue >= '0') && (keyValue <= '9')) && setFlag && !lockFlag) //有按键按下 keyValue!=66
	{
		input_Value[k] = keyValue;
		if (k == 0)
		{
			LCD_DispStr(9, 0, "     ");
		}
		LCD_DispOneChar(9 + k, 0, input_Value[k]);
		// LCD_DispOneChar(9+k, 0, '*');

		k++;
		if (k >= 4) //判断
		{
			if (setFlag == 2)
			{
				for (j = 0; j < 4; j++)
				{
					saved_Value[j] = input_Value[j];
				}
				errorCnt = 0;
				EEPROM_Write();
				LCD_DispStr(9, 0, "     ");
				LCD_DispStr(0, 1, "     ");
				setFlag = 0;
				delayBuzzer = 2+1;
			}
			else if (setFlag == 1)
			{ ///============================================
				errorFlag = 0;
				for (j = 0; j < 4; j++)
				{
					if (input_Value[j] != saved_Value[j])
						errorFlag = 1;
				}
				if (!errorFlag) ///旧密码输入正确
				{
					setFlag = 2; ///可以进行下一步操作
					LCD_DispStr(9, 0, "     ");
					LCD_DispStr(0, 1, "NEW  ");
				}
				else
				{
					BUZZER = ON; //声音报警
					RELAY = OFF; //关闭继电器
					delayBuzzer = 2+1;
					LCD_DispStr(9, 0, "ERROR");

					errorCnt = EEPROM_ReadByte(PASSWORD_ADDR + 4); //存储输入错误次数
					if (errorCnt >= 2)
					{
						lockFlag = 1;
						// delayTime = 1800+1; //1800秒即30min
						delayTime = 100+1; //延时10s
						LCD_DispStr(9, 0, "LOCK ");
						UartSendStr("AT+CMGF=1\r\n", 11);
						DelayS(2);
						UartSendStr("AT+CSCS=\"GSM\"\r\n", 15);
						DelayS(2);
						UartSendStr("AT+CMGS=\"+86xxxxxxxxxxx\"\r\n", 26); //可以修改电话号码
						DelayS(2);
						UartSendStr("Please pay attention to your house.\x1a", 36); //可以修改短信内容,不可以发汉字,如果发汉字的话,需要转化为特定的码
						DelayS(2);
					}
					errorCnt++;
					EEPROM_WriteByte(PASSWORD_ADDR + 4, errorCnt); //存储输入错误次数
				}
			} ///============================================

			k = 0;
		}
	}
	///===========修改密码操作 end======================

	if (keyValue == 'A' && !lockFlag) //有按键按下
	{
		setFlag = 1;
		LCD_DispStr(9, 0, "     ");
		LCD_DispStr(0, 1, "OLD  ");

		k = 0; //=================
	}
	=============############================================
	else if (keyValue == 'B' && !lockFlag) //有按键按下,关上锁,清除窗口!LCK
	{
		BUZZER = OFF;
		LCD_DispStr(9, 0, "     ");
		RELAY = OFF; //关闭继电器
	}
}

/*******************************************************************************
 * 函 数 名         : KeyDown
 * 函数功能		   : 检测有按键按下并读取键值
 * 输    入         : 无
 * 输    出         : 无
 *******************************************************************************/
unsigned char KeyDown(void)
{
	unsigned char temp = 0xff;
	unsigned char keyCode = 0xff;

	//**********扫描第一行*********
	KEY_PORT = 0xfe;
	temp = KEY_PORT;
	temp = temp & 0xf0;
	if (temp != 0xf0)
	{

		DelayMs(5);
		temp = KEY_PORT;
		temp = temp & 0xf0;
		if (temp != 0xf0)
		{
			temp = KEY_PORT;
			switch (temp)
			{
			case 0xee:
				keyCode = 'A';
				break;

			case 0xde:
				keyCode = 'B';
				break;

			case 0xbe:
				keyCode = 'C';
				break;

			case 0x7e:
				keyCode = 'D';
				break;
			}
			while (temp != 0xf0)
			{
				temp = KEY_PORT;
				temp = temp & 0xf0;
			}
		}
	}

	//**********扫描第二行*********
	KEY_PORT = 0xfd;
	temp = KEY_PORT;
	temp = temp & 0xf0;
	if (temp != 0xf0)
	{
		DelayMs(5);
		temp = KEY_PORT;
		temp = temp & 0xf0;
		if (temp != 0xf0)
		{
			temp = KEY_PORT;
			switch (temp)
			{
			case 0xed:
				keyCode = '3';
				break;

			case 0xdd:
				keyCode = '6';
				break;

			case 0xbd:
				keyCode = '9';
				break;

			case 0x7d:
				keyCode = '#';
				break;
			}
			while (temp != 0xf0)
			{
				temp = KEY_PORT;
				temp = temp & 0xf0;
			}
		}
	}

	//**********扫描第三行*********
	KEY_PORT = 0xfb;
	temp = KEY_PORT;
	temp = temp & 0xf0;
	if (temp != 0xf0)
	{
		DelayMs(5);
		temp = KEY_PORT;
		temp = temp & 0xf0;
		if (temp != 0xf0)
		{
			temp = KEY_PORT;
			switch (temp)
			{
			case 0xeb:
				keyCode = '2';
				break;

			case 0xdb:
				keyCode = '5';
				break;

			case 0xbb:
				keyCode = '8';
				break;

			case 0x7b:
				keyCode = '0';
				break;
			}
			while (temp != 0xf0)
			{
				temp = KEY_PORT;
				temp = temp & 0xf0;
			}
		}
	}

	//**********扫描第四行*********
	KEY_PORT = 0xf7;
	temp = KEY_PORT;
	temp = temp & 0xf0;
	if (temp != 0xf0)
	{
		DelayMs(5);
		temp = KEY_PORT;
		temp = temp & 0xf0;
		if (temp != 0xf0)
		{
			temp = KEY_PORT;
			switch (temp)
			{
			case 0xe7:
				keyCode = '1';
				break;

			case 0xd7:
				keyCode = '4';
				break;

			case 0xb7:
				keyCode = '7';
				break;

			case 0x77:
				keyCode = '*';
				break;
			}

			while (temp != 0xf0)
			{
				temp = KEY_PORT;
				temp = temp & 0xf0;
			}
		}
	}
	return keyCode;
}

仿真演示视频:
https://www.bilibili.com/video/BV1Xv4y1A7mx/

实物演示视频:
https://www.bilibili.com/video/BV1xT4y1q7iE/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值