/*
課程名稱:電子密碼鎖設計
設計任務:根據(jù)設定好的密碼,采用按鍵實現(xiàn)6為的輸入功能,
當用戶輸入的密碼正確并且是在規(guī)定的時間(普
通用戶要求在12s內(nèi)輸入正確的密碼)時,鎖就
打開,如果輸入的三次密碼不正確,就發(fā)出警報
聲。如果用戶的時間超過40秒,電路將報警80
秒,若電路連續(xù)報警三次,電路將鎖定鍵盤5分
鐘,防止他人的非法操作
*/
#include"reg51.h"
#include"intrins.h"
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
sbit bj = P3^0; //定義報警
sbit led_y = P3^5; //定義黃色燈
sbit led_r = P3^6; //定義紅色燈
sbit led_g = P3^7; //定義綠色燈
ulong pwd = 234567; //定義電子鎖密碼
uint gy = 0; //定義管理員/用戶(管理員為1)標識
uint ss = 0; //定義上鎖標識(0時表示已上鎖)
uint flag = 0; //定義中斷函數(shù)中所用到的標識
uchar sd = 1; //定義鍵盤鎖定(1為未鎖)標識
uint pcw = 0; //定義密碼錯誤次數(shù)
uint bjc = 0; //定義報警次數(shù)
uint jp = 0; //定義鍵盤掃描值
uint cnt = 0; //定義中斷次數(shù)
uint mcnt = 0;
uint cs = 0; //定義超時標識
uchar key;
//uchar j;
//定義共陽數(shù)碼管段選數(shù)組
uchar code table[11] ={0x3F,0x06,0x5B,0x4F,0x66,
0x6D,0x7D,0x07,0x7F,0x6F,0x08};
//定義按鍵
uchar code table1[16] = {0xee,0xde,0xbe,0x7e,
0xed,0xdd,0xbd,0x7d,
0xeb,0xdb,0xbb,0x7b,
0xe7,0xd7,0xb7,0x77};
//定義儲存按鍵值
uchar table2[6];
//定義短延遲函數(shù)
void delay(uint n)
{
while(n--);
}
//定義延遲n s函數(shù)
void delayns(uint n)
{
unsigned char a,b,c,e;
for(e=n;e>0;e--)
for(c=167;c>0;c--)
for(b=171;b>0;b--)
for(a=16;a>0;a--);
_nop_(); //if Keil,require use intrins.h
}
//定義初始化函數(shù)
void init()
{
uchar i,k;
led_y = 0;
led_r = 1;
led_g = 1;
bj = 1;
EA = 1; //打開總中斷
EX1 = 1; IT1 = 1; //打開外部中斷1,并設置觸發(fā)方式為下降觸發(fā)方式
TMOD = 0X01; //設置定時器0工作方式1
TH0 = (65536 - 50000)/256;
TL0 = (65536 - 50000)%256; //給定時器0賦值為50ms
for(i = 0;i < 6; i++)
{
table2[i] = 10;
}
for(k = 0;k<8;k++)
{
P0=0x08;
P2 = k;
}
}
//定義上鎖中斷函數(shù)
void INT_0() interrupt 0
{
uchar h;
ss = 0; //密碼鎖上鎖
led_g = 1;
for(h = 0;h < 6; h++) //初始化table2[]為10
{
table2[h] = 10;
}
}
//定義管理員/用戶切換中斷函數(shù)
void INT_1() interrupt 2
{
uchar h;
if(flag == 0)
{
gy = 1; //關閉管理員指示燈
led_y = 1; //關閉密碼錯誤指示燈
flag = 1;
for(h = 0;h < 6; h++) //初始化table2[]為10
{
table2[h] = 10;
}
}
else
{
gy = 0; //關閉管理員指示燈
led_y = 0; //關閉密碼錯誤指示燈
flag = 0;
for(h = 0;h < 6; h++) //初始化table2[]為10
{
table2[h] = 10;
}
}
}
//定義計時器中斷函數(shù)
void timer() interrupt 1
{
TH0 = (65536 - 50000)/256;
TL0 = (65536 - 50000)%256;
++cnt; //中斷一次加以
if(cnt == 20) //每1秒
{
cnt = 0;
++mcnt;
if(gy) //管理員時
{
if(mcnt > 40)
{
bjc++;
cs = 1;
bj = 0;
delayns(80);
bj = 1;
}
else if(mcnt > 5) //大于5秒時
{
cs = 1;
}
else //小于5秒時
{
cs = 0;
}
}
else //用戶時
{
if(mcnt > 40)
{
bjc++;
cs = 1;
bj = 0;
delayns(80);
bj = 1;
}
else if(mcnt > 12) // 大于12秒時
{
cs = 1;
}
else //小于1秒時
{
cs = 0;
}
}
}
}
//定義顯示函數(shù)
void display( uint wei, uint duan)
{
P2 = wei;
P0 = table[duan];
delay(50);
}
//定義鍵盤掃描函數(shù)并顯示按鍵
void scan()
{
uchar i,j,h,k,m=20, e = 1;
while(j != 6) //讀取六個鍵值
{
P1 = 0xf0; //置行為0.列為1,讀列值
if(P1 != 0xf0) //判斷有無鍵盤被按下
{
delay(19000); //消振
if(P1 != 0xf0) //確實有鍵盤被按下
{
uchar temp = P1; //存儲列列讀入值
if(j==5) //當最后一位密碼輸入時
{
ET0 = 0; //關閉定時/計數(shù)0中斷
}
if(j == 0) //當要輸入第一個密碼時
{
ET0 = 1; TR0 = 1; //開啟定時/計數(shù)0中斷
led_r = 1; //關閉報警燈
led_g = 1; //關閉打開指示燈
for(h = 0;h < 6; h++) //初始化table2[]為10
{
table2[h] = 10;
}
}
P1 = 0x0f; //置列為0.行為1,讀行值
key = temp|P1; //將列、行綜合,讀取鍵值
for(i = 0; i < 10; i++)
{
if(key == table1[i]) //判斷鍵值
{
table2[j] = i; //將密碼存儲到table2[]中
j++;
break;
}
}
}
}
for(k = 0;k < 6;k++) //顯示輸入鍵值
{
uint n=20;
while(n--)
display(k,table2[k]);
}
}
for(k = 0;k < 6;k++) //顯示輸入鍵值
{
uint n=20;
while(n--)
display(k,table2[k]);
}
}
//定義報警函數(shù)
void speaker(uint n)
{
uint i;
for(i = 0; i<n; i++)
{
bj = 0;
delayns(1);
bj = 1;
}
}
//定義密碼正確函數(shù)驗證函數(shù)
void mmyz()
{
uchar mmy;
uint m1 = pwd/100000; //取得密碼的第一位
uint m2 = pwd%100000/10000; //取得密碼的第二位
uint m3 = pwd%100000%10000/1000; //取得密碼的第三位
uint m4 = pwd%100000%10000%1000/100; //取得密碼的第四位
uint m5 = pwd%100000%10000%1000%100/10; //取得密碼的第五位
uint m6 = pwd%100000%10000%1000%100%10; //取得密碼的第六位
//判斷密碼的正確性
mmy = (m1==table2[0])&(m2==table2[1])&(m3==table2[2])
&(m4==table2[3])&(m5==table2[4])&(m6==table2[5]);
if(!cs) //沒超過規(guī)定時間
{
if(mmy == 1) //密碼正確
{
ss = 1;
led_g = 0; //打開密碼鎖。綠燈亮
EX0 = 1; IT0 = 1; //打開外部中斷0,并設置觸發(fā)方式為下降觸發(fā)方式
pcw = 0; //密碼錯誤次數(shù)清零
bjc = 0; //報警次數(shù)清零
bj = 1; //關閉報警
}
else //密碼錯誤
{
pcw++; //密碼錯誤加1
led_r = 0; //密碼錯誤,紅燈亮
if(pcw >=3)
{
pcw = 0;
bjc++;
P2 = 0xff;
speaker(1);
if(bjc == 3)
{
bjc = 0; //報警
led_r = 0;
led_g = 0;
P2 = 0xff;
EA = 0; //關閉總中斷
delayns(300); //鎖定5分鐘
EA = 1; //開啟總中斷
led_r = 1;
led_g = 1;
}
}
}
}
else //超過規(guī)定時間
{
uchar h;
for(h = 0;h < 6; h++) //初始化table2[]為10
{
table2[h] = 10;
}
}
}
//定義主函數(shù)
void main()
{
uchar i;
init(); //初始化程序
while(1)
{
if(!ss)
{
if(gy) //管理員時
{
if(sd == 1)
{
scan(); //調(diào)用鍵盤掃面函數(shù),接收輸入的鍵值
mmyz(); //驗證密碼
}
}
else //用戶時
{
if(sd == 1)
{
scan(); //調(diào)用鍵盤掃面函數(shù),接收輸入的鍵值
mmyz(); //驗證密碼
}
}
}
else
{
for(i = 0;i < 6;i++) //顯示輸入鍵值
{
table2[i] = 10;
}
for(i = 0;i < 6;i++) //顯示輸入鍵值
{
uint n=20;
while(n--)
display(i,table2[i]);
}
}
}
} |