用单片机制作,家里进小偷时候,自动拨打主人的手机号码。红外线报警+超声波探测双模式。
#include <AT89x051.H> //器件配置文件
#define uchar unsigned char //变量类型的宏定义
#define uint unsigned int
uchar code DATA_7SEG[10]={0xC0,0xF9,0xA4,0xB0,0x99,
0x92,0x82,0xF8,0x80,0x90,};/*0-9数码管段码*/
uchar DATA[20]; /* 存放电话号码的数组*/
uchar X[3]; /*存放时间t1数组*/
uchar Y[3]; /*存放时间t2数组*/
uchar flag; /*RAM区防干扰标志*/
uchar data_flag=0; /*输入电话号码计数器(最长二十位)*/
uchar set="0"; /*功能键值*/
uchar m="0"; //全局变量
uchar n="0";
uint f;
uchar t1_flag=0; /*输入时间1计数器(最长三位)*/
uchar t2_flag=0; /*输入时间2计数器(最长三位)*/
uchar cnt_1=0; /*时间t1单元数学运算后暂存单元*/
uchar cnt_2=0; /*时间t2单元数学运算后暂存单元*/
/*****************************************************/
void delay(uint k); /*延时子函数声明*/
void stop(); /*关机子函数声明*/
void bh(); /*拨号子函数声明*/
/***************************************************/
/*定时器T0初始化*/
void init_timer()
{
TMOD=0x01;
TH0=-(50000/256);
TL0=-(50000%256);
IE=0x82;
}
/***************************************************/
/*100mS定时中断服务子函数*/
void zd0()interrupt 1
{
P3_0=!P3_0; //P3.0每100ms取反一次,送出脉冲
P1_7=!P1_7; //数码管小数点同步闪烁
n++;
TH0=-(50000/256);
TL0=-(50000%256);
}
/***************************************************/
/*INT0中断服务子函数*/
void zd_int0()interrupt 0
{
delay(10);
if(P3_2==0)set++; //功能键值递增
if(set>=5)set=0; //键值的范围0~4
if(set==1)flag=0x55; //向RAM区的标志flag写入55H
PCON=0x00;f=8;
again:if(P3_2==0)goto again; //若按键未释放,则等待
}
/******************************************************/
/*INT1中断服务子函数*/
void zd_int1()interrupt 2
{uchar h;
f=0;
for(h=0;h<10;h++) /*检查磁性开关(P3_3状态)10次,共1秒*/
{
delay(100);
if(P3_3==0)f++;
}
}
/********************************************************/
/*---关机---*/
void stop()
{if(flag==0x55)P1=0xfb;
else P1=0x86; //数码管右下角显示"1"。
delay(1);
if(flag==0x55)PCON=0x01; /*进入节电待机状态*/
delay(1);
}
/********************************************************/
/*延时1ms*K子函数*/
void delay(uint k)
{
uint i,j;
for(i=0;i<k;i++){
for(j=0;j<60;j++)
{;}}
}
/********************************************************/
/*----输入时间t1----*/
void in_time1()
{
P1=0xf7;delay(1); /*数码管显示"一"*/
if(P3_5==0)
{
delay(10); /*按下OK键确认并点亮小数点*/
if(P3_5==0){P1=0x7f;m=0;t1_flag=0;delay(500);}
while(t1_flag<3)
{
if(P3_4==0)
{delay(10);if(P3_4==0) /*按下UP键数码管作0-9递增显示*/
{m++;if(m==10)m=0;P1=DATA_7SEG[m];delay(300);}
}
P1=DATA_7SEG[m];delay(1); /*若不按下UP键数码管也作0-9显示*/
if(P3_5==0)
{delay(10);if(P3_5==0) /*按下OK键显示的数据存入数组X中*/
{X[t1_flag]=m;t1_flag++;P1=0x7f;delay(500);}
}
}
}
if(t1_flag>=3)t1_flag=0; /*时间1计数器>=3时归零*/
}
/***********************************************************************/
/*----输入时间t2----*/
void in_time2()
{
P1=0xb7;delay(1); /*数码管显示"二"*/
if(P3_5==0)
{
delay(10); /*按下OK键确认并点亮小数点*/
if(P3_5==0){P1=0x7f;m=0;t2_flag=0;delay(500);}
while(t2_flag<3)
{
if(P3_4==0)
{delay(10);if(P3_4==0) /*按下UP键数码管作0-9递增显示*/
{m++;if(m==10)m=0;P1=DATA_7SEG[m];delay(300);}
}
P1=DATA_7SEG[m];delay(1); /*若不按下UP键数码管也作0-9显示*/
if(P3_5==0)
{delay(10);if(P3_5==0) /*按下OK键显示的数据存入数组Y中*/
{Y[t2_flag]=m;t2_flag++;P1=0x7f;delay(500);}
}
}
}
if(t2_flag>=3)t2_flag=0; /*时间2计数器>=3时归零*/
}
/***********************************************************************/
/*----输入电话号码----*/
void in_data()
{uchar g;
P1=0xb6;delay(1); /*数码管显示"三"*/
if(P3_5==0)
{delay(10);if(P3_5==0)
{P1=0x7f;m=0;data_flag=0; /*按下OK键确认并点亮小数点*/
for(g=0;g<20;g++){DATA[g]=10;}
delay(500); /*同时DATA数组中全部写入10*/
while(1)
{
if(P3_4==0){delay(10); /*按下UP键数码管作0-9递增显示*/
if(P3_4==0){m++;if(m==10)m=0;P1=DATA_7SEG[m];delay(300);}
}
P1=DATA_7SEG[m];delay(1);/*若不按下UP键数码管也作0-9显示*/
if(P3_5==0)
{delay(10);
if(P3_5==0) /*按下OK键显示的数据(号码)存入数组DATA中*/
{DATA[data_flag]=m;data_flag++;P1=0x7f;delay(500);}
} /*按下OK键超过2秒则退出向数组DATA送入号码*/
if(P3_5==0){delay(2000);if(P3_5==0)break;}
}
}
} /*数码管显示"三"*/
F1:if(P3_5==0){delay(10);if(P3_5==0){P1=0xb6;delay(1);goto F1;}}
}
/***********************************************************************/
/*---启动报警器进入警戒工作---*/
void work()
{ uchar h;
P1=0xdf; /*数码管左上角显示"1"*/
delay(1);
if(set==1) /*进入时间1循环*/
{while(cnt_1<=X[0]*100+X[1]*10+X[2])
{
delay(1000);
cnt_1++; /*计数器cnt_1累加*/
if(set!=1){EX1=0;cnt_1=0;break;}
} /*如按下Set键,则退出此循环*/
}
else {EX1=0;PCON=0x00;}/*Set不为1,则关闭外中断1,退出待机状态*/
if(set==1)
{if(cnt_1>=X[0]*100+X[1]*10+X[2])
{EX1=1;cnt_1=0;} /*时间1到,打开外中断1,计数器归零*/
/*进入待机。若有1秒以上开关动作,退出待机*/
while(1)
{PCON=0x01;if(f>=5){PCON=0x00;break;}}
}
/*-----------------------------------------------------*/
EX1=0; /*关闭外中断1*/
if(set==1) /*进入时间2循环*/
{while(cnt_2<=Y[0]*100+Y[1]*10+Y[2])
{
delay(1000);
cnt_2++; /*计数器cnt_2累加*/
if(set!=1){cnt_2=0;break;}
} /*如按下Set键,则退出此循环*/
}
if(set==1)
{
bh(); /*时间2到,调用拨号子程序*/
delay(3000);
P3_7=0;//控制输出端为低
for(h=0;h<60;h++) /*发出60秒警音*/
{ for(f=0;f<500;f++)
{f++;
P3_1=!P3_1;P1=0x5f;
delay(1);
}
P3_1=0;P1=0x7f;delay(500);
}
P3_7=1;//控制输出端恢复高
cnt_1=0;cnt_2=0; /*有关计数器、端口回到初始状态*/
P3_0=0;P3_1=0;P1_7=1;
for(f=0;f<3;f++)delay(60000);/*关闭3分钟,以便进行电话报警*/
}
}
/********************************************************************/
/*---拨号---*/
void bh()
{data_flag=0; /*电话号码计数器(二十位)归零*/
P3_0=1; /*接通线路*/
P1_7=0; /*数码管小数点亮*/
delay(1000);
while(DATA[data_flag]<10) /*号码小于10进入循环拨号状态*/
{
if(DATA[data_flag]==0) /*若号码为0*/
{TR0=1; /*启动T0定时器*/
if(n==20){data_flag++; /*进行20次中断,产生10个脉冲*/
n=0;TR0=0;
P3_0=1;P1_7=0;
delay(500);
}
}
if(DATA[data_flag]>0) /*若号码>0*/
{TR0=1; /*启动T0定时器*/
if(n==((DATA[data_flag])*2))/*进行号码x2次中断,产生号码个脉冲*/
{data_flag++;
n=0;TR0=0;
P3_0=1;P1_7=0;
delay(500);
}
}
}
TR0=0;
}
/*********************************************************************/
/*--主函数--*/
void main()
{
init_timer(); /*定时器T0初始化*/
EA=1;EX0=1; /*开总中断,开外中断0*/
P3_0=0; /*关闭线路(挂机)*/
P3_1=0;
while(1) /*无限循环*/
{
switch(set) /*根据Set标志散转*/
{
case 0:stop();break; /*关机*/
case 1:work();break; /*警戒工作*/
case 2:in_time1();break; /*输入时间t1*/
case 3:in_time2();break; /*输入时间t2*/
case 4:in_data();break; /*输入电话号码*/
default:break;
}
if(flag!=0x55) /*若flag标志变化,数码管显示E(错误)*/
{P1=0x86;delay(1);}
}
}
文章评论(0条评论)
登录后参与讨论