原创作品,如有转载,请表明出处和作者。
/**********************************************************************
注:
调用时,直接引用函数GetTempValue()的返回值。在进入主循环之前,最好先启动一次温度转换,然后延时1S,让18B20稳定。
整理时间: 2007年01月12日(鱼儿不上钩)
*******************************************************************/#include<reg51.h>
#include<stdio.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
//********************** DS18B20
指令*********************
#define
ds18B20_READ_ROM
0x33
// 读ROM指令
#define
ds18B20_MATCH_ROM
0x55
// 匹配ROM指令
#define
ds18B20_SKIP_ROM
0xCC
// 跳过ROM指令
#define
ds18B20_SEARCH_ROM
0xF0
// 搜索ROM指令
#define
ds18B20_ALARM_SEARCH
0xEC
// 报警搜索指令
#define ds18B20_WRITE_SCRATCHPAD
0x4E
// 写暂存寄存器指令
#define ds18B20_READ_SCRATCHPAD
0xBE
// 读暂存寄存器指令
#define ds18B20_COPY_SCRATCHPAD
0x48
// 复制暂存寄存器指令
#define
ds18B20_CONVERT_T
0x44
// 启动温度转换指令
#define
ds18B20_RECALL_E2
0xB8
// 重新调出E2PROM的数据
#define ds18B20_READ_POWER_SUPPLY
0xB4
// 读电源
sbit ds18B20_data =
P1^3;
//温度探头数据端口对应的单片机引脚
//*********************温度探头程序************************
bit
Rstds18B20(void);
// DS18B20复位程序, 返回0-有设备连接,1-无设备连接
void Writeds18B20(uchar
);
// 写一个字节ds18B20数据、命令子程序
uchar
Readds18B20(void);
// 读一个字节ds18B20数据子程序
uint
GetTempValue(void);
// 启动ds18B20温度转换程序
//******************************************************************
//
ds18B20复位程序
//******************************************************************
bit
Rstds18B20(void)
// 返回,0-有设备连接;1-无设备连接
{
uchar i;
bit RstFlag;
RstFlag = 1;
ds18B20_data = 1;
_nop_();
ds18B20_data =
0;
// 发送复位脉冲,时间>480us
Delay_15us(40);
// 延时480--960us
ds18B20_data =
1;
// 拉高总线,延时15us-60us后等待ds18B20响应
Delay_15us(2);
// 15us-60us
for
(i=0;i<6;i++) //
60us-240us
{
Delay_15us(1);
if (ds18B20_data==0)
RstFlag=0;
// 接收ds18B20的存在信号
}
Delay_15us(15);
// 240us
return RstFlag;
}
//*******************写一个字节ds18B20数据、命令子程序******************
//功能:向ds18B20写入数据或命令
//入口:待写入ds18B20的数据或命令
//出口:无
//******************************************************************
void Writeds18B20(uchar ch)
{
uchar i;
ds18B20_data =
1;
// 拉高总线,延时1us,准备启动
_nop_();
for (i=0;i<8;i++)
{
ds18B20_data =
0;
// 拉低总线
Delay_10us();
// 延时10us
ds18B20_data =
ch&0x1; //
发送待写入的数据,“1”或“0”
Delay_15us(2);
// 保持写入数据时间45us
ds18B20_data =
1;
// 拉高总线,延时1us后准备下一位传输
ch =
ch>>1;
//先写低位,后写高位
_nop_();
}
}
//******************读一个字节ds18B20数据子程序************************
//功能:从ds18B20读出数据
//入口:无
//出口:读出的ds18B20的数据
//******************************************************************
uchar Readds18B20(void)
{
uchar i,ch;
ch = 0;
ds18B20_data =
1;
// 拉高总线,延时1us,准备启动
_nop_();
for (i=0;i<8;i++)
{
ds18B20_data =
0;
// 拉低总线
Delay_10us();
// 延时10us
ds18B20_data =
1;
// 拉高总线,准备接收数据
_nop_();
ch = ch>>1;
if (ds18B20_data ==
1) // 接收ds18B20的数据
ch =
ch+0x80;
Delay_15us(2);
// 延时45us,保证整个读命令有60us
}
return ch;
}
//*************************启动ds18B20温度转换程序*********************
//功能:读取18B20的温度值
//入口:无
//出口:0xffff-18B20不正常
//
0x8000-温度低于零度
//
0~1250-摄氏温度(0~125)
//******************************************************************
uint GetTempValue(void)
{
uchar i=0,j=0;
uint T=0;
if(!Rstds18B20())
//如果探头连接正常
{
Rstds18B20();
// 复位ds18B20
Writeds18B20(ds18B20_SKIP_ROM);
// 跳过ROM操作
Writeds18B20(ds18B20_CONVERT_T);
// 启动ds18B20温度转换
if(!Rstds18B20())
//如果探头连接正常
{
Rstds18B20();
// 复位ds18B20
Writeds18B20(ds18B20_SKIP_ROM);
// 跳过ROM操作
Writeds18B20(ds18B20_READ_SCRATCHPAD);
// 发读ds18B20数据,前两位是温度值
i =
Readds18B20();
// 温度值的低位数据
j =
Readds18B20();
// 温度值的高位数据
T = i+(j<<8);
if (T==0xffff) |