简介
DS18B20的核心功能是直接温度-数字测量。其温度转换可由用户自定义为9、10、11、12位精度分别为0.5℃、0.25℃、0.125℃、0.0625℃分辨率。值得注意的是,上电默认为12位转换精度。DS18B20上电后工作在低功耗闲置状态下。主设备必须向DS18B20发送温度转换命令[44h]才能开始温度转换。温度转换后,温度转换的值将会保存在暂存存储器的温度寄存器中,并且DS18B20将会恢复到闲置状态。
高五位S为符号位。正温度把16进制数转成10进制即可;负温度把16进制数取反后加1再转成10进制数。
初始化
检查总线上是否存在该器件,存在就返回一个低电平脉冲,不存在,总线保持高电平。
/*
拉低引脚,持续500us
延时60us
读取存在脉冲,并等待脉冲结束
*/
bit Get18B20Ack()
{
bit ack;
EA=0; //禁止总中断
IO_18B20=0;
DelayX10us(50);
IO_18B20=1;
DelayX10us(6);
ack=IO_18B20;
while(!IO_18B20);//等待存在脉冲结束
EA=1; //使能总中断
return ack;
}
ROM操作指令
在总线上可以通过不同的器件地址来访问不同的器件
这个序列号为64位长,开始8位位产品类型编码,接着48位为每个器件的唯一的序号,最后8位为CRC校验码。
当总线上只有一个器件时,可以跳过ROM,不进行ROM检测。指令为0xCC。
RAM存储器操作指令
读暂存寄存器:0xBE (先读地位再读高位)
启动温度转换:0x44 (最大转换时间为740ms)
读写操作
写
void Write18B20(unsigned char dat)
{
unsigned char mask;
EA=0;
for(mask=0x01;mask!=0;mask<<=1)
{
IO_18B20=0;
_nop_();
_nop_();//延时2us
if((mask&dat)==0)
IO_18B20=0;
else
IO_18B20=1;
DelayX10us(6);
IO_18B20=1;
}
EA=1;
}
读
解读:单片机首先拉低这个引脚,至少保持1us,然后释放引脚,释放完毕后尽快读取,从拉低引脚倒读取引脚状态,不能超过15us,
unsigned char Read18B20()
{
unsigned char mask;
unsigned char dat;
EA=0;
for(mask=0x01;mask!=0;mask<<=1)
{
IO_18B20=0;
_nop_();
_nop_();//延时2us
IO_18B20=1;
_nop_();
_nop_();//延时2us
if(!IO_18B20)
dat&=~mask;
else
dat|=mask;
DelayX10us(6);
}
EA=1;
return dat;
}
DS18B20.c文件
#include <reg52.h>
#include <intrins.h>
sbit IO_18B20=P3^2;
void DelayX10us(unsigned char t)//延迟时间为t*10us
{
do{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}while(--t);
}
/*
拉低引脚,持续500us
延时60us
读取存在脉冲,并等待脉冲结束
*/
bit Get18B20Ack()
{
bit ack;
EA=0; //禁止总中断
IO_18B20=0;
DelayX10us(50);
IO_18B20=1;
DelayX10us(6);
ack=IO_18B20;
while(!IO_18B20);//等待存在脉冲结束
EA=1; //使能总中断
return ack;
}
void Write18B20(unsigned char dat)
{
unsigned char mask;
EA=0;
for(mask=0x01;mask!=0;mask<<=1)
{
IO_18B20=0;
_nop_();
_nop_();//延时2us
if((mask&dat)==0)
IO_18B20=0;
else
IO_18B20=1;
DelayX10us(6);
IO_18B20=1;
}
EA=1;
}
unsigned char Read18B20()
{
unsigned char mask;
unsigned char dat;
EA=0;
for(mask=0x01;mask!=0;mask<<=1)
{
IO_18B20=0;
_nop_();
_nop_();//延时2us
IO_18B20=1;
_nop_();
_nop_();//延时2us
if(!IO_18B20)
dat&=~mask;
else
dat|=mask;
DelayX10us(6);
}
EA=1;
return dat;
}
//启动温度转换操作
bit Start18B20()
{
bit ack;
ack= Get18B20Ack();
if(ack==0)
{
Write18B20(0xCC);//跳过ROM操作
Write18B20(0x44);//启动温度转换
}
return ~ack;
}
//读取温度,返回值表示是否读取成功
bit Get18B20Temp(int *temp)
{
bit ack;
unsigned char LSB,MSB;
ack= Get18B20Ack(); //获取应答
if(ack==0)
{
Write18B20(0xCC);
Write18B20(0xBE);//发送读命令
LSB=Read18B20(); //读取低位
MSB=Read18B20(); //读取高位
*temp=((int)MSB<<8)+LSB; //合成整型数
}
return ~ack;
}