基于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公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计。
电路原理图:

实物图:

程序:
/*------------------------------------------------
*硬件: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(右键另存为)