功能介绍:
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;
}