#ifndef DS18B20_Drive
#define DS18B20_Drive
sbit DS18B20_DQ=P5^0;
extern void DS18B20_Read_Celsius_Drive(); //DS18B20读取温度服务
extern u8 xdata DS18B20_Read_Buffer[2]; //DS18B20温度值,整数+小数
#endif
#include<all.h>
u8 xdata DS18B20_Read_Buffer[2];
//DS18B20延迟,对应30M主频
void DS18B20_Delay(u8 t)
{
EA=0; //为了让延迟时间准确,先关闭中断,再打开中断
while(t–)
{
nop(); nop();nop();nop();nop();nop();nop();
nop(); nop();nop();nop();nop();nop();nop();
nop();
}
EA=1; //良好的编程习惯很重要,比如IO口初始化
}
void DS18B20_Write_Reg(u8 Dat) //写入到DS18B20寄存器
{
u8 idata i;
for(i=0;i<8;i++)
{
DS18B20_DQ=0; //先拉低
DS18B20_Delay(15);
DS18B20_DQ=(bit)(Dat&0x01); //强制将运算结果转换为位。0101 0001 &0000 0001最低位先
Dat>>=1;
DS18B20_Delay(15);
DS18B20_DQ=1;
DS18B20_Delay(1);
}
} //写寄存器带参 ,写数据
u8 DS18B20_Read_Data(void) //从DS18B20读取数据
{
u8 idata i,Value=0;
for(i=0;i<8;i++)
{
Value>>=1; //先移位后保存。
DS18B20_DQ=0;
DS18B20_Delay(1);
DS18B20_DQ=1;
DS18B20_Delay(15); //延迟15微妙
if(DS18B20_DQ)
{
Value|=0x80; //如果高电平,最高为赋值1。 1000 0000
}
DS18B20_Delay(15);
}
return Value;
} //读取带返回值,读数据
void DS18B20_Read_Celsius_Drive() //DS18B20读取转换,读取温度
{
static xdata u16 count=0;
float num;
u8 xdata Value_High,Value_Low;
count++; //通过计数器将数据打散
switch(count)
{
case 1: DS18B20_DQ=0;break;
case 35: DS18B20_DQ=1;break; //时间长短要试验,各个开发板不一样。先复位成功
拉高之后DS18B20会有106μs的低电平应答
case 60:
DS18B20_Write_Reg(0xcc); //发送0xcc,跳过ROM指令
DS18B20_Write_Reg(0x44);
break; //启动温度转换
case 1000: DS18B20_DQ=0;break;
case 1035: DS18B20_DQ=1;break;
case 1060:
DS18B20_Write_Reg(0xcc); //发送0xcc,跳过ROM指令
DS18B20_Write_Reg(0xbe); //DS18B20会马上发送温度寄存器的数值
Value_Low=DS18B20_Read_Data(); //接收低寄存器
Value_High=DS18B20_Read_Data(); //接收高寄存器
Value_High<<=4;
Value_High+=(Value_Low&0xf0)>>4; //1111 0000 低寄存器高四位右移与高寄存器等于整数
DS18B20_Read_Buffer[0]=Value_High; //高四位,整数部分。整数直接使用
num=(Value_Low&0xf0)*0.0625; //小数部分,每个值是0.0625
DS18B20_Read_Buffer[1]=(u8)(num*100); //浮点强制转换成字符型。2位小数放大100倍变成char。
break;
case 2000:count=0;break;
}
}
/
main.c
void DS18B20_Allot()
{
DS18B20_Read_Celsius_Drive();
}