疯狂单片机

一个普普通通的单片机、嵌入式学习个人博客站

基于51单片机和DS18B20的温度计

基于DS18B20的数字温度计

所需元件:

名称 数量

1.AT89S52 1
2.稳压管(7805) 1
3.12MHz晶振 1
4.22pF瓷片电容 2
5.一位断码 2
6.点解电容100uF 1
7.电解电容1uF 1
8.电阻1K 2
9.电阻4.7K 1
10.开关 1
11.led指示灯 1
12.十针插头 1
13.电源插座 1
14.温度传感器DS18B20 1  

简介:

    这是一个基于51单片机和DS18B20的温度计,这里只用两个断码作显示。所以目前的温度显示范围是-9度到99度,作为一般测室温用途是足够了;DS18B20数字温度计是DALLAS公司生产的1Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计。

 

 电路原理图:

 

 

实物图:

 

 

 程序:

/*------------------------------------------------
*硬件:AT89S52
*晶振:12MHz
*入口:main()  main.c
*日期:2009.10.22
*作者:莫旭冬
*www.mculover.com
*
*修改:
*  内容:xxx
*  人员:xxx
*  日期:xxxx.xx.xx
*
*版本:V0.0.1
*-------------------------------------------------*/

/*-----------------------说明--------------------
*函数命名规则如下:
*void ds18b20_init(void)
*uchar ds18b20_read(uint xxx)
*
*宏定义规则如下:
*#define DS18B20_USE_ALARM
*
*变量申明
*uchar = unsigned char
*uint = unsigned int
*ulong = unsigned long
*
*版本说明:0.0.1 变量参数改动为第三位0.0.1 0.0.2...
*        函数接口名称改动0.1.0 0.2.0...
*        添加功能函数1.0.0 2.0.0...
*-------------------------------------------------*/
#include "at89x52.h"
#include "ds18b20.h"

void main(void)
{
         uint data_temp=0;
         while(1)
         {
                  data_temp = ds18b20_read_temperature();//显示
                  ds18b20_show_temperature(data_temp/10,data_temp%10);
         }
}

/*--------------------------------------------------
*<ds18b20.c>功能实现
*日期:2009.10.22
*作者:莫旭冬
*修改:
*  内容:xxx
*  人员:xxx
*  日期:xxxx.xx.xx  
*--------------------------------------------------*/
#include <at89x52.h>
#include "ds18b20_type.h"
//for 12MHz
sbit DQ_BUS  = 0xA0;//P2_0
uchar DQ_SIGN = 0;//是否成功初始化标志位
code uchar led_data[10]={0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09};
                         //显示0      1        2       3      4        5       6       7       8       9
                         //对应关系a b c  d | e f g h,共阳和电流灌入方式
                         //            0 0 0 0 | 0 0 0 0 LSB  
                         //            PX_7 PX_6 ... PX_0

void delay_us(uchar delay_count);

void ds18b20_init(void)
{
         DQ_BUS = 0;
         delay_us(255);//delay 550uS(>480uS)
         DQ_BUS = 1;
         delay_us(50);//delay 100uS
         DQ_SIGN = DQ_BUS;
         if(!DQ_SIGN)
                  P2_7 = 0;//初始化成功则点亮LED
         delay_us(120);//some delay wait the bus-wire pull up
}
 
void ds18b20_write( uchar data_write)
{
         uchar i=0;
         uchar data_tmp = data_write;
         for(; i<8; i++)        
         {
                  DQ_BUS = 0;
                  delay_us(1);
                  DQ_BUS = data_tmp&0x01;
                  delay_us(30);//60<delay<120
                  DQ_BUS = 1;                                
                  data_tmp >>= 1;
                  delay_us(1);//>1uS
         }
}

uchar ds18b20_read(void)
{
         uchar data_read=0;
         uchar i=0;
         for(; i<8; i++)
         {
                  data_read >>= 1;
                  DQ_BUS = 0;
                  delay_us(1);//>1uS
                  DQ_BUS = 1;
                  if(DQ_BUS)
                           data_read |= 0x80;//first read LSB        
                  else
                           data_read |= 0x00;//可以没有
                  delay_us(7);
                  DQ_BUS = 1;
                  delay_us(1);//>1uS
         }
 return data_read;
}

uint ds18b20_read_temperature(void)
{
         uint data_temp=0;
         float data_temp_convert=0;
         uchar data_read_low=0,data_read_high=0;
         ds18b20_init();
         ds18b20_write(0xCC);
         ds18b20_write(0x44);        
         ds18b20_init();
         ds18b20_write(0xCC);
         ds18b20_write(0xBE);
         data_read_low = ds18b20_read();//先读到低字节
         data_read_high = ds18b20_read();//高字节
         data_temp = data_read_high;
         data_temp <<= 8;
         data_temp |= data_read_low;

         delay_us(255);
         delay_us(255);//delay all = 1ms
         data_temp_convert = data_temp*0.0625;
         data_temp = (int)data_temp_convert;
         return data_temp;
}

void delay_us(uchar delay_count)
{
         while(--delay_count);        
}

void ds18b20_show_temperature(uchar data_led0,uchar data_led1)
{                                                          //high-dig. low-dig.
         P3 = led_data[data_led0];//这个可以根据自己的接线来修改
         P0 = led_data[data_led1];
}

/*--------------------------------------------------
*<ds18b20.h>头文件
*日期:2009.10.22
*作者:莫旭冬
*修改:
*  内容:xxx
*  人员:xxx
*  日期:xxxx.xx.xx  
*--------------------------------------------------*/
#ifndef _DS18B20_H_
#define _DS18B20_H_
#include "ds18b20_type.h"

extern uint ds18b20_read_temperature(void);
extern void ds18b20_show_temperature(uchar data_led0,uchar data_led1);

#endif


/*--------------------------------------------------
*<ds18b20_types.h>头文件
*日期:2009.10.22
*作者:莫旭冬
*修改:
*  内容:xxx
*  人员:xxx
*  日期:xxxx.xx.xx 
*说明:编程中所遇到的数据类型和数据结构
*--------------------------------------------------*/
#ifndef _DS18B20_TYPE_H_
#define _DS18B20_TYPE_H_

typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;

#endif

程序见附件(keil工程):DS18B20_程序.rar(右键另存为)

 

« 上一篇 | 下一篇 »
  • 相关文章:
  • quote 2.莫旭冬
  • 说明一下,ds18b20的DQ和单片机连接时需要上拉电阻!这里的ds18b20采用单独5V供电。
  • 2009-10-29 12:43:08 回复该留言
  • quote 3.king森
  • 我试试,因为看起来还可以
    mxdaiyi 于 2009-11-4 12:31:11 回复
    呵呵!我测试下来发现温度自己涨上去了,原来是一直不停的读取温度造成DS18B20自身发热了,可以在main中读完一次歇个几秒再读.
  • 2009-11-3 21:06:42 回复该留言
  • quote 4.
  • 楼主。我用的时候却显示不了。我按照你的方法接的。不知道为什么错了!
  • 2010-7-23 18:25:21 回复该留言
  • quote 5.
  • 你如果有你的联系方式,请发邮箱给我!
  • 2010-7-23 18:25:57 回复该留言

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新评论及回复

最近发表

Powered By Z-Blog 1.8 Arwen Build 90619 and Theme By BokeZhuti.cn

Copyright 2009-2010 www.mculover.com All Rights Reserved. 京ICP备09098861号
站长:莫旭冬 联系邮箱:moxudong@yeah.net