|
#include <reg52.h>
#define uchar unsigned char //無符號字符型 宏定義 變量范圍0~255
#define uint unsigned int //無符號整型 宏定義 變量范圍0~65535
#include "lcd1602.h"
#include "at24c02.h"
sbit relay = P2^2; //繼電器定義
sbit beep = P3^3; //蜂鳴器定義
sbit beiguang = P2^3; //背光
bit flag_200ms=1; //200ms標志位
uchar value,i; //變量
uchar flag_lj_en=1; //連加使能
uchar flag_lj_en_value;
uchar key_can; //鍵值
uchar menu_1,menu_i;
uchar smg_i; //輸密光標
uchar dis_smg[8]={0};
uchar password[8]={8,7,6,5,4,3,2,1}; //密碼保存
uchar password_bj[8]={1,2,3,4,5,6,7,8}; //密碼比較
uchar code password_r[8] = {1,2,3,4,1,2,3,4} ;
uchar password_xg[8]={7,6,5,4,3,2,1,0}; //密碼修改
uchar flag_password; //密碼正確否標志
uchar flag_password_cishu;//密碼錯誤次數(shù)標志
uint flag_time; //時間標志位
uint flag_bisuo; //閉鎖標志位
/***********************1ms延時函數(shù)*****************************/
void delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<120;j++);
}
/*************************清空數(shù)組函數(shù)**************************/
void clear_shuzu(uchar *p)
{
for(i=0;i<8;i++)
p[i] = 0;
}
/**************************定時器0初始化函數(shù)*******************/
void time_init()
{
EA = 1; //開總中斷
TMOD = 0X01; //定時器0、工作方式1
ET0 = 1; //開定時器0中斷
TR0 = 1; //允許定時器0定時
}
/********************下載程序密碼初始化函數(shù)********************/
void password_chushihua()
{
beep = 0;
write_24c02_8(8,0,password_r);
delay_1ms(200);
read_24c02_8(8,0,password);
beep = 1;
}
/***********************鍵盤掃描函數(shù)**************************/
void key()
{
static uchar key_new = 0, key_l;
key_can = 20; //按鍵值還原
P1 = 0x0f;
if((P1 & 0x0f) != 0x0f) //如果有按鍵按下
{
delay_1ms(1); //延時消抖
if(((P1 & 0x0f) != 0x0f) && (key_new == 1)) //再次確認
{
key_new = 0;
key_l = (P1 | 0xf0); //通過算法得到鍵值
P1 = key_l;
switch(P1) //得到鍵值
{
case 0xee: key_can = 1; break;
case 0xde: key_can = 4; break;
case 0xbe: key_can = 7; break;
case 0x7e: key_can = 10; break;
case 0xed: key_can = 0; break;
case 0xdd: key_can = 8; break;
case 0xbd: key_can = 5; break;
case 0x7d: key_can = 2; break;
case 0xeb: key_can = 3; break;
case 0xdb: key_can = 6; break;
case 0xbb: key_can = 9; break;
case 0x7b: key_can = 11; break;
case 0xe7: key_can = 15; break;
case 0xd7: key_can = 14; break;
case 0xb7: key_can = 13; break;
case 0x77: key_can = 12; break;
}
}
}
else
{
key_new = 1; //沒有鍵按下時賦值
flag_lj_en = 0;
}
}
/****************按鍵功能處理********************/
void key_with()
{
static uchar value;
if(key_can == 14) //如果是“手動閉鎖”鍵
relay = 1;
if(key_can == 10) //如果是“密碼還原”鍵
{
flag_lj_en = 1; //連加使能
flag_lj_en_value = 0;
}
if(menu_1 == 0)
{
if(key_can <= 9)
if(menu_i < 8) //密碼輸入位數(shù)
{
menu_i ++;
if(menu_i > 8) //超過8位無法寫入
menu_i = 8;
smg_i = menu_i;
for(i=8;i>0;i--) //依次裝入密碼比較數(shù)組
password_bj[i] = password_bj[i-1];
password_bj[0] = key_can;
for(i=0;i<smg_i;i++) //顯示占位符“*”
dis_smg[i] ='*';
write_string(2,7,dis_smg);
lcd1602_gbiao(1,7 + menu_i + 0x40); //開光標
}
if(key_can == 11) //如果是“密碼刪除”鍵
{
for(i=0;i<menu_i;i++) //依次從比較數(shù)組中取出密碼
password_bj[i] = password_bj[i+1];
menu_i --;
password_bj[menu_i] = ' '; //清除占位符
dis_smg[menu_i] = ' ';
write_string(2,7,dis_smg);
lcd1602_gbiao(1,7 + menu_i + 0x40); //開光標
}
if(key_can == 15) //如果是“確認”鍵
{
value = 0;
for(i=0;i<8;i++) //8位密碼分別比較
{
if(password_bj[i] == password[i])
{
flag_password = 1; //密碼正確
relay = 0; //鎖開
flag_password_cishu=0; //輸入正確,錯誤次數(shù)清零
for(i=0;i<8;i++)
dis_smg[i] = 0xbf;
}
else
{
flag_password = 0;
flag_password_cishu ++;
write_string(1,0," Password error ");
write_string(2,0," cishu: ");
write_cwcs(2,9,flag_password_cishu); //在第二行第九位顯示次數(shù)
delay_1ms(280);
for(i=0;i<6;i++) //蜂鳴三聲
{
beep = ~beep;
delay_1ms(200);
}
beep = 1; //關(guān)閉蜂鳴
delay_1ms(800);
break;
}
}
clear_shuzu(dis_smg); //顯示初始化
write_string(1,0," Password Lock ");
write_string(2,0," Input: ");
lcd1602_gbiao(1,7+0x40); //開光標
menu_i = 0;
}
}
}
/**************************密碼還原函數(shù)***************************/
void password_return()
{
if(flag_lj_en == 1)
{
flag_lj_en_value ++;
if(flag_lj_en_value > 13)
{
flag_lj_en_value = 0;
flag_lj_en = 0;
write_24c02_8(8,0,password_r); //寫入初始化密碼
beep = 0;
delay_1ms(500);
beep = 1;
read_24c02_8(8,0,password); //讀取密碼
}
}
}
/*******************************修改密碼**************************/
void xiugai_password()
{
if(key_can == 13) //如果是“修改密碼”鍵
{
if((relay == 0) && (menu_1 == 0))
{
menu_1 = 1; menu_i = 0; //賦值
clear_shuzu(password_bj); //數(shù)據(jù)清空
clear_shuzu(dis_smg);
write_string(1,0,"Input1: ");
write_string(2,0,"Input2: ");
lcd1602_gbiao(1,7); //開光標
}
}
if(menu_1 == 1) //第一次輸入修改的密碼
{
if(key_can <= 9) //鍵號小于或等于9
{
if(menu_i < 8) //輸入個數(shù)小于8
{
menu_i ++;
if(menu_i > 8)
menu_i = 8;
smg_i = menu_i;
for(i=8;i>0;i--)
password_bj[i] = password_bj[i-1]; //依次裝入數(shù)組中
password_bj[0] = key_can;
for(i=0;i<menu_i;i++)
dis_smg[i] ='*'; //依次顯示占位符“*”
write_string(1,7,dis_smg);
lcd1602_gbiao(1,7 + menu_i); //開光標
}
}
if(key_can == 11) //如果是"刪除"鍵
{
for(i=0;i<menu_i;i++)
password_bj[i] = password_bj[i+1];
menu_i --;
password_bj[menu_i] = ' ';
dis_smg[menu_i] = ' ';
write_string(1,7,dis_smg);
lcd1602_gbiao(1,7 + menu_i); //開光標
}
if(key_can == 15) //如果是“確定”鍵
{
clear_shuzu(password_xg); //數(shù)據(jù)清空
clear_shuzu(dis_smg);
lcd1602_gbiao(1,7 + 0x40); //開光標
menu_1 = 2;
menu_i = 0;
key_can = 20; //按鍵值還原
}
}
if(menu_1 == 2) //第二次輸入修改的密碼
{
if(key_can <= 9)
{
if(menu_i < 8)
{
menu_i ++;
if(menu_i > 8)
menu_i = 8;
for(i=8;i>0;i--)
password_xg[i] = password_xg[i-1];
password_xg[0] = key_can;
for(i=0;i<menu_i;i++)
dis_smg[i] ='*';
write_string(2,7,dis_smg);
lcd1602_gbiao(1,7 + menu_i + 0x40); //開光標
}
}
if(key_can == 11) //如果是“刪除”鍵
{
for(i=0;i<menu_i;i++)
password_xg[i] = password_xg[i+1]; //依次從數(shù)組最后一個清除
password_xg[menu_i] = ' ';
dis_smg[menu_i] = ' '; //依次顯示占位符“ ”
write_string(2,7,dis_smg);
lcd1602_gbiao(1,7 + menu_i + 0x40); //開光標
}
if(key_can == 15) //如果是“確定”鍵
{
for(i=0;i<8;i++) //分別比較兩次輸入的8位密碼
{
if(password_bj[i] == password_xg[i]) //只要有一位不匹配就會執(zhí)行else
{
flag_password = 1; //兩次輸入的密碼一樣
}
else
{
flag_password = 0;
write_string(1,0," Password Error ");
write_string(2,0," reenter ");
delay_1ms(300);
for(i=0;i<6;i++)
{
beep = ~beep; //提示三聲
delay_1ms(300);
}
beep = 1;
delay_1ms(1000);
break;
}
}
if(flag_password == 1) //如果兩次輸入一致
{
for(i=0;i<8;i++)
{
write_string(1,0," Password ");
write_string(2,0," Succeed ");
password[i] = password_bj[i]; //保存密碼
}
write_24c02_8(8,0,password); //將密碼寫入AT24C02
delay_1ms(300);
beep = 0; //蜂鳴器提示一聲
delay_1ms(2000);
beep = 1;
}
clear_shuzu(password_xg); //數(shù)據(jù)清空
clear_shuzu(dis_smg);
write_string(1,0," Password Lock ");
write_string(2,0," Input: ");
lcd1602_gbiao(1,7+0x40); //開光標
menu_1 = 0;
menu_i = 0;
}
}
}
/********************************主程序******************************/
void main()
{
static uint value ;
password_chushihua(); //密碼初始化
time_init(); //定時器初始化
read_24c02_8(8,0,password); //從AT24C02讀取密碼
init_1602(); //LCD1602初始化
beiguang = 0; //背光開
while(1)
{
if(flag_password_cishu < 3) //判斷密碼錯誤次數(shù)是否小于3
{
key(); //按鍵掃描函數(shù)
if(key_can < 20)
{
if(beiguang == 0)
{
if(menu_1 == 0)
key_with(); //按鍵處理函數(shù)
xiugai_password(); //修改密碼函數(shù)
}
else
beiguang = 0;
flag_time = 0;
}
}
if(flag_200ms == 1)
{
flag_200ms = 0;
if(beiguang == 0) //延時30秒關(guān)閉背光
{
flag_time ++;
if(flag_time >= 5 * 30) //延時30秒(50×4×5×30)
{
flag_time = 0;
beiguang = 1; //關(guān)閉背光
}
}
if(relay == 0) //延時10秒關(guān)閉鎖
{
flag_bisuo++;
if(flag_bisuo >= 5 * 10) //延時10秒
{
flag_bisuo = 0;
relay = 1; //關(guān)閉鎖
}
}
else
flag_bisuo = 0;
if(flag_password_cishu >= 3)
{
value ++; //每自加一次延時200ms
beep = ~beep; //蜂鳴器報警
if(value >= 5 * 60) //報警時間為1分鐘
{
value = 0;
beep = 1;
flag_password_cishu = 0;
}
}
password_return(); //密碼還原函數(shù)
}
delay_1ms(1);
}
}
/***********************定時器0中斷服務程序***********************/
void time0_int() interrupt 1
{
static uchar value;
TH0 = 0x3c; // 50ms(12M晶振下的定時初值)
TL0 = 0xb0;
value ++;
if(value % 4 == 0)
{
flag_200ms = 1;
}
}
|
|