打印

用DS18B20给奶奶做个生日礼物!

[复制链接]
8231|38
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
for_fun|  楼主 | 2009-9-20 15:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
奶奶的生日快到了,我在外面上学一年也会不了几次家,所以这次十一回家想给奶奶一样特别的礼物.
奶奶岁数大了,每次往水缸里放水都会忘记把水龙头关掉,结果有好几次我家差点儿成了水帘洞————为此,奶奶很是自责……:(
礼物描述:我想利用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();
}
}

相关帖子

沙发
maychang| | 2009-9-20 16:33 | 只看该作者
不必用18B20吧?
水位是开关量,市场上有浮子开关卖,里面是块小磁铁和一个干簧管。也不必使用单片机,一个RS触发器足矣。

使用特权

评论回复
板凳
maychang| | 2009-9-20 16:36 | 只看该作者
若是用个电磁阀,连关带开都可以自动,不过需要两个浮子开关确定高低水位。

想孝敬老人,这个心意不错。

使用特权

评论回复
地板
for_fun|  楼主 | 2009-9-20 17:33 | 只看该作者
3# maychang
第一次听说还有浮子开关这种东东,估计会给我省了好多麻烦,接受你的建议,我回去好好研究一下!非常感谢!:loveliness:

使用特权

评论回复
5
for_fun|  楼主 | 2009-9-20 18:42 | 只看该作者
可是,我的程序错在哪了呢?很想知道答案!希望得到大家的关注!:)

使用特权

评论回复
6
Wxy8030| | 2009-9-20 20:56 | 只看该作者
用什么浮子开关啊,直接用两线悬在水边上,一个作为信号地,一个搞个100K上拉接个高阻抗输入的IO(如P0.0),然后直接读这个IO的电平就知道水有没有淹到这两根线了........

甚至不用单片机,直接搞个三极管把这个信号放大一下然后去驱动蜂鸣器,小孩的尿床告警器就这么干的!

使用特权

评论回复
7
yzhj| | 2009-9-20 21:16 | 只看该作者
有孝心固然好,但是也要考虑现实情况。

一个成品不等于画个图写段代码就行了的,还要考虑很多现实情况。例如:供电如何处理。生活用水、老人、记性不好。。。。。。综合起来一定要好好考虑周全。既要方便、耐用,更要安全、可靠。

使用特权

评论回复
8
colinzhang| | 2009-9-20 21:29 | 只看该作者
俺觉得这个贴可以展开,可惜发错地方了,  ^_^  
纯灌水哦

使用特权

评论回复
9
maychang| | 2009-9-20 21:40 | 只看该作者
回6楼:
你的这个办法,我早就用过。问题是电极接触水要生锈,贵金属不锈价格又太高,而且电极和导线上沾点水与电极接触水面往往无法区分,造成误动作,涂憎水材料如硅油成本又高了。

使用特权

评论回复
10
McuPlayer| | 2009-9-20 22:02 | 只看该作者
还是用浮子吧,简单的东西故障率低

使用特权

评论回复
11
星河绚丽| | 2009-9-20 22:15 | 只看该作者
我也来捧捧学姐的场,O(∩_∩)O~,不过小弟还没学过你写的这么复杂的程序,不能帮你啦:lol

使用特权

评论回复
12
Nopromises| | 2009-9-20 22:27 | 只看该作者
要做复杂点可以用AD7150,把PCB做成电容,可以测量液位,液位不同电容值也不同

使用特权

评论回复
13
maychang| | 2009-9-20 22:33 | 只看该作者
18B20使用时有个特点,就是不允许中断。
中断必占用时间,所以延时就不准确,结果是18B20读数错误。
楼主是否使用了中断?

使用特权

评论回复
14
呆板书生| | 2009-9-21 06:09 | 只看该作者
水温不一定低于室温,有时候还会高于室温呢。

手摸肯定觉得水比较凉,因为水的比热容大,而不是水温比室温低

使用特权

评论回复
15
for_fun|  楼主 | 2009-9-21 07:09 | 只看该作者
18B20使用时有个特点,就是不允许中断。
中断必占用时间,所以延时就不准确,结果是18B20读数错误。
楼主是否使用了中断?
maychang 发表于 2009-9-20 22:33

我没使用中断延时,都是用的while语句延时,至于延时的时间,都是用keil中的单步执行一点一点算的时间.没有想到更简单的办法.
Delay_10us(uint count)
{
       while(count--);
}

使用特权

评论回复
16
for_fun|  楼主 | 2009-9-21 07:15 | 只看该作者
有孝心固然好,但是也要考虑现实情况。

一个成品不等于画个图写段代码就行了的,还要考虑很多现实情况。例如:供电如何处理。生活用水、老人、记性不好。。。。。。综合起来一定要好好考虑周全。既要方便、耐用,更 ...
yzhj 发表于 2009-9-20 21:16

你说的甚是,这个我考虑到了,我的电路板已经焊好了,就是单片机的最小系统加个DS18B20,把它挂在水缸边上,DS18B20以探头的方式放到水缸里(外面套了层塑料袋),简单又方便,整个电路板上只有两个按键,一个复位键,一个停止键.蜂鸣器一响,告诉奶奶直接按下停止键即可.

使用特权

评论回复
17
for_fun|  楼主 | 2009-9-21 07:27 | 只看该作者
谢谢大家:)大家的想法都是我不曾想到过的,都很有创意!
我的想法有些笨拙,基本的电路已经焊好了!现在只差程序有问题了.希望大家能指出我程序的不足!:loveliness:

使用特权

评论回复
18
乌龟背蜗牛| | 2009-9-21 22:09 | 只看该作者
看见小丫了,所以我进来了。。

使用特权

评论回复
19
for_fun|  楼主 | 2009-9-26 06:55 | 只看该作者
我遇到的问题可真够多的了,不明原因,总是短路!
十一假期回来后在与你探讨!

使用特权

评论回复
20
bioe| | 2009-9-27 16:35 | 只看该作者
想法很好

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

271

帖子

0

粉丝