奶奶的生日快到了,我在外面上学一年也会不了几次家,所以这次十一回家想给奶奶一样特别的礼物.
奶奶岁数大了,每次往水缸里放水都会忘记把水龙头关掉,结果有好几次我家差点儿成了水帘洞————为此,奶奶很是自责……:(
礼物描述:我想利用DS18B20设计一个自动报警装置来提醒奶奶水满了,原理很简单:把DS18B20设计成探头放在水缸里,当水缸里的水没过DS18B20时,温度自然就下降到低于室温,蜂鸣器报警————奶奶赶到,按下按键,报警结束.:)
我用的是STC89C52单片机,晶振11.0592MHZ.
DS18B20有个特点就是us级的延时,这个特点搞得我很是头疼,整个大礼拜在寝室调了两天的延时程序,很恶心的!:funk: 感觉程序在延时时间上基本没有问题了,本来打算温度低于T_Low或者高于T_High的值时才报警,但是程序编译通过后,只有当温度超过T_High=4094时,才报警!总不能是室温达到了4094摄氏度吧?;P
请大家帮我找找原因,谢谢啦!
程序如下:
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit Led=P1^0;
sbit DS18B20_DQ=P2^2;
sbit Beep=P2^3;
uint T_Low=16;
uint T_High=4094;
uint Temperatrue;
void Delay_10us(uint count)//延时时间为count*10us
{
while(count--);
}
void Delay_ms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
uchar DS18B20_init()//DS18B20复位函数
{
uchar flag;
DS18B20_DQ=0;
Delay_10us(70); //延时大于480us
DS18B20_DQ=1; //释放总线
Delay_10us(2); //等待DS18B20应答
flag=DS18B20_DQ;
return flag; //返回DS18B20_DQ的值,看是否复位成功
}
void DS18B20_write(uint cmd)//向DS18B20写一字节数据
{
uchar count;
bit test_bit;
for(count=1;count<=8;count++)
{
DS18B20_DQ=0;
test_bit=cmd&0x01;
if(test_bit==0)//写0
{
Delay_10us(7);
DS18B20_DQ=1;
}
else//写1
{
DS18B20_DQ=1;
Delay_10us(7);
}
cmd>>=1;
}
}
uint DS18B20_read()//从DS18B20读取一字节数据
{
uint count,ReadValue;
for(count=1;count<=8;count++)
{
DS18B20_DQ=0;
ReadValue>>=1; //进行下一次读取
DS18B20_DQ=1;
if(DS18B20_DQ==1)
ReadValue|=0x80; //提取1
Delay_10us(3); //等待mcu处理读到的数据
}
return ReadValue;
}
uint DS18B20_Temperatrue() //读取出DS18B20的温度值
{
uint T;
uchar TempL,TempH;
DS18B20_init();
DS18B20_write(0xcc); //跳过ROM
DS18B20_write(0x44); //启动温度转换
DS18B20_init();
DS18B20_write(0xcc); //跳过ROM
DS18B20_write(0xbe); //读取DS18B20内部的寄存器内容
TempL=DS18B20_read(); //读温度值的低位(内部RAM的第0个字节)
TempH=DS18B20_read(); //读温度值的高位(内部RAM的第1个字节)
T=TempH;
T<<=8;
T=T|TempL; //得到DS18B20的16为二进制温度值
return T;
}
void Warn()//报警
{
uint count;
for(count=15;count>0;count--)
{
Delay_ms(500);
Beep=~Beep;
Led=~Led;
}
}
void main()
{
while(1)
{
Temperatrue=DS18B20_Temperatrue();
Temperatrue=Temperatrue*0.0625; //得到了十进制的当前温度值
if(Temperatrue>T_High)Warn();
}
} |