#ifndef __DS18B20_H__
#define __DS18B20_H__
#include <intrins.h>
typedef unsigned int uint;
typedef unsigned char uchar;
sbit DQ = P1 ^ 4;
void delay_2us(uint t) //延时(2*t)us
{
while (--t);
}
bit init_18b20(void) //初始化18B20函数
{
bit init_flag = 0;
DQ = 1;
delay_2us(1);
DQ = 0; //从高拉至低以产生写时间隙
delay_2us(250); //最短为480us的低电平复位信号
DQ = 1; //释放总线并进入接收状态
delay_2us(10); //15us<等待时间<80us
init_flag = DQ; //18B20发出存在脉冲(低电平)
delay_2us(40);
return init_flag; //返回初始化结果,0正确,1错误
}
void write_18b20(uchar dat) //通过单总线向从器件写一个字节(从低位开始)
{
uchar i;
for (i=0; i<8; i++)
{
DQ = 1;
_nop_();
DQ = 0; //总线拉低后15us内给数据
DQ = dat & 0x01; //单片机给数据
delay_2us(15); //大约在30us时刻18b20读取
DQ = 1; //拉高,本次写时间隙结束
dat >>= 1;
}
delay_2us(5);
}
uchar read_18b20(void)//从18B20中读取一个字节
{
uchar i,dat;
for (i=0; i<8; i++)
{
DQ = 0; //拉低开始读时间隙
dat >>= 1;
DQ = 1; //单片机释放总线
if (DQ) //18b20有效数据出现
{
dat |= 0x80;
}
delay_2us(30); //从时序开始共延时15us
}
return dat;
}
/*此算法读取的数据包括整数部分和小数部分及负温度值*/
uint read_temp(void) //温度转换、读取及处理函数
{
uchar low,high;
uint temp; //由于read_temp()返回的是16位数据,因此必须声明一个uint型变量来存储!!!
init_18b20();
write_18b20(0xcc); //写指令:跳过ROM,仅一个DS18B20
write_18b20(0x44); //启动温度转换
init_18b20();
write_18b20(0xcc); //写指令:跳过ROM,仅一个DS18B20
write_18b20(0xbe); //读暂存寄存器
low = read_18b20(); //读低8位
high = read_18b20(); //读高8位
temp = (high << 8); ////这两行必须分开写,这样写temp=high<<8+low出现的结果不正确!
temp |= low; //此时temp得到的是16位的全部数据,高5位是符号位
return temp;
}
#endif