你认识的第一款温度传感器——DS18B20 (一)

DS18B20是一种数字温度传感器,常用于温度监测、控制等领域。

它有三个脚,如图所示

DQ是信号线,经过4.7K上拉电阻(当连接的单片机io口不能确定电平的时候,DQ将走4.7K这条路,达到+5V)接到+5v ;

单总线时序:一根线来传输信号,因此要求比较严格,所有的信号(由0和1组成的一串按照规定高低变化的电平,相当于打一套拳,一下高一下低我们称为时序)都在这上面传达:例如复位,写0,写1,读0,读1

因此,在通信前,需要进行初始化操作。(想详细了解一个元件的使用,需要下载它的数据手册有详细介绍)

上图是它的内部结构,看不懂没关系不影响使用。64位的ROM相当于可以存放它们的身份证号,以便于在一条线上连接多个DS18B20

 暂存器是RAM寄存器(图里面看),就是相当于一个可以存放数据的小房子。

接下来我们来看如何通过特定操作来实现这套时序的打法:

 粗黑线表示单片机的动作:

浅灰线表示从机(DS18B20)的动作:

戏黑线表示上拉电阻的动作:

初始化:

1.发出一个至少480us的低电平脉冲(常取600us)

2.释放总线变为高电平,持续时间为15u~60us(常取60us)

3.若有低电平出现则说明总线上有器件做出应答,将总线电平拉低60~240us, 告知主机器件已经做好准备

4.若没有检测到则一直在检测,停止等待。

uchar DS18B20_Init()
{
	bit ackset;
	DS18B20_IO = 0;
	delay_us(600);
	DS18B20_IO = 1;
	delay_us(60);
	ackset = DS18B20_IO;
	while(!DS18B20_IO);
	return ackset;
}

写0和写1:

 1.单片机直接将引脚拉低

2.写1的时候,单片机先将这个引脚拉低,拉低时间大于 1us,然后马上释放总线,DS18B20 会在15us 到 60us 之间来读取这个被上拉电阻拉高的 1。

3.写0的时候,单片机先将这个引脚拉低,然后马上释放总线,DS18B20 会在15us 到 60us 之间来读取这个仍然被主机置 的0。

void DS18B20_WriteByte(uchar dat)//定义一个函数,有个形参dat:代表单片机往DS1302要写入的数据
这里是写字节,1字节Byte是8bit (8个01比特)
{
	uchar detect;//辅助变量
	for(detect = 0x01;detect !=0; detect <<1)//循环左移,判断detect不是0就继续,为0停止,来八次
	{
		DS18B20_IO = 0;//先拉低
		_nop_();_nop_();//_nop_: 51单片机中封装好的函数,相当于机器执行一条指令的时间,用于延时,在晶振为12MHz时候大约1us  需包含  #include “intrins.h”  间隔2us


		if((detect&dat)==0)
			DS18B20_IO = 0;
		else
			DS18B20_IO = 1;
		delay_us(60);//等待它采集存入
		DS18B20_IO = 1;	
	}
}

1.例如想写入dat:10101101

最低位相与(&)然后判断是否为0,发现写的不是0,执行else IO置1

倒数第2位相与(&)然后判断是否为0,发现是0,执行IO置0

2.延时60us,让从机采集数据存入自己的房间

3.最后io口置1,回到初始的默认拉高状态,预备下一次操作

读0和读1:

 1.单片机首先要拉低引脚

2.至少保持1us 的时间,然后释放引脚

3.从拉低这个引脚到读取引脚状态,不能超过 15us。先读低位,再读高位!

留给大家思考

uchar DS18B20_ReadByte()
            {
	        uchar udat,detect;
	        for(detect = 0x01;detect!=0;detect<<=1)
	       {
	               DS18B20_IO = 0;
	                 _nop_();_nop_();
		DS18B20_IO = 1;
		_nop_();_nop_();
		if(DS18B20_IO)
		{
		 	udat = udat|detect;
		}
		else
		{
			 udat = udat&(~detect);
		}
		delay_us(60);	
	        }
	        return udat;	
             }

初始化,读,写三个强大的武器被我们制作好啦!!!

接下来就是利用上面的武器进行作战了!

第一步:初始化;

第二步:发出跳过ROM匹配指令【CCH】;(当总线上只有一个器件的时候,可以跳过ROM,不进行ROM检测,不用查身份证,因为只有一个人)

第三步:发出温度转换命令【44H】;

第四步:初始化;

第五步:发出跳过ROM匹配指令【CCH】;

第六步:发出读暂存器命令【BEH】;

第七步:读取RAM暂存器中的前两个字节,分别为低字节和高字节。

指令类型

指令

功能

详细描述

ROM指令

[CCH]

忽略ROM指令

允许总线控制器不用提供ROM编码就能使用该功能

功能指令

[44H]

温度转换指令

用来控制DS18B20启动一次温度转换,生成的数据以2字节形式存储在高速暂存器中

[BEH]

读暂存器指令

读取DS18B20暂存器数据,读取将从0字节开始到第8字节结束。

此处的低位高位就是用来存放DS18B20将温度转换成二进制数值。

byte4:用来设置温度精度,测量温度也需要有最小单位,像一把尺子,最小刻度可以是1mm,1cm。实际只需要操作bit6和bit5,排列组合有四种精度和最大转换时间可供选择。

 

注意看高位的前5bit 是s(五个1为负),代表符号位(可以表示正负温度)

低位的bit4是个位,bit5是十位,bit3是小数。以此类推:最低四位表小数

 上电默认精度就是0.0625℃

也就是

0000 0000 0000 0000 表示0℃

0000 0000 0000 0001 表示0.0625℃ 2的-4次方,        注意:本来按照计算机中的存放规则,最低位是2的0次方,这里面的寄存器为了表示小数,将2的0次方向左👈挪动了四位(扩大了16倍,每向左挪一位就相当于乘2)

写程序啦:

//DS18B20指令 见上面的图,先给大家取个名字
#define DS18B20_SKIP_ROM			0xCC
#define DS18B20_CONVERT_T			0x44
#define DS18B20_READ_SCRATCHPAD 	0xBE

void DS18B20_ConvertT(void)
{
	OneWire_Init();//初始化
	OneWire_SendByte(DS18B20_SKIP_ROM);//忽略查验大家的身份证,只有一个从机
	OneWire_SendByte(DS18B20_CONVERT_T);//开始温度转换
}
float DS18B20_ReadT(void)//定义一个返回值类型是浮点数(带小数点的)的函数
{
	unsigned char TLSB,TMSB;//定义无符号是2个变量,每个变量一个字节(8bit)
	int Temp;//定义有符号数整形变量,两个字节16位
	float T;
	DS18B20_Init();//初始化
	DS18B20_ReadByte(DS18B20_SKIP_ROM);
	DS18B20_WirteByte(DS18B20_READ_SCRATCHPAD);
	TLSB=DS18B20_ReadByte();//读取,放入TLSB
	TMSB=DS18B20_ReadByte();//读取,放入TLSB
	Temp=(TMSB<<8)|TLSB;//强制类型转换后,高位左移8位,低位放进低8位两个数拼在一起
	T=Temp/16.0;//跟实际相比大了十六倍,给他还原,同时带小数点,不让他丢失精度
	return T;//返回这个浮点温度值
}

这个返回的T就可以送去显示啦,大功告成!

显示可以用LCD1602;数码管;OLED,以后逐一介绍哦

还可以通过串口发送给电脑哦

还可以通过无线模块传输哦

十分有趣!

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猪之康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值