初步认识51单片机-2.3单片机控制DS18B20温度传感器模块

发布者:sokaku最新更新时间:2016-03-29 来源: eefocus关键字:51单片机  单片机控制  DS18B20  温度传感器 手机看文章 扫描二维码
随时随地手机看文章
通过前面LCD1602的例子我相信对IO口的控制和延时基本有所了解,下面再来一个例子温度传感器,同样只需要IO口操作和延时。先来个DS18B20温度传感器的简介。既然是温度传感器,那么一定有个感知温度的感应器。这个感应器能把它周围的温度直接转成数字并存储在scratchpad存储器中。这个感知温度和转换成数字信号的过程我们可以不用理解。我们要做的事情就是读存储器的内容及其他一些配置。其原理图如下:
图1 DS18B20温度传感器概述

在DS18B20中有一个温度传感器(如上图所示),它能感知周围环境温度,并能将温度的结果直接转成数字信号存储起来。温度信号转成数字信号的过程我们可以不用关心。那么数字信号存在哪里了?DS18B20中有一个叫做ScratchPad的存储器,一共9个字节(Byte0-Byte8),数字信号就存储在Byte0_LSM和Byte1_MSB中。其中Byte0为低位,Byte1为高位。事实上,我们的目的就是读出Byte0和Byte1中存储的数字信号而已。由此可见,虽然名字是温度传感器模块,但是在我们的思考过程中丝毫不用关心传感的过程,这一点与前面讲到的LCD1602其实是一样,我们要做的事情只是去读或者写。这就是模块的作用,我们可以把它当作黑盒子,按照它的规则,只要掌握往里面输入,它会产出什么就行了,不需要关注中间的过程。我们把Byte0_LSM和Byte1_MSB组合成一个16bit的数字信号,Byte0_LSB为低位,Byte1_MSB为高位,并给它取个名字叫”T-16bit”,如上图所示。那么如何把这个”T-16bit”的数字信号转换成温度呢?从图中看出,bit11-bit15为S,表示温度的正负,如果S=0,那么温度为正,如果S=1那么温度为负。后面的bit10-bit0,数值每增加一就表示温度增加0.0625°C,举个例子: 假如LSB中读出来的是1100 0011,MSB读出来的是0000 0110,那么LSB和MSB结合起来”T-16bit”就是0000 0110 1100 0011,高5位为0,表示温度为正,余下11位bit10-bit0(110 1100 0011=1731),把1731×0.0625=108.1875,那么测量的温度为+108.1875°C. 如果LSB和MSB结合起来”T-16bit”为1111 1110 1100 0011,那么测量的温度为-108.1875°C. 在”T-16bit”中,我们也可以这样理解,bit0位每加1,表示20×0.0625°C,bit1位每变化1表示21×0.0625°C, 依此类推, bit4位每变化1为24×0.0625°C=1°C.

接着就是Byte2_TH和Byte3_TL报警的功能了,图中Byte2_TH表示设置的最高温度,Byte3_TL表示设置的最低温度。同样S表示温度的正负,如果S=0,那么表示正,如果S=1,那么温度为负。Byte2_TH和Byte3_TL就表示设定温度的范围了。注意这里的Byte2_TH与Byte3_TL与”T-16bit”中的bit11到bit4是对应的,如图中蓝色部分所示。前面讲了,在”T-16bit”中,bit4每变化1为1°C,因此在Byte2_TH与Byte3_TL中的最低位每变化1,表示温度变化1°C. 比如Byte2_TH设定为,01111001(十进制为121),首位为0,表示+121°C, Byte3_TL为01001001(十进制为73),首位为0,表示+73°C .因此温度的设定范围为:73-121°C. 当”T-16bit”中的温度高于/等于+121°C,或者低于/等于73°C时,将触发报警。

接下来就是温度采集的精度设置了,如图中的Byte4_Config所示。bit5和bit6分别为R0和R1,其他几位是固定的。R0和R1分别可以取0或者1,因此可以组合成4种情况,00/01/10/11,分别对应不同的精度,如下表所示:

Byte5-Byte7未给出,Byte8为CRC用与通信错误检测,我们暂且不用管它,我们先考虑简单的部分

通过上面的讲解,相信对DS18B20有了初步的认识,现在再来谈谈它与单片机如何沟通的。DS18B20一共三个引脚,两个电源引脚(电源正负极),一个数据引脚DQ.  其结构图如下所示。黑色壳体朝上,引脚朝下,平面对着自己,左手边第一个引脚为GND. DS18B20的正负极如果接反,可能会烧掉。

可见单片机与DS18B20的沟通只能靠这一根线了,另外这一根线上可以同时接很多个DS18B20. 那么单片机是如何通过这一根线准确的与多个DS18B20沟通的呢?单片机是不知道DQ线上有没有DS18B20的,或者有多个,或者有但是坏了。与人的沟通方式一样,当你不知道屋里情况的时候,会先打个招呼,问下有人没。同样,单片机也一样,先来个初始化,打个招呼,看看DQ线上有没有18B20。怎么样打招呼呢,与前面讲LCD1602一样,当然按照DS18B20的规则。单片机先要把DQ拉低至少480μS, 然后释放DQ,大约在15-60μS后,如果线上有DS18B20并能正常工作,那么DS18B20将DQ拉低并维持60-240μS. 单片机通过检查这个信号,从而判断线上是否有能正常工作的DS18B20,有多少个信号就挂着多少个DS18B20,这个就是DS18B20的规则,具体如下,

初始化后之后就可以与DS18B20沟通了?线上如果有多个DS18B20,你到底是要与哪个沟通呢?因此沟通之前要先来个确定对象。这里我们取最简单一个DS18B20,搞懂了一个,自然会做控制多个DS18B20了。我们来看看初始化代码如何写,

step1:首先DQ拉低,要维持至少480Us,这里我们取500Us保险一点

step2:释放总线(DQ=1),大约等待15-60Us后,DS18B20会把DQ拉低。那么这里到底是选15Us,还是60Us?

step3:此时DS18B20把DQ拉低信号(L_DQ)能持续60-240Us.那么到底选60Us还是240Us?

注意我们这里的目的是要检测出DS18B20是否拉低DQ的信号(L_DQ)。那么在step2中,释放总线(DQ=1)后,我们到底要延时多长时间(Tdelay),去读DQ是否等于0的信号?

我们来个极端假设,最小值和最大值

(1)在step2中, 单片机释放总线(DQ=1),等待15Us(最小值)后,DS18B20把DQ拉低,在step3中,DQ拉低持续了60Us(最小值)

    在这种情况下,如果Tdelay>75Us,你就不能检测到L_DQ信号了。因此Tdelay要小于75Us.

(2)在step2中, 单片机释放总线(DQ=1),等待60Us(最大值)后,DS18B20把DQ拉低,在step3中,DQ拉低持续了60/240Us(两种情况)

   在这种情况下,如果Tdelay<60Us,你就检测不到L_DQ信号了。比如你设置Tdelay=50Us然后去读DQ,此时DQ仍然为1,为什么?因为60Us后

   DS18B20才把DQ拉低。因此Tdelay>60Us.

综上所述,保险时间为:75Us>Tdelay>60Us,代码如下:

void ds18b20_init(void)

{

        DQ=0;//总线拉低

        delayUs(240);  //延时526Us

        DQ=1;//释放总线

    delayUs(28);//延时66Us(60-75Us之间)

        if(DQ==0)

        {

                LED1=0;//(设置一个LED,如果检测到DQ=0,就把LED1点亮)

        }

        else

        {

                LED2=0;

        }

        delayUs(240);//注意读完DQ后要继续延时480Us

}

DS18B20的ID信号在ROM中,因此这里我们可以跳过读ROM(Skip ROM[CCh]).

接下来就到了与DS18B20沟通的部分了。DS18B20一上电的时候是钝态的,就是说它是被动的,没有指令它就不干活。所以,单片机给DS18B20的第一个指令就是让它开始测量温度(Convert T [44h]). 当DS18B20收到这条指令后干什么呢?这里就要回到前面的我们讲的图1,DS18B20开始感知周围温度并把温度高低转成数字信号存储在ScratchPad中的Byte0和Byte1中。从这里我们知道,我们仅仅通过一条指令Convert T,就让DS18B20开始温度测量并存储,至于这个过程怎么发生的我们并不关心。从这里我们看到,其实控制DS18B20模块与LCD1602模块没有本质上区别,我们要做的事情仅仅是去读懂规则,这些规则来源与它们的芯片手册,那么简单的讲就是阅读理解芯片手册。这一点其实被很多初学者忽略了,不愿意或者不习惯查看芯片手册。DS18B20把温度信号转成数字信号需要一定的时间,因此在发布下一条指令前,我们这里需要检测DS18B20是否仍处于工作之中,如果你想简化,来个延时也行。转换完成后,DS18B20又处于钝态了,这个转换过程不是持续的,因此你想让它再转换,那么就必须再发一次Convert T指令。

那么怎么发指令呢?这个就涉及到‘DS18B20写’的部分了。参考数据手册,找到‘写时序

首先看单片机如何往DS18B20中写0和1,

(1)写0:DQ拉低,维持至少60Us,在大约15-60Us的时候,DS18B20开始接受数据

(2)写1: DQ拉低,延时2Us,然后释放DQ,此时,上拉电阻会把DQ拉高,延时至少60Us,在15-60Us的时候,DS18B20开始接受数据

因此写指令的代码如下

void ds18b20_com(unsigned char mycom)

{

        unsigned char temp;

        unsigned char i;

        for (i=0;i<8;i++)

        {

                temp=mycom & 0x01;

                if (temp==1)

                {

                        DQ=0;

                        _nop_();

                        _nop_();

                        DQ=1;

                        delayUs(35);

                }

                else

                {

                        DQ=0;

                        delayUs(35);

                        DQ=1;

                

                }

                mycom>>=1;

        }        

}

所以,如果你要发指令 ds18b20_com(0xcch)//skip rom,DS18B20就知道了要跳过读ROM,如果要发指令Convert T, ds18b20_com(0x44h),DS18B20就开始温度转换,并存储在ScratchPad中的前两个字节。

当转换完成后,数据存储在Byte0和Byte1中,下面的任务就是去读Byte0和Byte1了。这里需要注意的是,再单片机每发一次指令之前都要: 初始化->ROM指令->功能指令。这个是芯片手册上规定的。因此在读Byte0和Byte1之前要再初始化一次,Skip ROM([CCh]), 就可以读Byte0和Byte1了。之后将Byte0和Byte1合并,然后转换成温度就可以了。

现在我们来看看如何读DS18B20,同样查看芯片手册,找到读的时序图

DS18B20要把数据发送给单片机,那么DS18B20怎么知道单片机什么时候开始要数据呢?这里同样有个规则,当单片机将DQ拉低,延时1Us,然后释放DQ。此时,DS18B20就知道了,哦,单片机开始要数据了。如果此时DS18B20要给0,就把DQ拉低,相反,如果要写1就让DQ维持高的状态。从单片机发出读数据信息,DS18B20给数据,单片机采集数据,这个过程要在15Us完成,之后需要延时45Us,为保险,我们这里取65Us。两个读之间,至少要有1Us的间隔。因此很容易得出单片机读DS18B20的代码:

unsigned int ds18b20_read(void)

{

        unsigned char temp1=0;

        unsigned int temp2=0;

        unsigned int temp=0;

        unsigned char i;

        for (i=0;i<8;i++)

        {

                temp1>>=1;

                DQ=0;

                _nop_();

                _nop_();

                DQ=1;

                if(DQ==1)

                temp1 |=0x80;

                delayUs(35);

        }

        for (i=0;i<8;i++)

        {

                temp2>>=1;

                DQ=0;

                _nop_();

                _nop_();

                DQ=1;

                if(DQ==1)

                temp2 |=0x80;

                delayUs(35);

        }

        temp2 <<=8;

        temp=temp1+temp2;

        return temp;

}

通过LCD1602和DS18B20两个例子可以看出,对这两个模块的控制,其实只用了单片机的引脚控制和延时程序。重点和难点其实在理解各模块的控制规则。其实这些只需要通过仔细阅读对应的芯片手册就能找到。而单片机引脚的控制和延时部分与LED的操作并无区别,难怪有人说,如果你把操作LED的过程真正搞懂了,单片机你就学会了一半。后面我们会反复的使用LED作为例子,讲解单片机其它相关内容。

关键字:51单片机  单片机控制  DS18B20  温度传感器 引用地址:初步认识51单片机-2.3单片机控制DS18B20温度传感器模块

上一篇:初步认识51单片机-2.4单片机C语言模块化编程
下一篇:初步认识51单片机-2.2单片机控制LCD1602液晶显示模块

推荐阅读最新更新时间:2024-03-16 14:48

4利用移位函数操作点亮流水灯
功能说明:利用移位函数操作点亮流水灯 程序源代码如下: #include reg52.h #include intrins.h #define uchar unsigned char #define uint unsigned int #define led P0 void delay (void) { uchar a,b; for(a=0;a 200;a++) for(b=0;b 200;b++); } void main(void) { uchar i,k; while(1) { k = 0xfe; for(i=0;i 8;i++) { led = k; de
[单片机]
4利用移位函数操作点亮流水灯
51单片机-定时器概念
1.生活的例子 通过上一章大家已经有了对中断知识的了解,像外部中断这种需要物理动作才能触发中断函数执行,但很多情况下我们需要的是中断函数在适当时刻可以自动得去执行,所以就需要定时器来辅助了。 定时器是单片机内部的一个硬件资源。 用生活常见现象举例:定时器相当于一个闹钟,我们调5分钟后闹钟就响,在这5分钟里我们想做什么就做什么,相当于我们自己是主函数里的任务,想运行什么任务就运行什么,也不用去理会闹钟还剩多少时间就响,我们只是一直做我们想做的事就行。 之后闹钟响了,这时我们不能再任性去做主函数的事了,得赶紧把中断函数里的事办完先,也就是要去执行中断函数了,主函数的事要暂停不做先,执行完中断函数之后继续回到主函数做我们的
[单片机]
基于51单片机的智能水表
一.硬件方案 本设计主要以51单片机作为主控处理器的智能水表,该水表能够记录总的用水量和单次用水量,当用水量超出设定值时系统发出声光报警提醒,水量报警值能够通过按键进行自行设置,并且存储于AT24C02中,并且可以测量水流速度。测量的结果采用LCD1602液晶显示平显示出来。 主要由51单片机+最小系统+LCD1602液晶显示模块+蜂鸣器模块+LED指示灯模块+继电器驱动模块+按键电路+AT24C02芯片模块+水泵驱动电路;如图: 二.设计功能 (1)采用LCD1602液晶显示屏实时显示瞬时水流速、总用水量、本次用水量、水流量限值; (2)可通过按键设置水流量限值,当本次用水量超过水流量限值时系统发出声光报警提醒; (3)
[单片机]
基于<font color='red'>51单片机</font>的智能水表
8051单片机基础5:数据类型占用空间大小及取值范围
参考资料: Keil Help uVision Help Cx51 Compiler User’s Guide Language Extensions Data Types Keil Help uVision Help Arm Compiler 5 User’s Guides Compiler User Guide C and C++ Implementation Details C语言中使用变量时需要先定义数据类型,定义数据类型后,编译器自动分配适当的存储空间。比如定义unsigned char型变量,分配1个字节的存储空间。 在不同MCU平台使用C语言编写代码时,需要注意基本数据类型占用字节数,比如
[单片机]
80<font color='red'>51单片机</font>基础5:数据类型占用空间大小及取值范围
MCS-51单片机在饱和蒸汽的流量计量补偿中的应用
0  引  言 流体流量的检测与控制是各行各业加强能源、物料管理、进行经济分析、结算和决策的重要依据,也是监控生产过程使其保持优质、安全、提高效率和改善环境的重要手段。尽管目前流量计量计已有几十种之多,然而对于越来越高的计量精确性而言,往往都要采用补偿措施。如用差压式流量计检测饱和蒸汽的流量,设计压力为0.5MPa,当蒸汽压力变化到1.0MPa时其流量误差达-26%左右 [1] 。工况变化越大,引入的误差越大。所以,在一些需要精确计量或者工况波动范围大而且波动频繁的场合必须采用补偿措施。 流体计量补偿技术,就是针对不同的流量计,检测不同流体而建立的一种修正方法。随着自动化技术的进步,计算机及其它智能装置的出现,自动补偿的技
[单片机]
MCS-<font color='red'>51单片机</font>在饱和蒸汽的流量计量补偿中的应用
51单片机电子日历(可调整 带温度)DS1302时钟+12864LCD显示
可按照程序接线 51单片机显示时间(可调整)(DS1302时钟+12864LCD显示) 仿真原理图如下: 单片机源程序如下: /****************************************/ /* 带温度显示的电子日历 */ /****************************************/ #include reg51.h #include intrins.h #include string.h #define uchar unsigned char #define uint unsigned int sbit DQ=P2^7; sbit CS1=P2^1;
[单片机]
<font color='red'>51单片机</font>电子日历(可调整 带温度)DS1302时钟+12864LCD显示
51单片机教程(七):LCD1602液晶显示模块
一、原理简介 液晶显示模块具有体积小、功耗低、显示内容丰富、超薄轻巧等优点,在嵌入式应用系统中得到越来越广泛的应用,这讲中向大家介绍的LCD1602 液晶显示模块(其内部控制器为HD44780 芯片),它可以显示两行,每行16 个字符,因此可相当于32 个LED数码管,而且比数码管显示的信息还多。采用单+5V 电源供电,外围电路配置简单,价格便宜,具有很高的性价比。 LCD1602 外观如图1(a) 所示。1602 字符型LCD 模块的管脚分布如图1(b) 所示, 其管脚各功能如表1 所示。 图1 (a) LCD1602外观图 (b) LCD1602管脚分布图 值得提出的是,各种液晶厂家均有提供几乎都是同样规格的160
[单片机]
<font color='red'>51单片机</font>教程(七):LCD1602液晶显示模块
用PC104控制模块和C51单片机实现AD检测板
  由PC104控制模块和Cgnal C8051F06x单片机组成的控制检测板可用于高端检测设备中,充分利用PC104控制模块和单片机丰富的软硬件资源,可用于各种检测应用中。   在开发检测设备的过程中,可采用核心板加底板的设计方法来降低技术难度,实现可编程、高性能、开发简单、扩展性强的设计方案,并且稍加改动就可以很容易地应用到其他领域。   核心板采用PC104控制模块,利用其强大的处理能力来处理数据,如数据存储、数据分析、数据评估,尤其是友好的GUI简化了用户的使用难度。底板采用Cgnal8051F06x、双口RAM和缓冲寄存器,利用C8051F06X单片机丰富的软硬件资源来实现可编程,可设置的各种复杂功能。核心板与底板之
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved