当前位置:首页 >> 信息与通信 >>

DS18B20的工作原理及应用


1.DS18B20 的工作原理 ① DS18B20 数字温度传感器概述 DS18B20 数字温度传感器是 DALLAS 公司生产的 1-Wire,即单总线器件, 具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路 简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。 DS18B20 产品的特点 只要求一个端口即可实现通信。 在 DS18B20 中的每个器件上都

有独一无二的序列号。 实际应用中不需要外部任何元器件即可实现测温。 测量温度范围在-55.C 到+125.C 之间。 数字温度计的分辨率用户可以从 9 位到 12 位选择。 内部有温度上、下限告警设置。 TO-92 封装的 DS18B20 的引脚排列见右图,其引脚功能描述见表
序号 1 2 名称 GND DQ 引脚功能描述 地信号 数字输入输出引脚,开漏单总线接口引脚,当使用寄生电源时, 可向电源提供电源 3 VDD 可选择的 VDD 引脚,当工作于寄生电源时,该引脚必须接地 表 3-2 DS18B20 详细引脚功能描述

② DS18B20 的内部结构

DS18B20的内部框图下图所示,DS18B20 的内部有64 位的ROM 单元,和9 字节的暂存器单元。64 位ROM存储器件独一无二的序列号。暂存器包含两字节(0和1字节)的温度寄存器,用于存储温度传感器的 数字输出。暂存器还提供一字节的上线警报触发(TH)和下线警报触发(TL)寄存器(2和3字节) ,和一字 节的配置寄存器(4字节) ,使用者可以通过配置寄存器来设置温度转换的精度。暂存器的5、6和7字节器件内 。使用寄生电源时,DS18B20不需额外的供电电源;当总线 部保留使用。第八字节含有循环冗余码(CRC )
1

为高电平时, 功率由单总线上的上拉电阻通过DQ引脚提供; 高电平总线信号同时也向内部电容CPP充电, CPP 在总线低电平时为器件供电。 字节5~8 就不用看了)。 (

图为 暂存器

A. 温度寄存器(0和1字节)

DS18B20 中的温度传感器可完成对温度的测量,以 12 位转化为例:用 16 位符号扩展的二进制补 码读数形式提供,以 0.0625℃/LSB 形式表达,其中 S 为符号位。 这是12位转化后得到的12位数据,存储在18B20的两个8比特的RAM中,二进制中的前面5 位是符号位,如果测得的温度大于0,这5位为0,只要将测到的数值乘于0.0625即可得到实际温 度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。

DS18B20 的温度操作是使用16 位,也就是说分辨率是0.0625。BIT15~BIT11 是符号位, 为了就是表示转换的值是正数还是负数。

2

█要求出正数的十进制值,必须将读取到的LSB 字节,MSB 字节进行整合处理,然后乘 以0.0625 即可。 Eg:假设从,字节0 读取到0xD0 赋值于Temp1,而字节1 读取到0x07 赋值于Temp2,然后求 出十进制值。 unsigned int Temp1,Temp2,Temperature; Temp1=0xD0; //低八位 Temp2=0x07; //高八位 Temperature = ((Temp2<<8 ) | Temp1 ) * 0.0625;//又或者 Temperature = (Temp1 + Temp2 *256) * 0.0625; //Temperature=125 █在这里我们遇见了一个问题,就是如何求出负数的值呢?很遗憾的,单片机不像人脑 那样会心算,我们必须判断BIT11~15 是否是1,然后人为置一负数标志。 Eg. 假设从,字节0 读取到0x90 赋值于Temp1,而字节1 读取到0xFC 赋值于Temp2,然后求 出该值是不是负数,和转换成十进制值。 unsigned int Temp1,Temp2,Temperature; unsigned char Minus_Flag=0; Temp1=0x90; //低八位 Temp2=0xFC; //高八位
3

//Temperature = (Temp1 + Temp2 *256) * 0.0625; //Temperature=64656 //很明显不是我们想要的答案 if(Temp2&0xFC) //判断符号位是否为1 { Minus_Flag=1; //负数标志置一 Temperature = ((Temp2<<8 ) | Temp1 ) //高八位第八位进行整合 Temperature= ((~Temperature)+1); //求反,补一 Temperature*= 0.0625; //求出十进制 } //Temperature=55; else { Minus_Flag=0; Temperature = ((Temp2<<8 ) | Temp1 ) * 0.0625; } █如果我要求出小数点的值的话,那么我应该这样做。 Eg:假设从,字节0 读取到0xA2 赋值于Temp1,而字节1 读取到0x00 赋值于Temp2, 然后求出十进制值,要求连同小数点也求出。 unsigned int Temp1,Temp2,Temperature; Temp1=0x90; //低八位 Temp2=0xFC; //高八位 //实际值为10.125 //Temperature = ((Temp2<<8 ) | Temp1 ) * 0.0625; //10,无小数点

4

Temperature = ((Temp2<<8 ) | Temp1 ) * (0.0625 * 10) ; //101 ,一位小数点 //Temperature = ((Temp2<<8 ) | Temp1 ) * (0.0625 * 100) ; //1012,二位小数点 █ 如以上的例题,我们可以先将0.0625 乘以10,然后再乘以整合后的Temperature 变量, 就可以求出后面一个小数点的值(求出更多的小数点,方法都是以此类推)。得出的结果是 101,然后再利用简单的算法,求出每一位的值。 unsinged char Ten,One,Dot1 Ten=Temperature/100; //1 One=Temperature%100/10; //0 Dot1=%10; //1 求出负数的思路也一样,只不过多出人为置一负数标志,求反补一的动作而已。自己发 挥想象力吧。 2~3:TH TL TL配置 B .字节2~3 TH 和TL 2~3 TH 与TL 就是所谓的温度最高界限, 和温度最低界限的配置。 其实这些可以使用软件来试验, 所以就无视了。

C 字节4:配置寄存器 4

BIT7 出厂的时候就已经设置为0,用户不建议去更改。而R1 与R0 位组合了四个不同的转 换精度,00 为9 位转换精度而转换时间是93.75ms,01 为10 位转换精度而转换时间是 187.5ms, 为11 位转换精度而转换时间是375ms, 为12 位转换精度而转换时间是750ms 10 11 (默认)。该寄存器还是留默认的好,毕竟转换精度表示了转换的质量。
低五位一直都是"1",TM 是测试模式位,用于设置 DS18B20 在工作模式还是在测试模式。在
5

DS18B20 出厂时该位被设置为 0,用户不要去改动。R1 和 R0 用来设置分辨率,如下表所示: (DS18B20 出厂时被设置为 12 位)
表 3-6R1 与 R0 确定传感器分辨率设置表 R1 0 0 1 1 R0 0 1 0 1 传感器精度/bit 9 10 11 12 转换时间/ms 93.75 187.5 375 750

D.字节5~7 8:保留位,CRC 5~7,8 D. 5~7 CRC

无视,无视吧。

③光刻 ROM 中的 64 位序列号是出厂前被光刻好的,它可以看作是该 DS18B20 的地址序列码。64 位光刻 ROM 的排列是:开始 8 位(28H)是产品类型标号,接着的 48 位是该 DS18B20 自身的序 列号,最后 8 位是前面 56 位的循环冗余校验码(CRC=X8+X5+X4+1)。光刻 ROM 的作用是使每一 个 DS18B20 都各不相同,这样就可以实现一根总线上挂接多个 DS18B20 的目的。 ④DS18B20 温度传感器的存储器 DS18B20 温度传感器的内部存储器包括一个高速暂存 RAM 和一个非易失性的可电擦除的 EEPRAM, 后者存放高温度和低温度触发器 TH、TL 和结构寄存器。 2 DS18B20 的工作过程 DS18B20 一般都是充当从机的角色,而单片机就是主机。单片机通过一线总线访问DS18B20 的话,需要经过以下几个步骤: ① DS18B20 复位(初始化), DS18B20 复位。 在某种意义上就是一次访问 DS18B20 的开始,

或者可说成是开始信号。
②执行ROM 指令(ROM命令跟随着需要交换的数据);ROM 指令,也就是访问,搜索,匹配,DS18B20
个别的64 位序列号的动作。在单点情况下,可以直接跳过ROM 指令。而跳过ROM 指令的字节是0xCC

③执行 DS18B20 功能指令(RAM 指令),功能命令跟随着需要交换的数据。

DS18B20 功能指令有很多种,我就不一一的介绍了,数据手册里有更详细的介绍。这里仅列 出比较常用的几个DS18B20 功能指令。 0x44:开始转换温度。转换好的温度会储存到暂存器字节0 和1。
0xEE:读暂存指令。读暂存指令,会从暂存器0 到9,一个一个字节读取,如果要停止的话,必须写下DS18B20 复位。

访问 DS18B20 必须严格遵守这一命令序列,如果丢失任何一步或序列混乱,DS18B20 都不会 响应主机(除了 Search ROM 和 Alarm Search 这两个命令,在这两个命令后,主机都必须返回 到第一步)。 一般上我们都是使用单点,也就是说单线总线上仅有一个DS18B20 存在而已。所以我们无
6

需刻意读取ROM 里边的序列号来,然后匹配那个DS18B20?而是更直接的,跳过ROM 指令,然后 直接执行DS18B20 功能指令。 a. 初始化, DS18B20 复位: 在初始化过程中,主机通过拉低单总线至少 480?s,以产生复位脉冲(TX)。然后主机释放总线并 进入接收(RX)模式。当总线被释放后,5kΩ的上拉电阻将单总线拉高。DS18B20 检测到这个上升 沿后,延时 15?s~60?s,通过拉低总线 60?s~240?s 产生应答脉冲。初始化波形如图 3-8 所示。

DS18B20 的复位时序如下:
1.单片机拉低总线480us~950us, 然后释放总线(拉高电平)。 2.这时DS18B20 会拉低信号,大约60~240us 表示应答。 3.DS18B20 拉低电平的60~240us 之间,单片机读取总线的电平,如果是低电平,那么表示复位成功。 4.DS18B20 拉低电平 60~240us 之后,会释放总线。

C 语言代码:
//DS1302 复位函数 void DS1302_Reset() { DDRA|=BIT(DQ); //DQ 为输出状态 PORTA&=~BIT(DQ); //输出低电平 Delay_1us(500); //延迟500 微妙 PORTA|=BIT(DQ); //示范总线 Delay_1us(60); //延迟60 微妙 DDRA&=~BIT(DQ); //DQ 位输出状态 while(PINA&BIT(DQ)); //等待从机DS18B20 应答(低电平有效) while(!(PINA&BIT(DQ))); //等待从机DS18B20 释放总线 }

DS18B20 所有的数据交换都由一个初始化序列开始。 由主机发出的复位脉冲和跟在其后的由 DS18B20 发出的应答脉冲构成。当 DS18B20 发出响应主机的应答脉冲时,即向主机表明它已处在 总线上并且准备工作。 b. ROM 命令: ROM 命令通过每个器件 64-bit 的 ROM 码,使主机指定某一特定器件(如果有多个器件挂在 总线上)与之进行通信。DS18B20 的 ROM 如表 3-4 所示,每个 ROM 命令都是 8 bit 长。 c. 功能命令:
7

主机通过功能命令对 DS18B20 进行读/写 Scratchpad 存储器,或者启动温度转换。DS18B20 的功 能命令如表 3-7 所示。
指令 读 ROM 符合 ROM 搜索 ROM 跳过 ROM 报警搜索命令 温度转换 读暂存器 写暂存器 复制暂存器 重调 E PROM 读供电方式
2

协议 33H 55H 0F0H 0CCH 0ECH 44H BEH 4EH 48H 0B8H 0B4H

功能 读 DS18B20 中的编码(即 64 位地址) 发出此命令后,接着发出 64 位 ROM 编码,访问单总线上与该编码 相对应的 DS18B20,使之作出响应,为下一步对该 DS18B20 的读写 作准备 用于确定挂接在同一总线上 DS18B20 的个数和识别 64 位 ROM 地址, 为操作各器件作好准备 忽略 64 位 ROM 地址,直接向 DS18B20V 温度转换命令,适用于单 个 DS18B20 工作 执行后,只有温度超过庙宇值上限或下限的片子才做出响应 启动 DS18B20 进行温度转换,转换时间最长为 500ms(典型为 200ms),结果丰入内部 9 字节 RAM 中 读内部 RAM 中 9 字节的内容 发出向内部 RAM 的第 3、4 字节写上、下温度数据命令,紧该温度 命令之后,传达两字节的数据 将 RAM 中第 3、4 字内容复制到 E PROM 中 将 E PROM 中内容恢复到 RAM 中的第 3、4 字节 读 DS18B20 的供电模式,寄生供电时 DS18B20 发送“0” ,外部供电 时 DS18B20 发送“1” 表 3-7
2 2

(6)DS18B20 的信号方式 DS18B20 采用严格的单总线通信协议,以保证数据的完整性。该协议定义了几种信号类型:复位 脉冲、应答脉冲、写 0、写 1、读 0 和读 1。除了应答脉冲所有这些信号都由主机发出同步信号。 总线上传输的所有数据和命令都是以字节的低位在前。 a.初始化序列:复位脉冲和应答脉冲 在初始化过程中,主机通过拉低单总线至少 480?s,以产生复位脉冲(TX)。然后主机释放总线并 进入接收(RX)模式。当总线被释放后,5kΩ的上拉电阻将单总线拉高。DS18B20 检测到这个上升 沿后,延时 15?s~60?s,通过拉低总线 60?s~240?s 产生应答脉冲。初始化波形如图 3-8 所示。

b.读和写时序 在写时序期间,主机向 DS18B20 写入指令;而在读时序期间,主机读入来自 DS18B20 的
8

指令。在每一个时序,总线只能传输一位数据。读/写时序如图 3-9 所示。 写时序 存在两种写时序:“写 1”和“写 0”。主机在写 1 时序向 DS18B20 写入逻辑 1,而在写 0 时序向 DS18B20 写入逻辑 0。所有写时序至少需要 60?s,且在两次写时序之间至少需要 1?s 的 恢复时间。两种写时序均以主机拉低总线开始。 产生写 1 时序: 主机拉低总线后, 必须在 15?s 内释放总线, 然后由上拉电阻将总线拉至高电平。 产生写 0 时序:主机拉低总线后,必须在整个时序期间保持低电平(至少 60?s)。 在写时序开始后的 15?s~60?s 期间,DS18B20 采样总线的状态。如果总线为高电平,则逻辑 1 被写入 DS18B20;如果总线为低电平,则逻辑 0 被写入 DS18B20。 写时序

DS18B20 写逻辑0 的步骤如下: 1.单片机拉低电平大约10~15us,。 2.单片机持续拉低电平大约20~45us 的时间。 3.释放总线 DS18B20 写逻辑1 的步骤如下: 1.单片机拉低电平大约10~15us,。 2.单片机拉高电平大约20~45us 的时间。 3.释放总线

写时序

DS18B20 读逻辑0 的步骤如下: 1.在读取的时候单片机拉低电平大约1us 2.单片机释放总线,然后读取总线电平。 3.这时候DS18B20 会拉低电平。 4.读取电平过后,延迟大约40~45 微妙
9

DS18B20 读逻辑1 的步骤如下: 1.在读取的时候单片机拉低电平大约1us 2.单片机释放总线,然后读取总线电平。 3.这时候DS18B20 会拉高电平。 4.读取电平过后,延迟大约 40~45 微妙

如果要读或者写一个字节,就要重复以上的步骤八次。如以下的C 代码,使用for 循环,和数 据变量的左移和或运算,实现一个字节读与写。 //DS18B20 写字节函数 void DS1302_Write(unsigned char Data) { unsigned char i; DDRA|=BIT(DQ); //DQ 为输出 for(i=0;i<8;i++) { PORTA&=~BIT(DQ); //拉低总线 Delay_1us(10); //延迟10 微妙(最大15 微妙) if(Data&0x01) PORTA|=BIT(DQ); else PORTA&=~BIT(DQ); Delay_1us(40); //延迟40 微妙(最大45 微妙) PORTA|=BIT(DQ); //释放总线 Delay_1us(1); //稍微延迟 Data>>=1; } } //DS18B20 读字节函数 unsigned char DS1302_Read() { unsigned char i,Temp; for(i=0;i<8;i++) { Temp>>=1; //数据右移 DDRA|=BIT(DQ); //DQ 为输出状态 PORTA&=~BIT(DQ); //拉低总线,启动输入 PORTA|=BIT(DQ); //释放总线 DDRA&=~BIT(DQ); //DQ 为输入状态 if(PINA&BIT(DQ)) Temp|=0x80; Delay_1us(45); //延迟45 微妙(最大45 微妙) } return Temp; } 就是这么建档而已,不过这里有一个注意点,就是Delay_1us(); 函数延迟的时间,必须模拟非常准 确,因为单线总线对时序的要求敏感点。

DS18B20 只能在主机发出读时序时才能向主机传送数据。所以主机在发出读数据命令后,必须马 上产生读时序,以便 DS18B20 能够传送数据。所有读时序至少 60?s,且在两次独立的读时序之
10

间至少需要 1?s 的恢复时间。 每次读时序由主机发起,拉低总线至少 1?s。在主机发起读时序之后,DS18B20 开始在总线 上传送 1 或 0。若 DS18B20 发送 1,则保持总线为高电平;若发送 0,则拉低总线。当传送 0 时, DS18B20 在该时序结束时释放总线,再由上拉电阻将总线拉回空闲高电平状态。DS18B20 发出的 数据在读时序下降沿起始后的 15?s 内有效,因此主机必须在读时序开始后的 15?s 内释放总线, 并且采样总线状态。 DS18B20 在使用时,一般都采用单片机来实现数据采集。只需将DS18B20 信号线与单片 机1 位I/O线相连, 且单片机的1 位I/O 线可挂接多个DS18B20 , 就可实现单点或多点温度检测。 (7)DS18B20 的温度计算 DS18B20 允许通过程序对传感器的分辨率,温度报警的上、下限等参数进行配置。它的内部存储 器包括一个高速暂存存储器和一个非易失性可擦除 E?PROM。 速暂存存储器共有 8 个字节(byte), 每个字节 8 位(bit)。 根据温度的计算方法如下: S S S S S = 11111 b 温度值: T = [ (MSB and 7) ×256 + LSB] ×0.0625 ℃ SSSSS = 00000 b 温度值: T = - [ (256 - MSB) ×256 - LSB] ×0.0625 ℃ 如果,存储器高位寄存器 MS 的 S S S S S 均为 1 ,则被测温度为正值,用上面第 1 个公式来计算 温度。如果存储器高位寄存器 MSB 的 S S S S S 均为 0,则被测温度为负值,用上面第 2 个公式来 计算温度。在这里,有两点应当注意:一是公式中中括号内的数值为二进制,在计算口号内计算完 成后应转化为十进制;二是这里的 7 与 0.0625 是假设传感器的分辨率设置 0.0625 时的计算值。 如果分辨率的设置值不是 0.0625,那么就应当作相应的变化。 3 和第 4 个字节分别用来存放温 第 度报警的上限(TH)和下限值(TL)。DS18B20 在完成温度变换后,会将所测温度值与贮存在 TH 和 TL 内的上下限值相比较,如果测温结果高于 TH 或低于 TL,DS18B20 内部的告警标志就会被置位, 表示温值超出了测量范围。并且该值在掉电后不会丢失,而是记忆其设定的上下限值。第 5 字节 是配置寄存器,如表 2.3 所示,该寄存器用于对温度转换值的分辨率进行设置。其中,最高位用于 设置传感器是工作模式还是测试模式,是生产厂家为便于检验使用。 其出厂时的默认值为 0,为工 作模式(即用户使用时的模式)。并且在用户使用中,该位总是保持为 0。R1 与 R0 确定传感器的 分辨率,如表 2.4 所示,DS18B20 有 4 种分辨率可供选择。使用时可以根据实际需要来设置,出厂 时的默认设置是 12 位。最后 5 位总保持为 1

简单归纳
实验开始之前,简单的归纳一些重点。单线总线高电平为闲置状态。单片机访问DS18B20必须遵 守,DS18B20 复位-->执行ROM 指令-->执行DS18B20 功能指令。而在单点上,可以直接跳过ROM 指令。 DS18B20 的转换精度默认为12 位, 而分辨率是0.0625。 DS18B20 温度读取函数参考步骤: DS18B20 开始转换: 1.DS18B20 复位。 2.写入跳过ROM 的字节命令,0xCC。 3.写入开始转换的功能命令,0x44。 4.延迟大约750~900 毫秒 DS18B20 读暂存数据:

11

1.DS18B20 复位。 2.写入跳过ROM 的字节命令,0xCC。 3.写入读暂存的功能命令,0xee。 4.读入第0 个字节LS Byte,转换结果的低八位。 5.读入第1 个字节MS Byte,转换结果的高八位。 6.DS18B20 复位,表示读取暂存结束。 数据求出十进制: 1.整合LS Byte 和MS Byte 的数据 2.判断是否为正负数(可选) 3.求得十进制值。正数乘以0.0625,一位小数点乘以0.625,二位小数点乘以6.25。 4.十进制的“个位”求出。
ds18b20 c 程序 //DS1820 C51 子程序 //这里以 11.0592M 晶体为例,不同的晶体速度可能需要调整延时的时间 //sbit DQ =P2^1;//根据实际情况定义端口 typedef unsigned char byte; typedef unsigned int word; //延时 void delay(word useconds) { for(;useconds>0;useconds--); } //复位 byte ow_reset(void) { byte presence; DQ = 0; delay(29); DQ = 1; delay(3); presence = DQ; delay(25); return(presence); }

//pull DQ line low 时序中 // leave it low for 480us // allow line to return high // wait for presence // get presence signal // wait for end of timeslot // presence signal returned // 0=presence, 1 = no part

//从 1-wire 总线上读取一个字节 byte read_byte(void) { byte i; byte value = 0;
12

for (i=8;i>0;i--) { value>>=1; DQ = 0; DQ = 1; delay(1); if(DQ)value|=0x80; delay(6); } return(value); }

// pull DQ low to start timeslot // then return high //for (i=0; i<3; i++); // wait for rest of timeslot

//向 1-WIRE 总线上写一个字节 void write_byte(char val) { byte i; for (i=8; i>0; i--) // writes byte, one bit at a time { DQ = 0; // pull DQ low to start timeslot DQ = val&0x01; delay(5); // hold value for remainder of timeslot DQ = 1; val=val/2; } delay(5); } //读取温度 char Read_Temperature(void) { union{ byte c[2]; int x; }temp; ow_reset(); write_byte(0xCC); write_byte(0xBE); temp.c[1]=read_byte(); temp.c[0]=read_byte(); ow_reset(); write_byte(0xCC); write_byte(0x44); return temp.x/2;

// Skip ROM // Read Scratch Pad

//Skip ROM // Start Conversion

13

} ds18b20 汇编程序: 本汇编程序仅适合单个 DS18B20 和 51 单片机的连接,晶振为 12MHZ 左右 DQ:DS18B20 的数据总线接脚 FLAG1:标志位,为"1"时表示检测到 DS18B20 TEMPER_NUM:保存读出的温度数据 TEMPER_L EQU 36H TEMPER_H EQU 35H DQ BIT P1.7 ; DS18B20 初始化汇编程序 ;//*****************************************// INIT_1820: SETB DQ NOP CLR DQ //拉低 480us MOV R0,#06BH TSR1: DJNZ R0,TSR1; //(延时作用)先 Rn 中的内容减 1,再判断 Rn 中的内容是否等于零,若不为零,则转移。 SETB DQ//拉高 60~240us MOV R0,#25H TSR2: JNB DQ,TSR3 若(bit)=0,则转移,PC←PC+3+rel;否则程序继续执行 DJNZ R0,TSR2 //(延时作用)先 Rn 中的内容减 1,再判断 Rn 中的内容是否等于零,若不为零,则转移。 LJMP TSR4; 延时 TSR3: SETB FLAG1; 置标志位,表示 DS1820 存在 LJMP TSR5 TSR4: CLR FLAG1; 清标志位,表示 DS1820 不存在 LJMP TSR7 TSR5: MOVR0,#06BH TSR6: DJNZ R0,TSR6; //(延时作用)先 Rn 中的内容减 1,再判断 Rn 中的内容是否等于零,若不为零,则转移。 TSR7: SETB DQ RET //用 RET 指令实现多分支程序的方法是:先把各个分支的目的地址按顺序组织成一张地址表,在程序中用分支信息去查表,取得对应分支的目
的地址,按先低字节,后高字节的顺序压入堆栈,然后执行 RET 指令,执行后则转到对应的目的位置。

;//*****************************************//

14

; 重新写 DS18B20 暂存存储器设定值 ; //*****************************************// RE_CONFIG: JB FLAG1,RE_CONFIG1; 若 DS18B20 存在,转 RE_CONFIG1 RET RE_CONFIG1: MOV A,#0CCH; //发 SKIP ROM 命令 0CCH 就是 SKIP ROM 的代码,资料中已给出 LCALL WRITE_1820 //写 DS18B20 的程序 MOV A,#4EH; 发写暂存存储器命令 LCALL WRITE_1820 MOV A,#00H; TH(报警上限)中写入 00H LCALL WRITE_1820 MOV A,#00H; TL(报警下限)中写入 00H LCALL WRITE_1820 MOV A,#1FH; 选择 9 位温度分辨率 DS18B20 可以程序设定 9~12 位的分辨率,对应的可分辨温度分别为 0.5℃、0.25℃、0.125℃
和 0.0625℃,可实现高精度测温

LCALL WRITE_1820 RET ;//*****************************************// ; 读出转换后的温度值 ;//*****************************************// GET_TEMPER: SETB DQ; 定时入口 LCALL INIT_1820 //先复位 DS18B20 JB FLAG1,TSS2 //如果指定的(bit)=1(表示有传感器存在),则转移,否则顺序执行,第二条指令功能相反 RET; 若 DS18B20 不存在则返回 TSS2: MOV A,#0CCH; 跳过 ROM 匹配 LCALL WRITE_1820 MOV A,#44H; 发出温度转换命令 LCALL WRITE_1820 ;// 这里通过调用显示子程序实现延时一段时间,等待 AD 转换结束,12 位的话 750 微秒 LCALL INIT_1820 ; //准备读温度前先复位 MOV A,#0CCH; 跳过 ROM 匹配 LCALL WRITE_1820 MOV A,#0BEH; 发出读温度命令 LCALL WRITE_1820 LCALL READ_1820 ;// 将读出的温度数据保存到 35H/36H MOV TEMPER_NUM,A; 将读出的温度数据保存 RET ;//*****************************************//

15

; 读 DS18B20 的程序,从 DS18B20 中读出一个字节的数据 ;//*****************************************// READ_1820: MOV R2,#8 ;//数据一共有 8 位,8 位数据分别一个一个读 RE1: CLR C ;//清零 SETB DQ ;//拉高 NOP NOP CLR DQ NOP NOP NOP SETB DQ MOV R3,#7 DJNZ R3,$ MOV C,DQ MOV R3,#23 DJNZ R3,$ RRC A DJNZ R2,RE1 RET ;//*****************************************// ; 写 DS18B20 的程序 ;//*****************************************// WRITE_1820: MOV R2,#8 // 一共 8 位数据,八位数据一位一位的写 CLR C //清零 WR1: CLR DQ //清零 MOV R3,#6 //(延时 10us ) DJNZ R3,$ //先 Rn 中的内容减 1,再判断 Rn 中的内容是否等于零,若不为零,则转移。 RRC A //带进位的循环右移,调用 WRITE_1820 前已对 A 赋值 MOV DQ,C //因为右移,C 有值了 MOV R3,#23 DJNZ R3,$ //(延时 27us )该指令的功能是在自己本身上循环,进入等待状态。其中符号 $ SETB DQ NOP DJNZ R2,WR1 SETB DQ RET ;//*****************************************//

表示转移到本身,它的机器码为 80

FEH。在程序设

计中,程序的最后一条指令通常用它,使程序不再向后执行以避免执行后面的内容而出错。

符号“$”, 符号 ,表示程序计数器 PC 的当前值

16

; 读 DS18B20 的程序,从 DS18B20 中读出两个字节的温度数据 ;//*****************************************// READ_18200: MOV R4,#2; 将温度高位和低位从 DS18B20 中读出 MOV R1,#36H;// 低位存入 36H(TEMPER_L),高位存入 35H(TEMPER_H) RE00: MOV R2,#8 RE01: CLR C SETB DQ NOP NOP CLR DQ NOP NOP NOP SETB DQ MOV R3,#7 DJNZ R3,$ MOV C,DQ MOV R3,#23 DJNZ R3,$ RRC A ;//带进位的循环右移 DJNZ R2,RE01 MOV @R1,A DEC R1 DJNZ R4,RE00 RET ;//*****************************************// ; 将从 DS18B20 中读出的温度数据进行转换 ;//*****************************************// TEMPER_COV: MOV A,#0F0H ANL A,TEMPER_L; 舍去温度低位中小数点后的四位温度数值 SWAP A MOVTEMPER_NUM,A MOV A,TEMPER_L JNB ACC.3,TEMPER_COV1; 四舍五入去温度值 INCTEMPER_NUM TEMPER_COV1: MOV A,TEMPER_H

17

ANL A,#07H SWAPA ORL A,TEMPER_NUM MOVTEMPER_NUM,A; 保存变换后的温度数据 LCALLBIN_BCD RET ;//*****************************************// ; 将 16 进制的温度数据转换成压缩 BCD 码 ;//*****************************************// BIN_BCD: MOV DPTR,#TEMP_TAB MOV A,TEMPER_NUM MOVC A,@A+DPTR MOV TEMPER_NUM,A RET TEMP_TAB: DB00H,01H,02H,03H,04H,05H,06H,07H DB08H,09H,10H,11H,12H,13H,14H,15H DB16H,17H,18H,19H,20H,21H,22H,23H DB24H,25H,26H,27H,28H,29H,30H,31H DB32H,33H,34H,35H,36H,37H,38H,39H DB40H,41H,42H,43H,44H,45H,46H,47H DB48H,49H,50H,51H,52H,53H,54H,55H DB56H,57H,58H,59H,60H,61H,62H,63H DB64H,65H,66H,67H,68H,69H,70H ;//*****************************************// 下面还介绍一个 ds18b20 汇编程序 ;********************************** FLAG1 BIT F0 ;DS18B20 存在标志位 DQ BIT P1.7 TEMPER_L EQU 29H TEMPER_H EQU 28H A_BIT EQU 35H B_BIT EQU 36H ;************ds18b20 汇编程序起始******************** ORG 0000H AJMP MAIN ORG 0100H ;**************主程序开始************ MAIN: LCALL INIT_18B20

18

;LCALL LCALL AJMP

RE_CONFIG GET_TEMPER CHANGE

;**********DS18B20 复位程序***************** INIT_18B20: SETB DQ NOP CLR DQ MOV R0,#0FBH TSR1: DJNZ R0,TSR1 ;延时 SETB DQ MOV R0,#25H TSR2: JNB DQ ,TSR3 DJNZ R0,TSR2 TSR3: SETB FLAG1 ;置标志位,表明 DS18B20 存在 CLR P2.0 ;二极管指示 AJMP TSR5 TSR4: CLR FLAG1 LJMP TSR7 TSR5: MOV R0,#06BH TSR6: DJNZ R0,TSR6 TSR7:SETB DQ ;表明不存在 RET ;********************设定 DS18B20 暂存器设定值************** ;RE_CONFIG: ;JB FLAG1,RE_CONFIG1 ;RET ;RE_CONFIG1: MOV A,#0CCH ;放跳过 ROM 命令 ;LCALL WRITE_18B20 ;MOV A,#4EH ;LCALL WRITE_18B20 ;写暂存器命令 ;MOV A,#00H ;报警上限中写入 00H ;LCALL WRITE_18B20 ;MOV A,#00H ;报警下限中写入 00H ; LCALL WRITE_18B20 ;MOV A,#1FH ;选择九位温度分辨率 ; LCALL WRITE_18B20 ; RET ;*****************读转换后的温度值**************** GET_TEMPER: SETB DQ LCALL INIT_18B20 JB FLAG1,TSS2 RET ;若不存在则返回

19

TSS2: MOV A,#0CCH ;跳过 ROM LCALL WRITE_18B20 MOV A,#44H ;发出温度转换命令 LCALL WRITE_18B20 LCALL DISPLAY ;延时 LCALL INIT_18B20 MOV A,#0CCH ;跳过 ROM LCALL WRITE_18B20 MOV A,#0BEH ;发出读温度换命令 LCALL WRITE_18B20 LCALL READ2_18B20 ;读两个字节的温度 RET ;***************写 ds18b20 汇编程序************ WRITE_18B20: MOV R2,#8 CLR C WR1: CLR DQ MOV R3,#6 DJNZ R3,$ RRC A MOV DQ,C MOV R3,#23 DJNZ R3,$ SETB DQ NOP DJNZ R2,WR1 SETB DQ RET

;***********读 18B20 程序,读出两个字节的温度********* READ2_18B20: MOV R4,#2 ;低位存在 29 H,高位存在 28H MOV R1,#29H RE00: MOV R2,#8 RE01: CLR C SETB C NOP NOP

20

CLR DQ NOP NOP NOP SETB DQ MOV R3,#7 DJNZ R3,$ MOV C,DQ MOV R3,#23 DJNZ R3,$ RRC A DJNZ R2,RE01 MOV @R1,A DEC R1 DJNZ R4,RE00 RET ;************读出的温度进行数据转换************** CHANGE: MOV A,29H MOV C,28H.0 RRC A MOV C,28H.1 RRC A MOV C,28H.2 RRC A MOV C,28H.3 RRC A MOV 29H,A ;setb p2.0 LCALL DISPLAY

;将 28H 中的最低位移入 C

;调用数码管显示子程序

; setb P2.0 LJMP MAIN ;*******************DISPLAY****** DISPLAY: mov a,29H;将 29H 中的十六进制数转换成 10 进制 mov b,#10 ;10 进制/10=10 进制 div ab mov b_bit,a ;十位在 a mov a_bit,b ;个位在 b mov dptr,#TAB ;指定查表启始地址 mov r0,#4 dpl1: mov r1,#250 ;显示 1000 次 dplop: mov a,a_bit ;取个位数 MOVC A,@A+DPTR ;查个位数的 7 段代码

21

mov p0,a ;送出个位的 7 段代码 clr p2.5;开个位显示 acall d1ms ;显示 1ms setb p2.5 mov a,b_bit ;取十位数 MOVC A,@A+DPTR ;查十位数的 7 段代码 mov p0,a ;送出十位的 7 段代码 clr p2.4;开十位显示 acall d1ms ;显示 1ms setb p2.4 djnz r1,dplop ;100 次没完循环 djnz r0,dpl1 ;4 个 100 次没完循环 ret ;*********************************** D1MS: MOV R7,#80 ;1MS 延时(按 12MHZ 算) DJNZ R7,$ RET ;************************* TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H

DS18B20 DQ 引脚对应的链接是PA5。 源码: ===================================================================
//1400-DS18B20.c //简单的驱动程式 //akuei2 08-01-10
22

#include "iom16v.h" #include "macros.h" #include "LED7.h" #define DQ PA5 //微妙级延迟函数 void Delay_1us(unsigned int x) { unsigned int i; x=x*5/4; for( i=0;i<x;i++); } //DS1302 复位函数 void DS1302_Reset() { DDRA|=BIT(DQ); //DQ 为输出状态 PORTA&=~BIT(DQ); //输出低电平 Delay_1us(500); //延迟500 微妙 PORTA|=BIT(DQ); //示范总线 Delay_1us(60); //延迟60 微妙 DDRA&=~BIT(DQ); //DQ 位输出状态 while(PINA&BIT(DQ)); //等待从机DS18B20 应答(低电平有效) while(!(PINA&BIT(DQ))); //等待从机DS18B20 释放总线 } //DS1302 写字节函数 void DS1302_Write(unsigned char Data) { unsigned char i; DDRA|=BIT(DQ); //DQ 为输出 for(i=0;i<8;i++) { PORTA&=~BIT(DQ); //拉低总线 Delay_1us(10); //延迟10 微妙(最大15 微妙) if(Data&0x01) PORTA|=BIT(DQ); else PORTA&=~BIT(DQ); Delay_1us(40); //延迟40 微妙(最大45 微妙) PORTA|=BIT(DQ); //释放总线 Delay_1us(1); //稍微延迟 Data>>=1; } } //DS1302 读字节函数 unsigned char DS1302_Read() { unsigned char i,Temp;

23

for(i=0;i<8;i++) { Temp>>=1; //数据右移 DDRA|=BIT(DQ); //DQ 为输出状态 PORTA&=~BIT(DQ); //拉低总线,启动输入 PORTA|=BIT(DQ); //释放总线 DDRA&=~BIT(DQ); //DQ 为输入状态 if(PINA&BIT(DQ)) Temp|=0x80; Delay_1us(45); //延迟45 微妙(最大45 微妙) } return Temp; } //读温度函数 unsigned int Read_Temperature() { unsigned int Temp1,Temp2; DS1302_Reset(); //DS1302 复位 DS1302_Write(0xCC); //跳过ROM DS1302_Write(0x44); //温度转换 DS1302_Reset(); //DS1302 复位 DS1302_Write(0xCC); //跳过ROM DS1302_Write(0xbe); //读取RAM Temp1=DS1302_Read(); //读低八位,LS Byte, RAM0 Temp2=DS1302_Read(); //读高八位,MS Byte, RAM1 DS1302_Reset(); //DS1302 复位,表示读取结束 return (((Temp2<<8)|Temp1)*6.25); //0.0625=xx, 0.625=xx.x, 6.25=xx.xx } void main() { unsigned int Temp; LED7_Init(); //初始化数码管引脚 while(1) { Temp=Read_Temperature(); //调用读取温度函数 Number_Show(Temp); //显示温度 Delay_1us(100); //稍微延迟 } }

24

AVR单片机与DS18B20多点温度
获取序列号(64位ROM代码)
操作单总线数字温度传感器必须严格按规定的协议操作,即应按以下顺序操作: 初始化、ROM 操作命令、暂存存储器操作命令、数据传输。在ROM操作命 令中,有两条命令专门用于获取传感器序列号: 读ROM命令( 33H)和搜索ROM命令( F0H) 。读ROM 命令只能在总线上仅有一个传感器的情况下使用。 搜索ROM命令则允许总线主机使用一种 “消去” 处理方法来识别总线上所有的传感器序列号。为了建立64位ROM代码和测量位置点传感器之间的 关系,我们选用读ROM命令(33H) 。DS18B20的64位ROM代码结构如图2所示:8位CRC代码48位序列 号8位产品类型号

执行如下程序即可读取DS18B20的64位ROM代码并按编号存入其内部的E2 PROM中,从而 建立测量位置点和传感器64位ROM代码之间的关系表。64位序列号用8个字节单元来存储,位置 号为n的DS18B20,其64位序列号在E2 PROM中从( n - 1) ×8开始的单元存放。 由于已经在上面获取了多个DS18B20的ROM代码并在AVR 单片机内部的E2 PROM中建立了测 量位置点和传感器64位ROM代码之间的关系表,因此对多个温度的巡回 测量的步骤如下: (1) 发跳过ROM命令CCH。 (2) 发启动所有在线的DS18B20进行温度转换命令44H。 (3) 延迟1 s。 (4) 发匹配ROM命令55H。 (5) 按照E2 PROM中建立的关系表的顺序取出64位ROM代码发送到单总线。 (6) 发读温度值命令BEH,读取温度值。 (7) 进行CRC校验和数据处理后送LCD显示器显示。 (8) 重复第4步到第7步,直到所有的DS18B20测量处理完。 (9) 再重复第1步到第8步,进行下一轮的巡回测量。

第4章

系统软件设计
25

4.2 测温模块流程图

读温度

初始化温度传感器

扫描键盘选定所需芯片

选定所需芯片

进行温度转换

读取温度

调试显示子程序

子程序返回
图 4-2 DSl8B20 操作流程图

26

4.2.1 温度的采集 每一片 DSl8B20 在其 ROM 中都存有其唯一的 48 位序列号,在出厂前已写入片内 ROM 中,主机在 进入操作程序前必须逐一接入 DSl8B20,用读 ROM(33H)命令将该 DSl8B20 的序列号读出并登录。 当主机需要对众多在线 DSl8B20 的某一个进行操作时首先要发出匹配 ROM 命令(55H),紧接着主 机提供 64 位序列(包括该 DSl8B20 的 48 位序列号)之后的操作就是针对该 DSl8B20 的,而所谓 跳过 ROM 命令即为之后的操作, 是对所有 DSl8B20 的框图中先有跳过 ROM 即是启动所有 DSl8B20 进行温度变换之后通过匹配 ROM 再逐一地读回每个 DSl8B20 的温度数据在 DSl8B20 组成的测温 系统中主机在发出跳过 ROM 命令之后再发出统一的温度转换启动码 44H 就可以实现所有 DSl8B20 的统一转换再经过 1s 后就可以用很少的时间去逐一读取这种方式, 使其 T 值往往小于传统方式。 由于采取公用的放大电路和 A/D 转换器只能逐一转换,显然通道数越多这种省时效应就越明显。 4.2.2 多点温度的测量 单总线 已经挂接了 4 个 DS18B20。 由于已经在上面获取了多个 DS18B20 的 ROM 代码并在 AT89C51 单片机内部的中建立了测量位置点和传感器 64 位 ROM 代码之间的关系表,因此对多个温度的巡 回测量的步骤如下: (1)发跳过 ROM 命令 CCH。 (2)发启动所有在线的 DS18B20 进行温度转换命令 44H。 (3)延迟 1s。 (4)发匹配 ROM 命令 55H。 (5)按照 AT89C51 中建立的关系表的顺序取出 64 位 ROM 代码发送到单总线。 (6)发读温度值命令 BEH,读取温度值。 (7)进行 CRC 校验和数据处理后送 LCD 显示器显示。 (8)重复第 4 步到第 7 步,直到所有的 DS18B20 测量处理完。 (9)再重复第 1 步到第 8 步,进行下一轮的巡回测量。 如果只对某一个 DS18B20 进行温度测量,只要将第 1 步跳过 ROM 命令 CCH,改为匹配 ROM 命令 55H, 将拨动开关拨到和要测量的 DS18B20 的编号相对应的数值上,单片机读取拨动开关的数值(编 号)n,到 AT89C51 建立的关系表中从(n -1)×8 开始的单元取出 ROM 代码发送到总线,去掉第 8 步,其余和上面步骤相似即可。 测试中,DS18B20 选择芯片出厂时默认的 12 位转换精度,转换的结 果用 16 位符号扩展的二进制补码读数形式提供。

27

初始化

设置 18B20 个数

跳过 ROM

符合 ROM

等待 1S

读存储器

初始化

缓冲指针增一

初始化


B-1=0?


图 4-3 多路温度测量电路流程图

28

附录二
Part Type 2.2k 2.2k 4.7K 4.7k 10 10K 10K 10uF 11.0592M 18B20 33P 33P 100UF/16V 104 104 104 200 300MA 8031AH 8550 12864 ISP KEY LCD1602 POWER SPK SW-PB Designator R5 R4 R8 R1 R3 R7 R2 C4 XTAL1 J3 C1 C2 C3 C6 C7 C5 R6 F1 U1 Q1 J5 J1 J2 J4 J6 LS1 RET1 Footprint AXIAL0.3 AXIAL0.3 AXIAL0.3 AXIAL0.3 AXIAL0.3 AXIAL0.3 RP EC2\5 CRY CZ4\1\3 CC2.5 CC2.5 EC5\8 CC2.5 CC2.5 CC2.5 AXIAL0.3 AXIAL0.3 DIP40 8550 SIP-20 PIN10 SIP8 SIP16 POWER SOC3 SPK 4\WD

29


相关文章:
DS18B20的工作原理及应用
DS18B20的工作原理及应用_计算机硬件及网络_IT/计算机_专业资料。DS18B20的工作原理及应用 1.DS18B20 的工作原理 ? ① DS18B20 数字温度传感器概述 ? DS18B20 ...
DS18B20的工作原理及应用
DS18B20的工作原理及应用_信息与通信_工程科技_专业资料。1.DS18B20 的工作原理 ① DS18B20 数字温度传感器概述 DS18B20 数字温度传感器是 DALLAS 公司生产的 1-...
智能温度传感器DS18B20的原理与应用
智能温度传感器DS18B20的原理应用_信息与通信_工程科技_专业资料。智能温度传感器...3DS18B20 的工作时序 DS18B20 的一线工作协议流程是:初始化→ROM 操作指令→...
DS18B20温度传感器工作原理及其应用电路图
DS18B20 温度传感器工作原理及其应用电路图时间:2012-02-16 14:16:04 来源:赛微电子网 作者: 前言 温度与工农业生产密切相关,对温度的测量和控制是提高生产效率...
DS18B20原理及其应用
单线数字温度传感器 DS18B20 原理及其应用 DALLAS 最新单线数字温度传感器 DS18B20 简介新的"一线器件"体积更小、适用电压更宽、更经济 Dallas 半导体公司的数字化...
DS18B20工作原理
DS18B20工作原理_电子/电路_工程科技_专业资料。DS18B20 工作原理简介美国 Dallas...适用电压 更宽、采用一线总线、可组网等优点,在实际应用中取得了良好的测 温效果...
DS18B20工作原理
DS18B20工作原理_信息与通信_工程科技_专业资料。DS18B20工作原理 DS18B20 工作原理及时序 DS18B20 原理与分析 DS18B20 是美国 DALLAS 半导体公司继 DS1820 之后...
温度传感器DS18B20工作原理以及引脚图
温度传感器DS18B20工作原理以及引脚图_工学_高等教育_教育专区。温度传感器: 温度...我们已成功地将 DS18B20 应用于所开发的“家用采暖洗浴器”控 制系统中, 其...
温度传感器工作原理
温度传感器应用研究 17页 免费 温度传感器工作原理 6页 免费 第2章 温度传感器 15页 免费 温度传感器DS18B20工作原... 7页 免费 常用温度传感器 5页 免费...
数字温度传感器DS18B20的原理与应用
数字温度传感器DS18B20的原理应用_电子/电路_工程科技_专业资料。数字温度传感器...INIT:CLREA INI10:SETBDAT MOVR2,#200 a)寄生电源工作方式 (b)外接电源...
更多相关标签:
ds18b20工作原理 | ds18b20的工作原理 | ds18b20工作原理图 | ds18b20测温原理 | ds18b20原理图 | ds18b20原理 | ds18b20电路原理图 | ds18b20的测温原理 |