目录

DS18B20介绍

模拟温度传感器的基本结构

数字温度传感器的应用

引脚及应用电路

DS18B20的原理图

DS18B20内部结构框图

暂存器内部

单总线介绍

单总线电路规范

单总线时序结构

初始化

发送一位

发送一个字节

接收一位

接收一个字节

DS18B20操作流程

指令介绍

ROM指令

功能指令

DS18B20数据帧

温度变换

温度读取

温度存储格式


DS18B20介绍

DS18B20是一种常见的数字温度传感器,其控制命令和数据都是以数字信号的方式输入输出,相比较于模拟温度传感器,具有功能强大、硬件简单、易扩展、抗干扰性强等特点

测温范围:-55°C 到 +125°C

通信接口:1-Wire(单总线)

其它特征:可形成总线结构(可以在一条通信线上挂很多设备,这样就可以节省IO口,这样单片机一个IO口就可以读很多个温度传感器)、内置温度报警功能可寄生供电因为数字温度传感器的三个引脚当中,有两个是供电的,一个是数据输入输出的,如果使用寄生供电的话,那么VCC电源正极就不用接了,直接一个数据线和一个GND就可以实现数据通信,这样十分省线路

 DS18B20这个模块就在我们开发板上的这个位置:

这个温度传感器是可以拔下来的

模拟温度传感器的基本结构

通过上图我们知道模拟温度传感器的结构比较复杂,我们最后读取到的温度只是正比于我们的温度,我们还得对这个数据进行一定的系数配比,才能测出我们真正的温度。

数字温度传感器的应用

那数字温度传感器又是怎样应用的呢?

比如下面的这个DS18B20:

它里面集成了模拟温度传感器和微控制器。其实它里面也是有芯片的,它相当于把整个模拟温度传感器的结构合起来变成一个芯片,然后它内部读取内部的模拟温度传感器,然后通过内部转化(内部有一些控制器把温度数据读出来),把温度存在里面的RAM里面。我们只需要通过引脚和单总线(1-Wire)通信协议把这个温度给转化读取出来。而且整个转化的过程中都是数字量输入输出的,所以也不需要我们的单片机有AD转换这个功能,也不需要外部AD芯片,因此应用起来比较简单。

引脚及应用电路

这个数字温度传感器的封装跟三极管一样的封装,叫做TO92封装。

PS:VDD和VCC的意思基本一样

DS18B20所接的上拉电阻和I2C所接的上拉电阻功能是一样的,都是为了实现总线操作。

DS18B20的原理图

原理图上这个模块没有接上拉电阻是因为我们单片机的IO口上已经接了上拉电阻

DS18B20内部结构框图

PS:64-BIT ROM:作为器件地址,用于总线通信的寻址;

SCRATCHPAD(暂存器):用于总线的数据交互;

EEPROM:用于保存温度触发阈值和配置参数。

其中这部分是寄生供电电路,有了它可以省去VDD,省去VDD之后总得有电源的正极吧,那个电源就是从DQ进来的。

比如,正常的来说这个电路就是上图所画的路径,但是如果说那个VDD没有接的话,那这条路显然是没有电源正极的,这时它就会从DQ取出电源正极然后通过这个二极管,然后向内部的控制器供电。

这个电容是相当于一个电池,如果DQ是高电平时,则就可以给这个电容充电,当DQ是低电平是,这个cpp就提取电源给内部。

如果采用这种寄生供电的话,对于内部比较耗电的操作,我们还需要给这个DQ一个强上拉,因为我们的上拉电阻比较弱,通过的电流比较小,不能达到温度传感器强电流工作时的需要。

给它一个强上拉就相当于给它一个非常高的电源正极,以达到内部供电的稳定。

这里是一个电源供给的供应,它可以感应那个外部VDD是否存在,如果不存在,它会调节内部的结构来省电,或者调节内部的一些执行操作逻辑。

当然这个寄生供电的结构是自动运行的,我们不需要对程序进行任何的配置。如果采用寄生供电,直接把这个外部VDD接到GND就行了。

这次我们的程序将不会用到寄生供电,因为寄生供电还需要一个强上拉,而我们的电路板没有强上拉的电路。我们直接使用这个外部VDD供电,就不用考虑寄生供电的部分了。

DQ的数据端口过来的时候首先要经过64位的ROM(只读存储器)和1-Wire port,这里的ROM真的是只读存储器,是一种光刻ROM,标识着ID号(每一个DS18B20都有一个全球唯一的ID号,用来表明它的身份),在通信的时候作为器件的地址,用于总线的一个通信选址(就像上一节所讲的I2C总线也有一个选址一样,比如固定地址1010和三位可编程地址,这就是器件的地址),但是这里我们没有可编程地址,它所有的地址都是存在了这个64位的ROM里面,而且是不可更改的。

DQ首先进来时是到1-Wire接口这里来,就像I2C一样刚要通信时就要发出地址,1-Wire接口就像是整个DS18B20通信的一个大门,外部发送正确的地址,才能通过这个大门。当然我们后面还会学习它可以选择指令跳过这个大门(如果只有一个设备在总线上的话我们可以选择跳过这个大门)。

至此,我们知道1-Wire接口这里是用来寻址的,当它选址进来之后就会进到内存的一个控制逻辑,我们可以把它理解为一个房子的管家,如果我们通过大门就会与它进行交互,它直接掌管着内部的一个RAM。

这个RAM这里的英文叫做Scratch Pad,这个东西叫作暂存器,实际上就是一种RAM,里面存的就是温度等等一些配置的参数。它也就是数据交互的寄存器,用于总线的数据交互,就相当于当我们想要通信的时候跳过大门和管家进行交流,管家就会知道我们想要干什么,如果是想要读取,它就会把这个暂存器或是说这个RAM的东西放到总线上,如果是想要写入的话,它就会把我们的数据写到这个暂存器里面,或者是执行一些指令,都是由这一部分(管家)来完成的。

这个RAM只是一个存数据的一个盒子,它跟这些设备进行关联:

这是它内部的一些设备(实实在在的设备)。其中第一个就是Temperature Sensor温度传感器。它相当于内部的一个模拟温度传感器,它自动把这些温度转换。当我们发出指令让它开始温度转换的时候,这个温度传感器就工作,然后把它的数据放在我们的RAM里面,然后再进行数据交互,就可以把温度值拿出来了。

其他的这些设备是用于更高阶的功能。比如alarm high Trigger报警高触发寄存器,用来存储温度的上限阈值,用来温度报警的,它的一个存储器是E2PROM(掉电不丢失数据)

接着下面那个设备就是与alarm high Trigger对应的报警低触发寄存器,也是E2PROM

再下来就是配置寄存器,这个寄存器里面存的就一个东西,就是设备分辨率和精度,分辨率是可以调的,出厂默认最高分辨率是0.0625摄氏度,我们可以通过配置这个寄存器里面的两位(其他位没有用),配置之后可以把精度降低,分辨率就会最低是0.5摄氏度,温度转换的速度就会提升。它也是E2PROM。

最后一个就是8位的CRC Generator(CRC生成器),CRC在我们这个领域里面是一个比较出名的一种校验码的算法,它会通过一种特殊的格式把我们这个RAM之前的一些数据进行一个校验,然后得到一个校验码放在后面,用于通信时判断数据是否正确。举个例子,我们身份证的最后一位就是校验码,是把我们前面的数字做一个运算得到的一个校验码,当输身份证输错了的时候,它都能校验出来,而且这个CRC校验是一个校正率比较高的一个校验码。

当然本节的代码演示并不会涉及到这个内容,我们只需要把暂存器的温度读出来。

暂存器内部

我们接下来看一下这个暂存器(红色标识)内部是怎么存的和左边的三个EEPROM(蓝色标识)是怎么交互的,绿色标识的两个设备是实实在在的设备,是不会变的,所以我们先不用介绍。

那我们来具体介绍一下这个暂存器,它内部总共是9个字节,其中前两位存的分别是最低有效位和最高有效位,这两个字节共同组成温度的一个数据。括号里面的是一个默认值,如果上电直接读的话,默认就是85摄氏度。

接下来是暂存器的字节2~字节4和EEPROM上的字节一样,为什么呢?因为当我们往暂存器里写东西的时候,我们要发送一条指令把暂存器里的东西复制到EEPROM里面。当然我们也可以发送指令将EEPROM里面的东西回调到暂存器里面。

其实暂存器是运行的时候实实在在参考的,EEPROM只做一个永久存储。在上电的时候会自动把EEPROM三个字节搬到RAM里面,方便里面判断。

再往下三个字节时保留位,在本节没有使用,以后如果器件升级的话可能会用到。

最后一位是CRC校验,就是把前面八个字节做一个运算,算出来一个校验位跟在后面。

我们把整个校验位读出来之后,可以进行相同的运算,我们在程序里运算,看看是不是得到这个校验位。如果是的话证明数据是正确的,否则是有问题的。

总结我们最后的操作流程就是:我们最后会发送一条温度转换指令,我们的硬件(实实在在的传感器)就会把我们的这个温度值放在我们的暂存器RAM里面,然后我们再发送一条读暂存器的指令,紧接着跟着我们的读时序就会把我们的暂存器给读出来。这样我们就可以根据这两个字节得到我们的温度。

那么我们的问题就转变为下一个问题就是如何通过我们的单总线来发送指令,来接收我们的暂存器。发送指令本身也是发送数据,接收暂存器就是接收数据,咋么来解决这两个问题?

单总线介绍

单总线(1-Wire BUS)是由Dallas公司开发的一种通用数据总线

一根通信线:DQ

异步(没有单独磁通线)、半双工(只有一根线,要在这根线上负责数据的来回,及发送又接收)

单总线只需要一根通信线即可实现数据的双向传输,当采用寄生供电时,还可以省去设备的VDD线路,此时,供电加通信只需要DQ和GND两根线

上图左边是DS18B20,右边的那个是温湿度传感器(可以测湿度和温度),这两种设备都利用了单总线。

工程项目上,一般单总线的使用比I2C总线少。

单总线电路规范

设备的DQ均要配置成开漏输出模式

DQ添加一个上拉电阻,阻值一般为4.7KΩ左右

若此总线的从机采取寄生供电,则主机还应配一个强上拉输出电路

不使用寄生供电时的电路(本节代码主要用这种独立供电模式):

使用寄生供电时的电路(稍作了解):

将VDD接到GND上,只需要GND和DQ两根线,然后主机还接上一个强上拉输出电路

这里有个电子开关,当左边给个低电平时,开关闭合,就是强上拉

当左边给个高电平时,开关断开,就是弱上拉,这时满足它基本的操作还是可以的,但是在温度转换或者EEPROM读写的时候这些耗电操作是必须要强上拉才能满足内部的工作要求的。

单总线时序结构

初始化

初始化:主机将总线拉低至少480us,然后释放总线,等待15~60us(可以取中间值)后,存在的从机会拉低总线60~240us(可以取中间值)以响应主机,之后从机将释放总线

可以将这个时序分成两个部分

发送一位

发送一位:主机将总线拉低60~120us(最大不能超过120us),然后释放总线,表示发送0;主机将总线拉低1~15us,然后释放总线,表示发送1。从机将在总线拉低30us后(典型值)读取电平,整个时间片应大于60us

这个也可以分为两部分

发送一个字节

发送一个字节:连续调用8次发送一位的时序,依次发送一个字节的8位(低位在前)

接收一位

接收一位:主机将总线拉低1~15us,然后释放总线,并在拉低后15us内读取总线电平(尽量贴近15us的末尾),读取为低电平则为接收0,读取为高电平则为接收1 ,整个时间片应大于60us

接收一个字节

接收一个字节:连续调用8次接收一位的时序,依次接收一个字节的8位(低位在前)

DS18B20操作流程

初始化:从机复位,主机判断从机是否响应

ROM操作:ROM指令+本指令需要的读写操作

(ROM操作就相当于我们前面说的要进入这个大门)

功能操作:功能指令+本指令需要的读写操作

(功能操作就相当于RAM操作,访问里面的数据,对里面的数据进行读写)

指令介绍

ROM指令

SEARCH ROM [F0h]:搜寻ROM,具体的操作流程是比较复杂的,本节不用管

READ ROM [33h]:读ROM

MATCH ROM [55h]:匹配ROM,相当于I2C想要读写操作时首先要发从机地址,那匹配ROM紧跟着就会发送设备ROM的地址,我们就可以选择得到对应的开门的钥匙,和某一个设备单独通信了。

SKIP ROM [CCh]:跳过ROM,本节就是使用这个,因为我们只有一个设备连在上面,所以根本不需要绳子,先跟谁交流还不知道吗?当然如果线上有多个设备,就不能使用跳过ROM。

ALARM SEARCH [ECh]:报警ROM,这个也是在多个设备时使用,我们的温度有上限阈值和下限阈值,如果某个设备处于报警状态,那我可以报警搜索获取哪个设备会有报警。这个操作和搜寻ROM一样比较复杂,本节不会使用。

功能指令

CONVERT T [44h]:温度变换,我们想要读取温度之前,首先要执行温度变换,但我们执行完ROM指令之后,如果发送这条指令,它就会在这里(如下图所示)启动温度变化,然后把这个温度传感器的数值读取出来放到暂存器里面,相当于暂存器温度值更新:

WRITE SCRATCHPAD [4Eh]:写暂存器,如果调用这条指令,再跟写的一个时序,它就会把我们的字节写入到中间三个字节

READ SCRATCHPAD [BEh]:读暂存器,在温度读取的时候会用到这条指令,如果调用这条指令,再调用接收字节这个时序,那DS18B20就会依次将暂存器的内容读出来,最后会读出来CRC,然后这个指令也解出来。我们得到这么多字节后就可以进行数据的操作处理了

但我们本节只想读取温度,所以读两个字节,这个时序就不需要继续执行了,后面都不需要,只需要这两个字节就可以获取温度了

COPY SCRATCHPAD [48h]:复制暂存器,当从机接收到这条指令的时候,它就会暂存器里面的这三个字节给写入到这个EEPROM里面。如果接收这条指令就相当于左边三个值就会覆盖原来的值(右边)。如果我们想要掉电不丢失,我们先写暂存器,把放在里面,然后再调用这条指令,复制暂存器,它就会把左边三个值写入EEPROM里面。

RECALL E2 [B8h]:recall EEPROM,和上一条复制暂存器指令是相反的过程,如果发这条指令,它就会把EEPROM的三个字节给覆盖到暂存器里的那三个字节里面去。

READ POWER SUPPLY [B4h]:读取设备的供电模式,发完这条指令后,后面会跟着读取一位的时序,它就会响应我们的供电到底是寄生供电还是独立供电

也就是我们之前之前讲的这里,会感应供电模式是寄生供电还是独立供电

我们为什么要读取这里是寄生供电还是独立供电呢?

因为在寄生供电的时候,温度变换之后需要强上拉,那么什么时候需要呢?我们就可以先读一下这个位,看看是不是在寄生供电,如果不是在寄生供电就不需要了强上拉了。本节是独立供电模式,所以也不需要这条指令。

这些所有的指令中重点是三个指令:跳过ROM,温度变换,读暂存器。

DS18B20数据帧

温度变换

温度变换:初始化→跳过ROM →开始温度变换

PS:CCH就是0xCC字节,H是16进制的后缀

温度读取

温度读取:初始化→跳过ROM →读暂存器→连续的读操作

温度存储格式

高字节和低字节合起来成了这16位数据

这16位数据的前5位表示符号位,如果是负的,那么这5位全是1,如果是正的,这5位全是0

后四位是存小数的,

bit3是1的话,代表存的是0.5,

bit2是1的话,代表存的是0.25,

bit1是1的话,代表存的是0.125,

bit0是1的话,代表存的是0.0625

所以最低位变化一次,整个温度值变化的是0.0625

剩下的bit4到bit10都是温度的整数部分

我们这张表上的数值都是例子

注意:存储是以二进制的补码形式来存储的。对负数的补码的整个位进行取反加1就能得到相应的正数值,比如-0.5度的二进制取反的话就是0000 0000 0000 0111,加1就变成0000 0000 0000 1000,结果正好是正0.5的二进制数值

以上就是本节内容,下一节开始代码演示!

声明:

本专栏是本人跟着B站江科大的视频的学习过程中记录下来的笔记,部分内容借鉴了江科大的视频资料。我之所以记录下来是为了方便自己日后复习。如果你也是跟着江科大的视频学习的,可以配套本专栏食用,如有问题可以留言交流,同时也可以私信我拉进微信群聊。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐