#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char //宏定义
sbit IR1=P2^5;
sbit IR2=P2^6;
sbit RT=P2^7;
sbit BUZZER=P2^3;
sbit LEDG=P2^2;
sbit LEDR=P2^1;
sbit BUTTON=P0^1;
sbit DP=P1^7; //小数点显示控制
sbit DQ = P0^0; //定义DS18B20端口
sbit d1=P3^3; //第一个数码管
sbit d2=P3^2; //第二个
sbit d3=P3^1; //第三个
uchar presence;uchar code LEDData[]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
/*{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00}; //00quanmie,40,fuhao*/
uchar data temp_data[2]= {0x00,0x00};
uchar data display[4] = {0x00,0x00,0x00,0x00};
uchar time=0;//定时器中断次数
bit flash=0; //显示开关标记
bit flag; //负号显示标志
bit dem;//模式默认为you红绿灯
/*****延时子程序*****/
void Delay(uint num)
{ while( --num );}
/*****初始化DS18B20*****/
Init_DS18B20(void)
{ DQ = 1; //DQ复位
Delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
Delay(90); //精确延时大于480us
DQ = 1; //拉高总线 Delay(8); 这句省略了,错了
Delay(8);
presence = DQ; //如果=0则初始化成功 =1则初始化失败 Delay(100); DQ = 1; 这句忘了,错了!
Delay(100); DQ = 1;
return(presence); //返回信号,0=presence,1= no presence
}
/*****读字节子程序*****/
ReadOneChar(void) //读一个字节
{ uchar i = 0;
uchar dat = 0;
for (i = 8; i > 0; i--)
{ DQ = 0; // 给脉冲信号
dat >>= 1;
DQ = 1; // 给脉冲信号
if(DQ)
dat |= 0x80;
Delay(4);
}
return (dat);
}
/*****写字节子程序*****/
WriteOneChar(uchar dat) //写一个字节
{ uchar i = 0;
for (i = 8; i > 0; i--)
{ DQ = 0;
DQ = dat&0x01;
Delay(5);
DQ = 1;
dat>>=1;
}
}
/*****读温度子程序******/
int Read_Temperature(void) //读取温度
{
unsigned int t=0,wd=0; //*****
float tt=0; //****
// bit flag=0; //xianshi fuhao
Init_DS18B20();
if(presence==1)
{ flash=1; }
else
{ flash=0;
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
temp_data[0] = ReadOneChar();//温度低8位
temp_data[1] = ReadOneChar();//温度高8位
t=temp_data[1];
t<<=8;
t=t|temp_data[0];
wd=t;
/*if (temp_data[1]>>4==0)
{
flag=0;
wd=t;}
else
{
flag=1;
wd=~t+1;
} */
tt=wd*0.0625;
t= (tt+0.5)*10; //放大10倍输出并四舍五入 ***gaidong
return(t);
}
}
/*****显示子程序*****/
Disp_Temperature() //显示温度
{ unsigned int i=0;
i=Read_Temperature();//读温度并送显
/* display[1]=i/100; //十位数
display[0]=i/10-display[1]*10; //个位数 */
display[2]=i/100; //十位数
display[1]=(i%100)/10; //个位数
display[0]=(i%100)%10;
P1 =LEDData[display[0]];// GEWEI
d1=1;d2=1;d3=0;Delay(700);
P1=LEDData[display[1]]; //SHIWEI
DP=0;/*第二位有小数点的显示*/
d3=1;d2=0; Delay(700);
P1=LEDData[display[2]];
d2=1;d1=0;Delay(700);
P1=0xff;
}
/*检测到人体报警函数*/
BELL1()
{
if(display[2]<3) //十位数小于3
{
if(IR1|IR2|RT&LEDR)
BUZZER=0;
else
BUZZER=1;
}
else
{
if(IR1|IR2&LEDR)
{BUZZER=0;
}/*HONGDENGLIANG*/
else{BUZZER=1;}
}
}
BELL2()
{
if(display[2]<3) //十位数小于3
{
if(IR1|IR2|RT==1)
{BUZZER=0;/*再加上灯亮控制*/
/*LEDR=0;*/}
else
{BUZZER=1;/*LEDR=1;*/}
}
else
{
if(IR1|IR2==1)
{BUZZER=0;
/*LEDR=0;*/
}/*HONGDENGLIANG*/
else
{BUZZER=1;/*LEDR=1;*/}
}
}
//定时器中断函数
timer0()interrupt 1 using 1
{
TH0=(65535-15536)/256;
TL0=(65536-15536)%256;
if(++time==250)
{ LEDR=~LEDR;
LEDG=~LEDG;
}
}
timer1()interrupt 3 using 2
{
TH1=(65535-1000)/256;
TL1=(65536-1000)%256;
if(++time==2)
{if(IR1|IR2)
LEDR=!LEDR;
}
}
//模式切换函数
demo()
{
if(BUTTON==1)
dem=1;
else
dem=0;
}
/*****主函数*****/
void main(void)
{
dem=1;//初始化默认为有红绿灯模式
demo();//调用模式函数
if (dem==1) //YOU DENG !
{
LEDG=0;//等0则亮
LEDR=1;
BUZZER=1; /*蜂鸣器初始值设为1,不响*/
TMOD=0x01;
TH0=(65535-15536)/256;
TL0=(65536-15536)%256;
EA=1;
ET0=1;
TR0=1;
do
{
Read_Temperature();
if(flash==0)
{ Disp_Temperature(); }
else P1 = 0xff ; //DS18B20不正常,关闭显示
if(LEDR==0)
{
BELL1(); /*检测到人体响*/
}
}while(1);
}
else
{
LEDG=1;//等0则亮,1zemie
LEDR=1;
BUZZER=1; /*蜂鸣器初始值设为1,不响*/
TMOD=0x10;
TH1=(65535-1000)/256;
TL1=(65536-1000)%256;
EA=1;
ET1=1;
TR1=1;
do{
Read_Temperature();
if(flash==0)
{ Disp_Temperature(); }
else P1 = 0xff ; //DS18B20不正常,关闭显示
BELL2(); /*检测到人体响*/
}while(1);
}
}