“DS18B20,感知每一度细微变化,记录每一刻温暖。”#DS18B20温度传感器

前言

  本篇博文介绍的是用STC89C52RC 51单片机驱动DS18B20温度传感器,包含DS18B20核心参数,DS18B20初始化函数代码编写,向DS18B20写入一个字节函数代码编写,向DS18B20中读取一个字节数据函数代码编写,DS18B20的ROM指令表和RAM指令表,DS18B20指令使用规则,DS18B20温度转换指令函数代码编写,读DS18B20温度指令函数代码编写,读取DS18B20温度数据函数代码编写,16位温度数据处理函数代码编写,DS18B20完整驱动程序代码。看到这篇博文的朋友,可以先赞再看吗?

预备知识

  一、基本电路标识识别,例如VCC,GND。
  二、电脑基本操作复制粘贴
  三、分文件编程
  四、C变量
  五、基本输入输出
  六、流程控制
  七、函数

  如果以上知识不清楚,请自行学习后再来浏览,或者私信我。如果我有没例出的,请在评论区写一下。谢谢啦!

1.DS18B20核心参数

  1. 电压范围:3.0~5.5V
  2. DS18B20在与微处理器(单片机)连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。
  3. DS18B20在使用中不需要任何外围元件,全部传感元件及转换电路集成在形如一只三极管的集成电路内。
  4. 温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃
  5. 负压特性:电源极性接反时,芯片不会因发热而烧毁, 但不能正常工作。

在这里插入图片描述

2.DS18B20初始化函数代码编写

2.1分析DS18B20初始化时序图

在这里插入图片描述

2.2依据时序图编写相应代码

//返回1存在 返回0不存在
unsigned char initDS18B20()  //初识化DS18B20函数
{
	unsigned char i = 0;       //等待超时控制变量
	/* 以下代码是根据初始化DS18B20时序图进行编写 */
	DQ = 0;                    //先让DQ为低电平
	Delay642us();              //保持低电平642微妙
	DQ = 1;                    //再让DQ为高电平
	while(DQ)                  //如果DS18B20存在,DQ被拉低。检测是否拉低,拉低返回1
	{
		i++;                     //等待超时控制变量自增1
		Delay1ms();              //延时1毫秒
		if(i>4)                  //i加一次就延时1毫秒,大于4,相当于i = 5执行if内的语句,延时5毫秒。
		{
			return 0;              //返回没有检测到DS18B20的数据0
		}
	}
	return 1;                  //返回1
}

3.向DS18B20写入一个字节函数代码编写

3.1分析DS18B20写时序图

在这里插入图片描述

3.2依据时序图编写相应代码

void writeByteDS18B20(unsigned char DSdata)   //向DS18B20写1个字节数据函数
{
	unsigned char i;                            //for循环控制变量i
	/* 以下代码是根据写DS18B20时序图进行编写 */
	for(i=0; i<8; i++)                          //循环执行8次
	{
		DQ = 0;                                   //先让DQ为低电平       
		Delay15us();                              //保持低电平15微妙
		DQ = DSdata & 0x01;                       //让要发送的数据和0x01相与,以达到把数据的最低位发送给DS18B20,因为发送数据是从低位开始发送
		Delay60us();                              //等待60微妙发送1位数据
		DQ = 1;                                   //让DQ为高电平
		DSdata = DSdata >> 1;                     //让需要发送的数据右移一位,准备次低位以便下一次循环发送
	}
}

-----------------------------------------------------------------------------------------------------------------
数据处理代码分析

DQ = DSdata & 0x01;
DSdata是要写入DS18B20的数据,如写入 1100 0011
    1100 0011
&   0000 0001
=   0000 0001
通过与运算后数据变成了0x01,也就是发送了最低位的数据给DQ

DSdata = DSdata >> 1;
DSdata右移一位,准备次低位以便下一次循环发送
    1100 0011
>>1 0110 0001
    
这样循环执行8次即可写入一个字节数据

4.向DS18B20中读取一个字节数据函数代码编写

4.1分析SD18B20读时序图

在这里插入图片描述

4.2依据时序图编写相应代码

unsigned char readByteDS18B20()               //向DS18B20读取1字节数据函数
{
	unsigned char i;                            //for循环控制变量i
	unsigned char tmp,dataDs;                   //过度变量tmp,暂时存放读取到的1位数据,完整1字节读取数据变量datyDs
	/* 以下代码是根据读DS18B20时序图进行编写 */
	for(i=0; i<8; i++)                          //循环执行8次
	{
		DQ = 0;                                   //让DQ为低电平
		_nop_();                                  //执行一个空函数经过5微妙,时序图中是大于1微妙,符合
		DQ = 1;                                   //让DQ为高电平,释放总线准备读取数据
		Delay10us();                              //延时10微妙等待总线被释放
		tmp = DQ;                                 //将DS18B20的1位数据读入tmp
		dataDs =(dataDs >> 1)|(tmp << 7);         //先让dataDs右移一位再与左移7位的tmp相或实现将tmp中的数据从左装入dataDs.
		Delay45us();                              //延时45微妙,等待读取一位数据
	}
	
	return dataDs;                              //返回读取到的数据
}

-----------------------------------------------------------------------------------------------------------------
数据处理代码分析

dataDs =(dataDs >> 1)|(tmp << 7);
先让dataDs右移一位再与左移7位的tmp相或实现将tmp中的数据从左装入;如
    dataDs  = 0000 0000
    tmp     = 0000 0001
dataDs >> 1 = 0000 0000
tmp    << 7 = 1000 0000
dataDs | tmp= 1000 0000
第二次
    dataDs  = 1000 0000
    tmp     = 0000 0001
dataDs >> 1 = 0100 0000
tmp    << 7 = 1000 0000
dataDs | tmp= 1100 0000
注意DQ存入tmp的数据从低位存入
    
这样循环执行8次即可完成一个字节的读取

5.DS18B20的ROM指令表和RAM指令表

5.1ROM指令表

在这里插入图片描述

  使用标记的指令即可

5.2RAM指令表

在这里插入图片描述

  使用标记的指令即可

6.DS18B20指令使用规则

  使用顺序为先ROM再RAM,不能先ROM再RAM在RAM,这样会出问题。

7.DS18B20温度转换指令函数代码编写

7.1温度转换指令代码编写思路

  初始化——>等待1毫秒初始化——>跳过ROM——>向RAM写入温度转换指令0x44

7.2温度转换指令函数代码

void changTmDS18NB20()                        //DS18B20温度转换指令函数
{
	initDS18B20();                              //先初始化DS18B20
	Delay1ms();                                 //等待1毫秒让DS18B20初始化完毕
	writeByteDS18B20(0xcc);                     //向DS18B20写入跳过ROM指令0xcc
	writeByteDS18B20(0x44);                     //向DS18B20的RAM中写入温度转换指令0x44
}

8.读DS18B20温度指令函数代码编写

8.1读取温度指令代码编写思路

  初始化——>等待1毫秒初始化——>跳过ROM——>向RAM写入读温度指令0xbe

8.2读取温度指令函数代码

void readTmHandlerDS18B20()                   //读DS18B20温度指令函数
{
	initDS18B20();                              //先初始化DS18B20
	Delay1ms();                                 //等待1毫秒让DS18B20初始化完毕
	writeByteDS18B20(0xcc);                     //向DS18B20写入跳过ROM指令0xcc
	writeByteDS18B20(0xbe);	                    //向DS18B20的RAM中写入读取数据指令0xbe
}

9.读取DS18B20温度数据函数代码编写

9.1DS18B20传数据规则

  DS18B20采用16位存储数据,分为两个8位RAM存储,一个存放高八位,一个存放低八位。在传温度数据时先传低位再传高位

9.2读取温度数据代码编写思路

  发送温度转换命令——>发送读取温度数据指令——>读取低8位温度数据——>读取高8位温度数据——>高低8位数据组合成一个16位的数据

9.3读取温度数据函数代码

int readTmDataDS18B20()                       //读取DS18B20数据函数
{
	unsigned char tmh,tml;                      //DS18B20传回的数据是16位的,分位高8和低8位,tmh高8,tml低8
	int temp = 0;                               //存放16位温度变量temp
	changTmDS18NB20();                          //让DS18B20转换温度
	readTmHandlerDS18B20();                     //让DS18B20准备读取数据
	tml  = readByteDS18B20();                   //读取数据是从低八为开始读;读低八位数据到tml
	tmh  = readByteDS18B20();                   //读高八位数据到tmh
	temp = tmh;                                 //把高8位数据存入temp
	temp = temp << 8;                           //把temp左移8位,给低八位留位置
	temp |=tml;                                 //让temp与低8位tml相或实现存入低8位
	
	return temp;                                //返回完整16位温度数据
}

-----------------------------------------------------------------------------------------------------------------
数据处理代码分析
    
temp = temp << 8;
把temp左移8位,给低八位留位置
temp为整型,占两个字节(16位)
temp存数据时从低位开始存;如:
temp       = 0000 0000 1100 0011
temp << 8  = 1100 0011 0000 0000

temp |=tml;
让temp与低8位tml相或实现存入低8位
tml和tmh为字符型,占8位一个字节;如:
tml                  = 1100 0011
temp       = 1100 0011 0000 0000
temp | tml = 1100 0011 1100 0011

这样就实现了两个8位拼接成一个16位的数据

10. 16位温度数据处理函数代码编写

10.1DS18B20温度转换规则

  温度传感器的精度为用户可编程的9101112位,分别以0.5℃0.25℃0.125℃0.0625℃增量递增。在上电状态下默认的精度为12位

  这是12位转化后得到的12位数据,存储在DS18B20的两个8位的RAM中,高字节的前5位是符号位,如果测得的温度大于0,这5位为‘0’,只要将测到的数值乘以0.0625即可得到实际温度;如果温度小于0,这5位为‘1’,测到的数值需要先减1再取反再乘以0.0625即可得到实际温度。

  温度寄存器格式表

在这里插入图片描述

  注意:标记处为符号位

  温度数据关系表

在这里插入图片描述

  注意:标记处代表了在做有关温度控制的项目时要对温度做多重判断,以免出现bug。

10.2 16位温度数据处理函数代码

int tmDataHandler()                           //16位温度数据处理函数
{
	int temp;                                   //处理后的温度数据存放变量temp
	float tmp;                                  //温度数据处理临时变量
	temp = readTmDataDS18B20();                 //把读取到的温度数据存入temp
	
	if(temp < 0)                                //温度为负数
	{
		temp--;                                   //温度数据减一
		temp = !temp;                             //温度数据取反
		tmp = temp;                               //整型数据温度存入浮点型温度处理临时变量tmp中,实现强转为浮点型
		temp = tmp * 0.0625 * 100;                //将浮点型的温度数乘以精度数据0.0625实现真正温度数据转换,*100将数据扩大100倍实现从两位数变到4位数,以便数码管显示数据时使用
	}
	else                                        //温度为正数
	{
		tmp = temp;                               //整型数据温度存入浮点型温度处理临时变量tmp中,实现强转为浮点型            
		temp = tmp * 0.0652 * 100;                //将浮点型的温度数乘以精度数据0.0625实现真正温度数据转换,*100将数据扩大100倍实现从两位数变到4位数,以便数码管显示数据时使用
	}

	return temp;                                //返回处理后的温度数据
}

-----------------------------------------------------------------------------------------------------------------
温度数据处理分析已写入代码注释,请认真看,不懂私信我。

11.DS18B20完整驱动程序代码

#include "reg52.h"        			//51单片机基本库
#include "delay.h"              //DS18B20单总线时序需要使用到演示函数
#include "intrins.h"            //DS18B20单总线时序需要使用到空函数

sbit DQ = P2^4;                 //DS18B20数据端接单片机P2.4口

//返回1存在 返回0不存在
unsigned char initDS18B20()  //初识化DS18B20函数
{
	unsigned char i = 0;       //等待超时控制变量
	/* 以下代码是根据初始化DS18B20时序图进行编写 */
	DQ = 0;                    //先让DQ为低电平
	Delay642us();              //保持低电平642微妙
	DQ = 1;                    //再让DQ为高电平
	while(DQ)                  //如果DS18B20存在,DQ被拉低。检测是否拉低,拉低返回1
	{
		i++;                     //等待超时控制变量自增1
		Delay1ms();              //延时1毫秒
		if(i>4)                  //i加一次就延时1毫秒,大于4,相当于i = 5执行if内的语句,延时5毫秒。
		{
			return 0;              //返回没有检测到DS18B20的数据0
		}
	}
	return 1;                  //返回1
}

void writeByteDS18B20(unsigned char DSdata)   //向DS18B20写1个字节数据函数
{
	unsigned char i;                            //for循环控制变量i
	/* 以下代码是根据写DS18B20时序图进行编写 */
	for(i=0; i<8; i++)                          //循环执行8次
	{
		DQ = 0;                                   //先让DQ为低电平       
		Delay15us();                              //保持低电平15微妙
		DQ = DSdata & 0x01;                       //让要发送的数据和0x01相与,以达到把数据的最低位发送给DS18B20,因为发送数据是从低位开始发送
		Delay60us();                              //等待60微妙发送1位数据
		DQ = 1;                                   //让DQ为高电平
		DSdata = DSdata >> 1;                     //让需要发送的数据右移一位,准备次低位以便下一次循环发送
	}
}

unsigned char readByteDS18B20()               //向DS18B20读取1字节数据函数
{
	unsigned char i;                            //for循环控制变量i
	unsigned char tmp,dataDs;                   //过度变量tmp,暂时存放读取到的1位数据,完整1字节读取数据变量datyDs
	/* 以下代码是根据读DS18B20时序图进行编写 */
	for(i=0; i<8; i++)                          //循环执行8次
	{
		DQ = 0;                                   //让DQ为低电平
		_nop_();                                  //执行一个空函数经过5微妙,时序图中是大于1微妙,符合
		DQ = 1;                                   //让DQ为高电平,释放总线准备读取数据
		Delay10us();                              //延时10微妙等待总线被释放
		tmp = DQ;                                 //将DS18B20的1位数据读入tmp
		dataDs =(dataDs >> 1)|(tmp << 7);         //先让dataDs右移一位再与左移7位的tmp相或实现将tmp中的数据从左装入dataDs.
		Delay45us();                              //延时45微妙,等待读取一位数据
	}
	
	return dataDs;                              //返回读取到的数据
}

void changTmDS18NB20()                        //DS18B20温度转换指令函数
{
	initDS18B20();                              //先初始化DS18B20
	Delay1ms();                                 //等待1毫秒让DS18B20初始化完毕
	writeByteDS18B20(0xcc);                     //向DS18B20写入跳过ROM指令0xcc
	writeByteDS18B20(0x44);                     //向DS18B20的RAM中写入温度转换指令0x44
}

void readTmHandlerDS18B20()                   //读DS18B20温度指令函数
{
	initDS18B20();                              //先初始化DS18B20
	Delay1ms();                                 //等待1毫秒让DS18B20初始化完毕
	writeByteDS18B20(0xcc);                     //向DS18B20写入跳过ROM指令0xcc
	writeByteDS18B20(0xbe);	                    //向DS18B20的RAM中写入读取数据指令0xbe
}

int readTmDataDS18B20()                       //读取DS18B20数据函数
{
	unsigned char tmh,tml;                      //DS18B20传回的数据是16位的,分位高8和低8位,tmh高8,tml低8
	int temp = 0;                               //存放16位温度变量temp
	changTmDS18NB20();                          //让DS18B20转换温度
	readTmHandlerDS18B20();                     //让DS18B20准备读取数据
	tml  = readByteDS18B20();                   //读取数据是从低八为开始读;读低八位数据到tml
	tmh  = readByteDS18B20();                   //读高八位数据到tmh
	temp = tmh;                                 //把高8位数据存入temp
	temp = temp << 8;                           //把temp左移8位,给低八位留位置
	temp |=tml;                                 //让temp与低8位tml相或实现存入低8位
	
	return temp;                                //返回完整16位温度数据
}

int tmDataHandler()                           //16位温度数据处理函数
{
	int temp;                                   //处理后的温度数据存放变量temp
	float tmp;                                  //温度数据处理临时变量
	temp = readTmDataDS18B20();                 //把读取到的温度数据存入temp
	
	if(temp < 0)                                //温度为负数
	{
		temp--;                                   //温度数据减一
		temp = !temp;                             //温度数据取反
		tmp = temp;                               //整型数据温度存入浮点型温度处理临时变量tmp中,实现强转为浮点型
		temp = tmp * 0.0625 * 100;                //将浮点型的温度数乘以精度数据0.0625实现真正温度数据转换,*100将数据扩大100倍实现从两位数变到4位数,以便数码管显示数据时使用
	}
	else                                        //温度为正数
	{
		tmp = temp;                               //整型数据温度存入浮点型温度处理临时变量tmp中,实现强转为浮点型            
		temp = tmp * 0.0652 * 100;                //将浮点型的温度数乘以精度数据0.0625实现真正温度数据转换,*100将数据扩大100倍实现从两位数变到4位数,以便数码管显示数据时使用
	}

	return temp;                                //返回处理后的温度数据
}

结束语

  很高兴您能看到这里,点个赞再走呗。谢谢您啦!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值