原理图
程序
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define DUAN P0
#define WEI P1
#define KEYMATRIX P3
sbit ON=P1^0;//开关标志灯
sbit sure=P0^7; //通话键
sbit KA=P1^7;
sbit KB=P1^6;
sbit KC=P1^5;
sbit INH=P1^4;
sbit OpenD=P3^7; //开锁键
sbit Beep=P3^0; //呼叫响铃
uchar dispbuf[8],dispcount;
uchar Key,result,password;
uint sum=0,temp;
uint num; //等待变量
uchar code dispbitcode[]=
{0xfd,0xfb,0xf7,}; //共阳位码表
unsigned char code dispcode[]=
{
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xff
}; //共阳段码表
//0,1,2,3,4,5,6,7,8,9,A,b,C,c,d,E,F,-;NULL
void delay(uint z)//延时1ms子函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void ledinit()/***初始化子函数,定时器0刷新显示内容***/
{
TMOD|=0x01; // 定时器0方式1
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1;
ET0=1;
EA=1;
}
/***显示子函数**/
void leddisp(uint x)
{
dispbuf[0]=x%10;
dispbuf[1]=x/10%10;
dispbuf[2]=x/100;
}
unsigned char Keyscan(void) //按键扫描程序 P2.0--P2.3为行线 P2.4--P2.7为列线
{
unsigned char rcode, ccode;
KEYMATRIX = 0xF1; // 发全0行扫描码,列线输入
Beep=1;
if((KEYMATRIX& 0xF1) != 0xF1) // 若有键按下
{
delay(5);// 延时去抖动
Beep=1;
if((KEYMATRIX& 0xF1) != 0xF1)
{
rcode = 0xFd; // 逐行扫描初值
while((rcode& 0x10) != 0)
{
KEYMATRIX = rcode; // 输出行扫描码
if((KEYMATRIX& 0xF1) != 0xF1) // 本行有键按下
{
ccode = (KEYMATRIX& 0xF0) | 0x0F;
while((KEYMATRIX& 0xF1) != 0xF1); //等待键释放
Beep=1;
return ((~rcode) + (~ccode)); // 返回键编码
}
else
rcode = (rcode<<1)|0x01; // 行扫描码左移一位
}
}
}
Beep=1;
return 0; // 无键按下,返回值为0
}
Keyresult(unsigned char key)
{
switch(key)
{
/* case 0x11: return(7); break;
case 0x21: return(8); break;
case 0x41: return(9); break; */
// case 0x81: return(?); break;
case 0x12: return(4); break;
case 0x22: return(5); break;
case 0x42: return(6); break;
// case 0x82: return(7); break;
case 0x14: return(1); break;
case 0x24: return(2); break;
case 0x44: return(3); break;
// case 0x84: return(11); break;
case 0x18: return(12); break;//*
case 0x28: return(0); break;
case 0x48: return(14); break;//#
// case 0x88: return(15); break;
default: break;
}
}
void alarm()
{
for(temp=0;temp<5;temp++)
{
P2=0X00;
delay(200);
P2=0XFF;
delay(200);
}
}
void hujiao() //呼叫声
{
uchar a;
for(a=0;a<5;a++)
{
Beep=!Beep;
delay(50);
}
}
void open()
{
P2=0xbf;
delay(100);
P2=0xef;
delay(100);
P2=0xfb;
delay(100);
P2=0xfe;
delay(100);
delay(100);
P2=0x7f;
delay(100);
P2=0xdf;
delay(100);
P2=0xf7;
delay(100);
P2=0xfd;
delay(100);
P2=0XFf;
}
void main()
{
start:
ledinit();
while(1)
{
//P1=0x40;
Key = Keyscan();
if(Key)
{
result = Keyresult(Key);
if(result==14)//#密码锁状态
{
dispbuf[0]=15;
dispbuf[1]=15;
dispbuf[2]=15;
password=sum=0;
do
{
Key = Keyscan(); //检测键盘
if(Key)//有按键按下
{
result = Keyresult(Key);//读入按键值
if(result>=0&&result<=9)//属于数字的输入
sum=sum*10+result;//计算累计数
if(result==12)//清零按键按下?
sum=0;//结果清零
leddisp(sum);//显示结果
if(sum>100)//已经输入三位数了,但是密码错
{
delay(1000);//延时并且报警
password=sum;//读入密码值
sum=0;//结果清零
if(password!=123)
alarm();//密码错误,报警
}
leddisp(sum);//显示结果
}
}while(password!=123);//等待密码正确
ON=0;//开锁
for(temp=0;temp<3;temp++)
open();
delay(2000);
ON=1;
sum=0;
}
else
{
if(result==12)//清零按键按下?
sum=0;//结果为零
if(result>=0&&result<=9)//属于数字输入?
sum=sum*10+result;//将结果计算出
}
}//以上是矩阵键盘操作
leddisp(sum);//显示结果
if(sum>100)
switch(sum)//输入正确,点亮对应的住户指示灯
{ //否则报警,重新输入
case 101:P2=0xbf;KC=0;KB=0;KA=0;hujiao();break;//对应八种结果
case 102:P2=0x7f;KC=0;KB=0;KA=1;hujiao();break;
case 201:P2=0xef;KC=0;KB=1;KA=0;hujiao();break;
case 202:P2=0xdf;KC=0;KB=1;KA=1;hujiao();break;
case 301:P2=0xfb;KC=1;KB=0;KA=0;hujiao();break;
case 302:P2=0xf7;KC=1;KB=0;KA=1;hujiao();break;
case 401:P2=0xfe;KC=1;KB=1;KA=0;hujiao();break;
case 402:P2=0xfd;KC=1;KB=1;KA=1;hujiao();break;
default : P2=0XFf;alarm();sum=0;hujiao();break;
}
// sure=1;
if(sure==0) //一旦按下通话键
{
Beep=1;
num=0;
if(sum==0)
INH=1;//关闭4051
if(sum>100) //接通对应的摄像头。
{
INH=~INH;//开启4051
if(!INH)
{
P2=0xff;//关闭报警灯
sum=0;//结果清零
}
}
// ON=~ON;
while(!sure);//松开键盘检测
}
else
{
if(sum>100)
{
num++;
if(num>40)
{
num=0;
P2=0XFf;
sum=0;
Beep=1;
goto start;
}
}
}
if(OpenD==0) //开锁键
{
delay(10);
if(OpenD==0)
{
ON=0;
}
while(!OpenD);
delay(2000);
ON=1;
}
}
}
/***定时器0刷新显示内容**/
void t0(void) interrupt 1 //using 0
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
WEI|=0x0e;//关位选
DUAN=dispcode[dispbuf[dispcount]]; //段选
WEI&=dispbitcode[dispcount]; //开位选
dispcount++;
if(dispcount==3)
dispcount=0;
}
程序
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define DUAN P0
#define WEI P1
#define KEYMATRIX P3
sbit ON=P1^0;//开关标志灯
sbit sure=P0^7; //通话键
sbit KA=P1^7;
sbit KB=P1^6;
sbit KC=P1^5;
sbit INH=P1^4;
sbit OpenD=P3^7; //开锁键
sbit Beep=P3^0; //呼叫响铃
uchar dispbuf[8],dispcount;
uchar Key,result,password;
uint sum=0,temp;
uint num; //等待变量
uchar code dispbitcode[]=
{0xfd,0xfb,0xf7,}; //共阳位码表
unsigned char code dispcode[]=
{
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xff
}; //共阳段码表
//0,1,2,3,4,5,6,7,8,9,A,b,C,c,d,E,F,-;NULL
void delay(uint z)//延时1ms子函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void ledinit()/***初始化子函数,定时器0刷新显示内容***/
{
TMOD|=0x01; // 定时器0方式1
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1;
ET0=1;
EA=1;
}
/***显示子函数**/
void leddisp(uint x)
{
dispbuf[0]=x%10;
dispbuf[1]=x/10%10;
dispbuf[2]=x/100;
}
unsigned char Keyscan(void) //按键扫描程序 P2.0--P2.3为行线 P2.4--P2.7为列线
{
unsigned char rcode, ccode;
KEYMATRIX = 0xF1; // 发全0行扫描码,列线输入
Beep=1;
if((KEYMATRIX& 0xF1) != 0xF1) // 若有键按下
{
delay(5);// 延时去抖动
Beep=1;
if((KEYMATRIX& 0xF1) != 0xF1)
{
rcode = 0xFd; // 逐行扫描初值
while((rcode& 0x10) != 0)
{
KEYMATRIX = rcode; // 输出行扫描码
if((KEYMATRIX& 0xF1) != 0xF1) // 本行有键按下
{
ccode = (KEYMATRIX& 0xF0) | 0x0F;
while((KEYMATRIX& 0xF1) != 0xF1); //等待键释放
Beep=1;
return ((~rcode) + (~ccode)); // 返回键编码
}
else
rcode = (rcode<<1)|0x01; // 行扫描码左移一位
}
}
}
Beep=1;
return 0; // 无键按下,返回值为0
}
Keyresult(unsigned char key)
{
switch(key)
{
/* case 0x11: return(7); break;
case 0x21: return(8); break;
case 0x41: return(9); break; */
// case 0x81: return(?); break;
case 0x12: return(4); break;
case 0x22: return(5); break;
case 0x42: return(6); break;
// case 0x82: return(7); break;
case 0x14: return(1); break;
case 0x24: return(2); break;
case 0x44: return(3); break;
// case 0x84: return(11); break;
case 0x18: return(12); break;//*
case 0x28: return(0); break;
case 0x48: return(14); break;//#
// case 0x88: return(15); break;
default: break;
}
}
void alarm()
{
for(temp=0;temp<5;temp++)
{
P2=0X00;
delay(200);
P2=0XFF;
delay(200);
}
}
void hujiao() //呼叫声
{
uchar a;
for(a=0;a<5;a++)
{
Beep=!Beep;
delay(50);
}
}
void open()
{
P2=0xbf;
delay(100);
P2=0xef;
delay(100);
P2=0xfb;
delay(100);
P2=0xfe;
delay(100);
delay(100);
P2=0x7f;
delay(100);
P2=0xdf;
delay(100);
P2=0xf7;
delay(100);
P2=0xfd;
delay(100);
P2=0XFf;
}
void main()
{
start:
ledinit();
while(1)
{
//P1=0x40;
Key = Keyscan();
if(Key)
{
result = Keyresult(Key);
if(result==14)//#密码锁状态
{
dispbuf[0]=15;
dispbuf[1]=15;
dispbuf[2]=15;
password=sum=0;
do
{
Key = Keyscan(); //检测键盘
if(Key)//有按键按下
{
result = Keyresult(Key);//读入按键值
if(result>=0&&result<=9)//属于数字的输入
sum=sum*10+result;//计算累计数
if(result==12)//清零按键按下?
sum=0;//结果清零
leddisp(sum);//显示结果
if(sum>100)//已经输入三位数了,但是密码错
{
delay(1000);//延时并且报警
password=sum;//读入密码值
sum=0;//结果清零
if(password!=123)
alarm();//密码错误,报警
}
leddisp(sum);//显示结果
}
}while(password!=123);//等待密码正确
ON=0;//开锁
for(temp=0;temp<3;temp++)
open();
delay(2000);
ON=1;
sum=0;
}
else
{
if(result==12)//清零按键按下?
sum=0;//结果为零
if(result>=0&&result<=9)//属于数字输入?
sum=sum*10+result;//将结果计算出
}
}//以上是矩阵键盘操作
leddisp(sum);//显示结果
if(sum>100)
switch(sum)//输入正确,点亮对应的住户指示灯
{ //否则报警,重新输入
case 101:P2=0xbf;KC=0;KB=0;KA=0;hujiao();break;//对应八种结果
case 102:P2=0x7f;KC=0;KB=0;KA=1;hujiao();break;
case 201:P2=0xef;KC=0;KB=1;KA=0;hujiao();break;
case 202:P2=0xdf;KC=0;KB=1;KA=1;hujiao();break;
case 301:P2=0xfb;KC=1;KB=0;KA=0;hujiao();break;
case 302:P2=0xf7;KC=1;KB=0;KA=1;hujiao();break;
case 401:P2=0xfe;KC=1;KB=1;KA=0;hujiao();break;
case 402:P2=0xfd;KC=1;KB=1;KA=1;hujiao();break;
default : P2=0XFf;alarm();sum=0;hujiao();break;
}
// sure=1;
if(sure==0) //一旦按下通话键
{
Beep=1;
num=0;
if(sum==0)
INH=1;//关闭4051
if(sum>100) //接通对应的摄像头。
{
INH=~INH;//开启4051
if(!INH)
{
P2=0xff;//关闭报警灯
sum=0;//结果清零
}
}
// ON=~ON;
while(!sure);//松开键盘检测
}
else
{
if(sum>100)
{
num++;
if(num>40)
{
num=0;
P2=0XFf;
sum=0;
Beep=1;
goto start;
}
}
}
if(OpenD==0) //开锁键
{
delay(10);
if(OpenD==0)
{
ON=0;
}
while(!OpenD);
delay(2000);
ON=1;
}
}
}
/***定时器0刷新显示内容**/
void t0(void) interrupt 1 //using 0
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
WEI|=0x0e;//关位选
DUAN=dispcode[dispbuf[dispcount]]; //段选
WEI&=dispbitcode[dispcount]; //开位选
dispcount++;
if(dispcount==3)
dispcount=0;
}