51单片机之DS18B20

一文读懂DS18B20温度传感器及编程

对于新手而言, DS18B20基本概念仅做了解,最重要的是利用单片机对DS18B20进行编程,读取温度信息,并把读取到的温度信息利用数码管,LCD1602或者上位机进行显示

初识DS18B20

DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。 [1] DS18B20数字温度传感器接线方便,封装 成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有LTM8877,LTM8874等等。

适用场景
该产品适用于冷冻库,粮仓,储罐,电讯机房,电力机房,电缆线槽等测温和控制领域。轴瓦,缸体,纺机,空调,等狭小空间工业设备测温和控制。
汽车空调、冰箱、冷柜、以及中低温干燥箱等。
供热/制冷管道热量计量,中央空调分户热能计量和工业领域测温和控制。

特点
1.1、适应电压范围更宽,电压范围:3.0~5.5V,在寄生电源方式下可由数 据线供电
1.2、独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯
1.3、 DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上,实现组网多点测温
1.4、DS18B20在使用中不需要任何外围元件,全部 传感元件及转换电路集成在形如一只三极管的集成电路内
1.5、温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃
1.6、可编程 的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃,可实现高精度测温
1.7、在9位分辨率时最多在 93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字,速度更快
1.8、测量结果直接输出数字温度信号,以"一 线总线"串行传送给CPU,同时可传送CRC校验码,具有极强的抗干扰纠错能力
1.9、负压特性:电源极性接反时,芯片不会因发热而烧毁, 但不能正常工作。

DS18B20引脚定义
51单片机之DS18B20_第1张图片

从图中可以看到DS18B20有三个引脚,其中GND接地,VCC接电源,DQ与单片机的一个I/O相连,所以DS18B20采用的是单总线方式,只需要一根线连接到单片机的I/O口即可

DS18B20自带A/D转换芯片,所以我们只需要通过51单片机唤醒DS18B20,设置DS18B20的工作状态,以及从DS18B20的寄存器中读出温度值即可,要注意负温度以补码的形式存储,读取后要进行码值的转换

代码

我们需要构建4个函数

  1. 向DS18B20写入一个字节的函数
  2. 从DS18B20读取一个字节的函数
  3. DS18B20初始化函数
  4. 从DS18B20寄存器读取温度的函数,该函数需要调用2函数,也就是通讯桥梁

1,2函数相当于单片机通过I/0口与DS18B20通讯的桥梁,无论是唤醒DS18B20,还是找到DS18B20的地址,亦或是从DS18B20的寄存器读取A/D转换后的温度值都需要这两个桥梁,桥梁就是通讯的规则,也就是DS18B20器件的时序图,时序图可在DS18B20的芯片手册里找到

但对于新手而言,可能不懂得时序的操作,但不要丧气,因为有人已经把时序对应的函数写好了,我们只需要借用即可,也就是常说的不要重复造轮子

编程实例

需特别注意延时函数需要结合自己单片机的晶振去写,delay(10us)代表延时10微妙,delay(10Ms)代表延时10毫秒

#include
#include
#define uchar unsigned char
#define uint  unsigned int
sbit DQ=P1^0;                         //定义DS18B20端口
void WriteOneChar(uchar dat);        //单片机向DS18B20写一个字节数据的函数
uchar ReadOneChar(void);            //单片机从DS18B20读一个字节数据的函数
bit Init_DS18B20(void);            //DS18B20初始化函数
uint ReadTemperature(void);       //从DS18B20读取温度函数


**D18B20写入一个字节函数**
void WriteOneChar(uchar dat)
{
uchar i=0;
for (i=8; i>0; i--)
{
  DQ = 0;
  DQ = dat&0x01;
  Delay(50us);
  DQ = 1;
  dat>>=1;
}
Delay(50us);
}



**DS18B20读取一个字节函数**
uchar ReadOneChar()
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
  DQ = 0; // 给脉冲信号
  dat>>=1;
  DQ = 1; // 给脉冲信号
  if(DQ)
   dat|=0x80;
  Delay(50us);
}
return(dat);
}



**DS18B20初始化函数**
bit Init_DS18B20(void)
{
bit dat=0;
DQ = 1;    			     //DQ复位
Delay(10us);  	 	    //稍做延时
DQ = 0;      		   //单片机将DQ拉低
Delay(800us); 		  //精确延时 大于 480us 小于960us
DQ = 1;       		 //拉高总线
Delay(100us); 		//15~60us 后 接收60-240us的存在脉冲
dat=DQ;            //如果x=0则初始化成功, x=1则初始化失败
Delay(50us);      //稍作延时返回
return dat;
}




**DS18B20读取温度函数**
uint ReadTemperature()
{
uchar a=0;
uint b=0;
uint t=0;
Init_DS18B20();
WriteOneChar(0xCC);  // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
Delay(10MS);
Init_DS18B20();
WriteOneChar(0xCC);  //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar();   //低位
b=ReadOneChar();  //高位


b<<=8;
t=a+b;


return(t);//**返回读取到的温度值**
}




**定时器初始化函数**
定时器的作用是控制读取DS18B20温度的时间间隔
void Init_Timer0(void)
{
 TMOD = 0x01;	  //使用模式1,16位定时器
 
 EA=1;            //总中断打开
 ET0=1;           //定时器中断打开
 TR0=1;           //定时器开关打开
}



**定时器中断函数**
void Timer0_isr(void) interrupt 1 
{
 static unsigned int num;
 TH0=(65536-2000)/256;		  //重新赋值 2ms
 TL0=(65536-2000)%256;
 
 num++;
 if(num==30)        //可通过挑整if条件判断语句控制时间间隔
   {
    num=0;
    ReadTempFlag=1; //读标志位置1
	}

}


char displaytemp[10]; //该数组存放读取到的温度值
bit  ReadTempFlag;   //定义一个读取DS18B20温度的标志
float temperature;  //定义温度值 


void main()
{
int temp;
if(ReadTempFlag==1)
			 {
				ReadTempFlag=0;
				temp=ReadTemperature();
			    temperature=(float)temp*0.0625;//最终读取到的温度值,可以把它放到一个数组里面,以便于LCD1602或者数码管显示
				sprintf(displaytemp,"%6.2f",temperature);//sprintf函数在头文件中
			}	

你可能感兴趣的:(单片机,嵌入式)