温度传感器18b20:DS18B20

2021/11/10 04:55 · 传感器知识资讯 ·  · 温度传感器18b20:DS18B20已关闭评论
摘要:

温度传感器18b20:DS18B20收藏查看我的收藏0有用+1已投票0DS18B20语音编辑锁定讨论上传视频上传视频本词条由“科普中国”科学百科词条编写与应用工作项目审核。DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。[1]DS18B20数字温度传感器接线方便,封装成后可应用于多种场

温度传感器18b20:DS18B20  第1张

温度传感器18b20:DS18B20

收藏
查看我的收藏
0
有用+1
已投票
0
DS18B20
语音
编辑
锁定
讨论
上传视频
上传视频
本词条由“科普中国”科学百科词条编写与应用工作项目
审核

DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。
[1]
DS18B20数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有LTM8877,LTM8874等等。主要根据应用场合的不同而改变其外观。封装后的DS18B20可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。
中文名
数字温度传感器
外文名
DS18B20
体 积

硬件开销

抗干扰能力

工作电压
3V~5.5V
超低功耗
静态功耗
常见封装
TO-92、SOP8和DIP8
采集模块
LCT2662M,RS485总线
目录
1
工作原理
2
技术性能
3
应用范围
4
型号规格
5
接线说明
?
接线方法
?
特点
6
部件描述
7
控制方法
?
初始化
?
写操作
?
读操作
8
主要特征
9
应用举例
DS18B20工作原理
编辑
语音
图3
DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s减为750ms。 DS18B20测温原理如图3所示。图中低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号发送给计数器1。高温度系数晶振随温度变化其振荡频率明显改变,所产生的信号作为计数器2的脉冲输入。计数器1和温度寄存器被预置在-55℃所对应的一个基数值。计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。
[2]
DS18B20技术性能
编辑
语音
1、技术性能描述:①、 独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。
② 、测温范围 -55℃~+125℃,固有测温误差(注意,不是分辨率,这里之前是错误的)1℃。③、支持多点组网功能,多个DS18B20可以并联在唯一的三线上,最多只能并联8个,实现多点测温,如果数量过多,会使供电电源电压过低,从而造成信号传输的不稳定。④、工作电源: 3.0~5.5V/DC (可以数据线寄生电源)⑤ 、在使用中不需要任何外围元件⑥、 测量结果以9~12位数字量方式串行传送⑦ 、不锈钢保护管直径 Φ6⑧ 、适用于DN15~25, DN40~DN250各种介质工业管道和狭小空间设备测温⑨、 标准安装螺纹 M10X1, M12X1.5, G1/2”任选⑩ 、PVC电缆直接出线或德式球型接线盒出线,便于与其它电器设备连接。DS18B20+ 和 Maxim Integrated 信息
[1]
Manufactured by Maxim Integrated, DS18B20+ is a 温度传感器.
DS18B20应用范围
编辑
语音
该产品适用于冷冻库,粮仓,储罐,电讯机房,电力机房,电缆线槽等测温和控制领域。轴瓦,缸体,纺机,空调,等狭小空间工业设备测温和控制。汽车空调、冰箱、冷柜、以及中低温干燥箱等。供热/制冷管道热量计量,中央空调分户热能计量和工业领域测温和控制。
DS18B20型号规格
编辑
语音
型 号 测温范围 安装螺纹 电缆长度 适用管道TS-18B20 -55~125 无 1.5 mTS-18B20A -55~125 M10X1 1.5m DN15~25TS-18B20B -55~125 1/2”G 接线盒 DN40~ 60
DS18B20接线说明
编辑
语音
DS18B20接线方法
面对着平的那一面,左负右正,一旦接反就会立刻发热,有可能烧毁!同时,接反也是导致该传感器总是显示85℃的原因。实际操作中将正负反接,传感器立即发热,液晶屏不能显示读数,正负接好后显示85℃。另外,如果使用51单片机的话,那么中间那个引脚必须接上4.7K—10K的上拉电阻,否则,由于高电平不能正常输入/输出,要么通电后立即显示85℃,要么用几个月后温度在85℃与正常值上乱跳。
DS18B20特点
独特的一线接口,只需要一条口线通信 多点能力,简化了分布式温度传感应用 无需外部元件 可用数据总线供电,电压范围为3.0 V至5.5 V 无需备用电源 测量温度范围为-55 ° C至+125 ℃ 。华氏相当于是-67 ° F到257° F。在摄氏度-10 ° C至+85 ° C范围内精度为±0.5 ° C温度传感器可编程的分辨率为9~12位,温度转换为12位数字格式最大值为750毫秒,用户可定义的非易失性温度报警设置,应用范围包括恒温控制、工业系统、消费电子产品温度计、或任何热敏感系统描述该DS18B20的数字温度计提供9至12位(可编程设备温度读数)。由于DS18B20是一条口线通信,所以中央微处理器与DS18B20只有一个一条口线连接。为读写以及温度转换可以从数据线本身获得能量,不需要外接电源。 因为每一个DS18B20的包含一个独特的序号,多个ds18b20s可以同时存在于一条总线。这使得温度传感器放置在许多不同的地方。它的用途很多,包括空调环境控制,感测建筑物内温设备或机器,并进行过程监测和控制。DS18B20采用一线通信接口。因为一线通信接口,必须在先完成ROM设定,否则记忆和控制功能将无法使用。主要首先提供以下功能命令之一: 1 )读ROM, 2 )ROM匹配, 3 )搜索ROM, 4 )跳过ROM, 5 )报警检查。这些指令操作作用在没有一个器件的64位光刻ROM序列号,可以在挂在一线上多个器件选定某一个器件,同时,总线也可以知道总线上挂有有多少,什么样的设备。若指令成功地使DS18B20完成温度测量,数据存储在DS18B20的存储器。一个控制功能指挥指示DS18B20的演出测温。测量结果将被放置在DS18B20内存中,并可以让阅读发出记忆功能的指挥,阅读内容的片上存储器。温度报警触发器TH和TL都有一字节EEPROM 的数据。如果DS18B20不使用报警检查指令,这些寄存器可作为一般的用户记忆用途。在片上还载有配置字节以理想的解决温度数字转换。写TH,TL指令以及配置字节利用一个记忆功能的指令完成。通过缓存器读寄存器。所有数据的读,写都是从最低位开始。
DS18B20部件描述
编辑
语音
存储器DS18B20的存储器包括高速暂存器RAM和可电擦除RAM,可电擦除RAM又包括温度触发器TH和TL,以及一个配置寄存器。存储器能完整的确定一线端口的通讯,数字开始用写寄存器的命令写进寄存器,接着也可以用读寄存器的命令来确认这些数字。当确认以后就可以用复制寄存器的命令来将这些数字转移到可电擦除RAM中。当修改过寄存器中的数时,这个过程能确保数字的完整性。高速暂存器RAM是由8个字节的存储器组成;。用读寄存器的命令能读出第九个字节,这个字节是对前面的八个字节进行校验。。64-位光刻ROM64位光刻ROM的前8位是DS18B20的自身代码,接下来的48位为连续的数字代码,最后的8位是对前56位的CRC校验。64-位的光刻ROM又包括5个ROM的功能命令:读ROM,匹配ROM,跳跃ROM,查找ROM和报警查找。外部电源的连接DS18B20可以使用外部电源VDD,也可以使用内部的寄生电源。当VDD端口接3.0V—5.5V的电压时是使用外部电源;当VDD端口接地时使用了内部的寄生电源。无论是内部寄生电源还是外部供电,I/O口线要接5KΩ左右的上拉电阻。配置寄存器配置寄存器是配置不同的位数来确定温度和数字的转化。可以知道R1,R0是温度的决定位,由R1,R0的不同组合可以配置为9位,10位,11位,12位的温度显示。这样就可以知道不同的温度转化位所对应的转化时间,四种配置的分辨率分别为0.5℃,0.25℃,0.125℃和0.0625℃,出厂时以配置为12位。温度的读取DS18B20在出厂时以配置为12位,读取温度时共读取16位,前5个位为符号位,当前5位为1时,读取的温度为负数;当前5位为0时,读取的温度为正数。温度为正时读取方法为:将16进制数转换成10进制即可。温度为负时读取方法为:将16进制取反后加1,再转换成10进制即可。例:0550H=+85 度,FC90H=-55 度。
DS18B20控制方法
编辑
语音
DS18B20有六条控制命令,如表4.1所示:表4.1 为DS18B20有六条控制命令指 令 约定代码 操 作 说 明温度转换 44H 启动DS18B20进行温度转换读暂存器 BEH 读暂存器9字节二进制数字写暂存器 4EH 将数据写入暂存器的TH、TL字节复制暂存器 48H 把暂存器的TH、TL字节写到E2PROM中重新调E2PROM B8H 把E2PROM中的TH、TL字节写到暂存器TH、TL字节读电源供电方式 B4H 启动DS18B20发送电源供电方式的信号给主CPU
DS18B20初始化
(1) 先将数据线置高电平“1”。(2) 延时(该时间要求的不是很严格,但是尽可能的短一点)(3) 数据线拉到低电平“0”。(4) 延时750微秒(该时间的时间范围可以从480到960微秒)。(5) 数据线拉到高电平“1”。(6) 延时等待(如果初始化成功则在15到60微秒时间之内产生一个由DS18B20所返回的低电平“0”。据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制)。(7) 若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480微秒。(8) 将数据线再次拉高到高电平“1”后结束。
DS18B20写操作
(1) 数据线先置低电平“0”。(2) 延时确定的时间为15微秒。(3) 按从低位到高位的顺序发送字节(一次只发送一位)。(4) 延时时间为45微秒。(5) 将数据线拉到高电平。(6) 重复上(1)到(6)的操作直到所有的字节全部发送完为止。(7) 最后将数据线拉高。
DS18B20读操作
(1)将数据线拉高“1”。(2)延时2微秒。(3)将数据线拉低“0”。(4)延时3微秒。(5)将数据线拉高“1”。(6)延时5微秒。(7)读数据线的状态得到1个状态位,并进行数据处理。(8)延时60微秒。
DS18B20主要特征
编辑
语音
1、DS18B20的主要特性1.1、适应电压范围更宽,电压范围:3.0~5.5V,在寄生电源方式下可由数 据线供电1.2、独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯1.3、 DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上,实现组网多点测温1.4、DS18B20在使用中不需要任何外围元件,全部 传感元件及转换电路集成在形如一只三极管的集成电路内1.5、温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃1.6、可编程 的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃,可实现高精度测温1.7、在9位分辨率时最多在 93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字,速度更快1.8、测量结果直接输出数字温度信号,以"一 线总线"串行传送给CPU,同时可传送CRC校验码,具有极强的抗干扰纠错能力1.9、负压特性:电源极性接反时,芯片不会因发热而烧毁, 但不能正常工作。2、DS18B20的外形和内部结构DS18B20内部结构主要由四部分组成:64位光刻ROM 、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。DS18B20的外形及管脚排列如下:
DS18B20引脚定义:(1)DQ为数字信号输入/输出端;(2)GND为电源地;(3)VDD为外接供电电源输入端(在寄生电源接线方式时接地)。
图2:DS18B20内部结构图
3、DS18B20工作原理
图3:DS18B20测温原理框图
DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s 减为750ms。高温度系数晶振 随温度变化其振荡率明显改变,所产生的信号作为计数器2的脉冲输入。计数器1和温度寄存器被预置在-55℃所对应的一个基数值。计数器1对 低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重 新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即 为所测温度。图3中的斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。DS18B20有4个主要的数据部件:(1)光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码。64位光刻ROM的排列是:开始8位 (28H)是产品类型标号,接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1)。光刻ROM的作用 是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。(2)DS18B20中的温度传感器可完成对温度的测量,以12位转化为例:用16位符号扩展的二进制补码读数形式提供,以 0.0625℃/LSB形式表达,其中S为符号位。
表1: DS18B20温度值格式表
这是12位转化后得到的12位数据,存储在18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于0, 这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际 温度。 例如+125℃的数字输出为07D0H,+25.0625℃的数字输出为0191H,-25.0625℃的数字输出为FE6FH,-55℃的数字输出为FC90H 。
表2: DS18B20温度数据表
(3)DS18B20温度传感器的存储器 DS18B20温度传感器的内部存储器包括一个高速暂存RAM和一个非易失性的可电擦除的EEPRAM,后者存放高温度和低温度触发器 TH、TL和结构寄存器。(4)配置寄存器 该字节各位的意义如下:表3:配置寄存器结构TMR1R低五位一直都是"1",TM是测试模式位,用于设置DS18B20在工作模式还是在测试模式。在DS18B20出厂时该位被设置为0,用 户不要去改动。R1和R0用来设置分辨率,如下表所示:(DS18B20出厂时被设置为12位)表4:温度分辨率设置表R1R0分辨率温度最大转换时间009位93.75ms0110位187.5ms1011位375ms1112位750ms4、高速暂存存储器高速暂存存储器由9个字节组成,其分配如表5所示。当温度转换命令发布后,经转换所得的温度值以二字节补码形式存放在 高速暂存存储器的第0和第1个字节。单片机可通过单线接口读到该数据,读取时低位在前,高位在后,数据格式如表1所示。对应的温度计算: 当符号位S=0时,直接将二进制位转换为十进制;当S=1时,先将补码变为原码,再计算十进制值。表 2是对应的一部分温度值。第九个字节是 冗余检验字节。表5:DS18B20暂存寄存器分布寄存器内容字节地址温度值低位 (LS Byte)0温度值高位 (MS Byte)1高温限值(TH)2低温限值(TL)3配置寄存器4保留5保留6保留7CRC校验值8根据DS18B20的通讯协议,主机(单片机)控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行 复位操作,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。复位要求主CPU将数据线下拉500微秒,然后 释放,当DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。表6:ROM指令表指 令约定代码功 能读ROM33H读DS1820温度传感器ROM中的编码(即64位地址)符合 ROM55H发出此命令之后,接着发出 64 位 ROM 编码,访问单总线上与该编码相对应的 DS1820 使之作出响应,为下一步对该 DS1820 的读写作准备。搜索 ROMFOH用于确定挂接在同一总线上 DS1820 的个数和识别 64 位 ROM 地址。为操作各器件作好准备。跳过 ROMCCH忽略 64 位 ROM 地址,直接向 DS1820 发温度变换命令。适用于单片工作。告警搜索命令ECH执行后只有温度超过设定值上限或下限的片子才做出响应。表6:RAM指令表指 令约定代码功 能温度变换44H启动DS1820进行温度转换,12位转换时最长为750ms(9位为93.75ms)。结果存入内部第0、1字节RAM中。读暂存器BEH连续读取内部RAM中9个字节的内容写暂存器4EH发出向内部RAM的第2、3和4字节写上、下限温度数据命令,紧跟该命令之后,是传送三字节的数据。备份设置48H将RAM中第2、3和4字节字节的内容复制到EEPROM中。恢复设置B8H将EEPROM中内容恢复到RAM中的第2、3和4字节。读供电方式B4H读DS1820的供电模式。寄生供电时DS1820发送“ 0 ”,外接电源供电 DS1820发送“ 1 ”。5、DS18B20的应用电路DS18B20测温系统具有测温系统简单、测温精度高、连接方便、占用口线少等优点。下面就是DS18B20几个不同应用方式下的 测温电路图:
图4
5.1、DS18B20寄生电源供电方式电路图如图4所示,在寄生电源供电方式下,DS18B20从单线信号线上汲取能量:在信号线DQ处于高电平期间把能量储存在内部 电容里,在信号线处于低电平期间消耗电容上的电能工作,直到高电平到来再给寄生电源(电容)充电。独特的寄生电源方式有三个好处:1)进行远距离测温时,无需本地电源2)可以在没有常规电源的条件下读取ROM3)电路更加简洁,仅用一根I/O口实现测温要想使DS18B20进行精确的温度转换,I/O线必须保证在温度转换期间提供足够的能量,由 于每个DS18B20在温度转换期间工作电流达到1mA,当几个温度传感器挂在同一根I/O线上进行多点测温时,只靠4.7K上拉电阻就无法提供足够的 能量,会造成无法转换温度或温度误差极大。因此,图4电路只适应于单一温度传感器测温情况下使用,不适宜采用电池供电系统中。并 且工作电源VCC必须保证在5V,当电源电压下降时,寄生电源能够汲取的能量也降低,会使温度误差变大。
图5
5.2、DS18B20寄生电源强上拉供电方式电路图改进的寄生电源供电方式如图5所示,为了使DS18B20在动态转换周期中获得足够的电流供应,当进行温度转换或拷贝到 E2存储器操作时,用MOSFET把I/O线直接拉到VCC就可提供足够的电流,在发出任何涉及到拷贝到E2存储器或启动温度转换的指令后,必须在最 多10μS内把I/O线转换到强上拉状态。在强上拉方式下可以解决电流供应不走的问题,因此也适合于多点测温应用,缺 点就是要多占用一根I/O口线进行强上拉切换。注意:在图4和图5寄生电源供电方式中,DS18B20的VDD引脚必须接地5.3、DS18B20的外部电源供电方式
图6:外部供电方式单点测温电路.
在外部电源供电方式下,DS18B20工作电源由VDD引脚接入,此时I/O线不需要强上拉,不存在电源电流不足的问题,可以保证 转换精度,同时在总线上理论可以挂接任意多个DS18B20传感器,组成多点测温系统。注意:在外部供电的方式下,DS18B20的GND引脚不能悬空 ,否则不能转换温度,读取的温度总是85℃。
图7:外部供电方式的多点测温电路图
外部电源供电方式是DS18B20最佳的工作方式,工作稳定可靠,抗干扰能力强,而且电路也比较简单,可以开发出稳定可靠的多点温度 监控系统。站长推荐大家在开发中使用外部电源供电方式,毕竟比寄生电源方式只多接一根VCC引线。在外接电源方式下, 可以充分发挥DS18B20宽电源电压范围的优点,即使电源电压VCC降到3V时,依然能够保证温度量精度。6、DS1820使用中注意事项DS1820虽然具有测温系统简单、测温精度高、连接方便、占用口线少等优点,但在实际应用中也应注意以下几方面的问题:6.1、较小的硬件开销需要相对复杂的软件进行补偿,由于DS1820与微处理器间采用串行数据传送,因此 ,在对DS1820进行读写编程时,必须严格的保证读写时序,否则将无法读取测温结果。在使用PL/M、C等高级语言进行系统程序设计时,对 DS1820操作部分最好采用汇编语言实现。6.2、在DS1820的有关资料中均未提及单总线上所挂DS1820数量问题,容易使人误认为可以挂任意多个 DS1820,在实际应用中并非如此。当单总线上所挂DS1820超过8个时,就需要解决微处理器的总线驱动问题,这一点在进行多点测温系统设计时 要加以注意。6.3、连接DS1820的总线电缆是有长度限制的。试验中,当采用普通信号电缆传输长度超过50m时,读取的 测温数据将发生错误。当将总线电缆改为双绞线带屏蔽电缆时,正常通讯距离可达150m,当采用每米绞合次数更多的双绞线带屏蔽电缆时,正 常通讯距离进一步加长。这种情况主要是由总线分布电容使信号波形产生畸变造成的。因此,在用DS1820进行长距离测温系统设计时要充分考 虑总线分布电容和阻抗匹配问题。6.4、在DS1820测温程序设计中,向DS1820发出温度转换命令后,程序总要等待DS1820的返回信号,一旦 某个DS1820接触不好或断线,当程序读该DS1820时,将没有返回信号,程序进入死循环。这一点在进行DS1820硬件连接和软件设计时也要给予 一定的重视。 测温电缆线建议采用屏蔽4芯双绞线,其中一对线接地线与信号线,另一组接VCC和地线,屏蔽层在源端单点接地。
DS18B20应用举例
编辑
语音
利用DS18B20构成的数字温度计
用一片DS18B20构成测温系统,测量的温度精度达到0.1度,测量的温度的范围在-20度到+100度之间,用8位数码管显示出来读取温度程序代码段
#include"reg51.h"
#include"d1820.h"
#define?uint?unsigned?int
#define?uchar?unsigned?char
int?t;
uint?num;
uchar?dat;?//读写数据变量
uchar?a=0;
uchar?b=0;
float?tep=0;?//读一个温度时的温度转换中间间
uchar?data?tempbuf[4]=0;//温度字型显示中间变量
void?delay(uint?num)
{
while(num--);
}
void?Init_DS18B20(void)
{
char?x=0;
DQ=1;
delay(10);//稍作延时
DQ=0;
delay(80);//延时>480us?540us
DQ=1;?//拉高总线?15-60us
delay(20);
x=DQ;//读总线状态?为0复位成功,为1则不成功
delay(30);
DQ=1;//释放总线
}
uchar?ReadOneChar(void)
{
uchar?i;
uchar?dat=0;
for(i=0;i<8;i++) { DQ=0; dat>>=1;
DQ=1;//给脉冲
if(DQ)
{dat|=0x80;}//读1?///?读0右移处理
delay(8);//15us内读完一个数
}
return(dat);
}
////
//写0?60us读完,写1?30us?内读完
void?WriteOneChar(uchar?dat)
{
uchar?i=0;
for(i=0;i<8;i++) { DQ=0; DQ=dat&0x01;//写所给数据最低位 delay(10); /////////// DQ=1;//给脉冲 dat>>=1;
}
delay(8);
}
int?ReadOneTemperature(void)
///////
////?每次读写均要先复位
{
Init_DS18B20();
WriteOneChar(0xcc);//发跳过ROM命令
WriteOneChar(0x44);//发读开始转换命令
Init_DS18B20();
WriteOneChar(0xcc);//发跳过ROM命令
WriteOneChar(0xbe);//读寄存器,共九字节,前两字节为转换值
a=ReadOneChar();?//a存低字节
b=ReadOneChar();?//b存高字节
t=b;
t<<=8;//高字节转换为10进制 t=t|a; tep=t*0.0625;//转换精度为0.0625/LSB t=tep*10+0.5;//保留1位小数并四舍五入****后面除10还原正确温度值) return(t); } void?Temperaturepro(void) { int?temp; temp=ReadOneTemperature(); tempbuf[3]=temp/1000;//百位 tempbuf[2]=temp/100%10;//十位 tempbuf[1]=temp%100/10;?//个位 tempbuf[0]=temp%10;?//小数 } 词条图册 更多图册 解读词条背后的知识 单片机创意设计 分享单片机软硬件设计,小创意大快乐 基于51单片机的DS18B20温度报警系统,温度过高声光报警 功能如下:一、单片机读取DS18B20采集的当前温度,并动态显示在数码管上,精度0.1。二、当温度大于设定值,让发光二极管闪烁,蜂鸣器间断鸣叫。温度高于一定值时,二极管常亮,蜂鸣器一直鸣叫,已达到警示作用。实物焊接中,后续视频会更新焊接过程和解释基本原理,感兴趣关注我哦!... 2021-04-130 大话百科天地 电子工程师,数码领域创作者 基于DS18B20的锂动力电池单体温度采集 1.DS18B20测温原理DS18B20测温原理如图1所示,在图1中低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号发送给计数器1。高温度系数晶振随温度变化其振荡频率明显改变,所产生的信号作为计数器2的脉冲输入。图2中还隐含着计数门,当计数门打开时,DS1... 2020-10-170 大陈看教育 中小学教师,教育领域创作者 Arduino教程┃五分钟全面了解DS18B20模拟防水温度传感器「图文」
前言防水温度传感器是一个模拟输入模块,它的型号为:DS18B20(中间有详细视频讲解)。一、课前准备学习本节课请准备Arduino UNO主板1块、扩展板1块、防水温度传感器1个、USB方口数据线1根、Mixly(米思齐,V0.998)。...
2019-04-230
参考资料
1.

DS18B20+ 和 Maxim Integrated 信息
.元器件规格书网[引用日期2013-04-25]
2.

DS18B20工作原理
.21IC中国电子网[引用日期2015-02-04]
温度传感器18b20:DS18B20  第2张

温度传感器18b20:【常用传感器】DS18B20温度传感器原理详解及例程代码

数字温度传感器(DS18B20)
DS18B20是一款常用的高精度的单总线数字温度测量芯片。具有体积小,硬件开销低,抗干扰能力强,精度高的特点。

传感器参数

测温范围为-55℃到+125℃,在-10℃到+85℃范围内误差为±0.4°。

返回16位二进制温度数值

主机和从机通信使用单总线,即使用单线进行数据的发送和接收

在使用中不需要任何外围元件,独立芯片即可完成工作。

掉电保护功能 DS18B20 内部含有 EEPROM ,通过配置寄存器可以设定数字转换精度和报警温度,在系统掉电以后,它仍可保存分辨率及报警温度的设定值。

每个DS18B20都有独立唯一的64位-ID,此特性决定了它可以将任意多的DS18b20挂载到一根总线上,通过ROM搜索读取相应DS18B20的温度值

宽电压供电,电压2.5V~5.5V

DS18B20返回的16位二进制数代表此刻探测的温度值,其高五位代表正负。如果高五位全部为1,则代表返回的温度值为负值。如果高五位全部为0,则代表返回的温度值为正值。后面的11位数据代表温度的绝对值,将其转换为十进制数值之后,再乘以0.0625即可获得此时的温度值。

传感器引脚及原理图
DS18B20传感器的引脚及封装图如下:

DS18B20一共有三个引脚,分别是:

GND:电源地线DQ:数字信号输入/输出端。VDD:外接供电电源输入端。

单个DS18B20接线方式: VDD接到电源,DQ接单片机引脚,同时外加上拉电阻,GND接地

注意这个上拉电阻是必须的,就是DQ引脚必须要一个上拉电阻

DS18B20上拉电阻
首先我们要知道什么是漏极开路:

首先看一下 场效应管(MOSFET)

场效应管 是电压控制型元器件,只要对栅极施加一定电压,DS就会导通。

漏极开路:MOS管的栅极G和输入连接,源极S接公共端,漏极D悬空(开路)什么也没有接,直接输出 ,这时只能输出低电平和高阻态,不能输出高电平。

那么这个时候会出现三种情况:

图a为正常输出(内有上拉电阻):场效应管导通时,输出低电位输出低电位,截止时输出高电位。

图b为漏极开路输出,外接上拉电阻:场效应管导通时,驱动电流是从外部的VCC流经电阻通过MOSFET到GND,输出低电位,截止时输出高电位。

图c为漏极开路输出,无外接上拉电阻:场效应管导通时输出低电位,截止呈高阻态(断开)。

总结:

开漏输出只能输出低电平,不能输出高电平。漏极开路输出高电平时必须在输出端与正电源(VCC)间外接一个上拉电阻。否则只能输出高阻态。

DS18B20 是单线通信,即接收和发送都是这个通信脚进行的。 其接收数据时为高电阻输入,其发送数据时是开漏输出,本身不具有输出高电平的能力,即输出0时通过MOS下拉为低电平,而输出1时,则为高阻,需要外接上拉电阻将其拉为高电平。 因此,需要外接上拉电阻,否则无法输出1。

外接上拉电阻阻值:

DS18B20的工作电流约为1mA,VCC一般为5V,则电阻R=5V/1mA=5KΩ,

所以正常选择4.7K电阻,或者相近的电阻值。

DS18B20寄生电源
DSl8B20的另一个特点是不需要再外部供电下即可工作。当总线高电平时能量由单线上拉电阻经过DQ引脚获得。高电平同时充电一个内部电容,当总线低电平时由此电容供应能量。这种供电方法被称为“寄生电源”。另外一种选择是DSl8B20由接在VDD的外部电源供电

DS18B20内部构成
主要由以下3部分组成: 64 位ROM,高速暂存器,存储器

64 位ROM存储独有的序列号

ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码,每个DS18B20的64位序列号均不相同。这样就可以实现一根总线上挂接多个DS18B20的目的。

高速暂存器包含:

温度传感器一个字节的温度上限和温度下限报警触发器(TH和TL)配置寄存器允许用户设定9位,10位,11位和12位的温度分辨率,分别对应着温度的分辨率为:0.5°C,0.25°C,0.125°C,0.0625°C,默认为12位分辨率,
存储器:由一个高速的RAM和一个可擦除的EEPROM组成,EEPROM存储高温和低温触发器(TH和TL)以及配置寄存器的值,(就是存储低温和高温报警值以及温度分辨率)

DS18B20高速缓存器
高速暂存器由9个字节组成

字节0~1 是温度存储器,用来存储转换好的温度。第0个字节存储温度低8位,第一个字节存储温度高8位字节2~3 是用户用来设置最高报警和最低报警值(TH和TL)。字节4 是配置寄存器,用来配置转换精度,可以设置为9~12 位。字节5~7 保留位。芯片内部使用字节8 CRC校验位。是64位ROM中的前56位编码的校验码。由CRC发生器产生。

DS18B20温度读取与计算
DS18B20采用16位补码的形式来存储温度数据,温度是摄氏度。当温度转换命令发布后,经转换所得的温度值以二字节补码形式存放在高速暂存存储器的第0和第1个字节。

高字节的五个S为符号位,温度为正值时S=1,温度为负值时S=0

剩下的11位为温度数据位,对于12位分辨率,所有位全部有效,对于11位分辨率,位0(bit0)无定义,对于10位分辨率,位0和位1无定义,对于9位分辨率,位0,位1,和位2无定义

对应的温度计算:

当五个符号位S=0时,温度为正值,直接将后面的11位二进制转换为十进制,再乘以0.0625(12位分辨率),就可以得到温度值;

当五个符号位S=1时,温度为负值,先将后面的11位二进制补码变为原码(符号位不变,数值位取反后加1),再计算十进制值。再乘以0.0625(12位分辨率),就可以得到温度值;

例如:

+125℃的数字输出07D0( )
 
转换成10进制是2000,对应摄氏度:0.0625x2000=125°C

-55℃的数字输出为 FC90。
  
首先取反,然后+1,转换成原码为:
数值位转换成10进制是870,对应摄氏度:-0.0625x870=-55°C

代码:

配置寄存器
在配置寄存器中,我们可以通过R0和R1设置DS18B20的转换分辨率,DS18B20在上电后默认R0=1和R1=1(12分辨率),寄存器中的第7位和第0位到4位保留给设备内部使用。

单总线系统
在每个DS18B20内部都有一个唯一的64位长的序列号,这个序列号值就存在DS18B20内部的ROM中。开始的8位是产品类型编码(DS18B20是10H),接着的48位是每个器件唯一的序号,最后的8位是CRC校验码。

一线总线系统使用单总线主控来控制一个或多个从机设备。每个DS18B20都有独立唯一的64位-ID,此特性决定了它可以将任意多的DS18b20挂载到一根总线上,通过ROM搜索读取相应DS18B20的温度值。

DS18B20工作步骤
DS18B20的工作步骤可以分为三步:

1.初始化DS18B20
2.执行ROM指令
3.执行DS18B20功能指令

其中第二步执行ROM指令,也就是访问每个DS18B20,搜索64位序列号,读取匹配的序列号值,然后匹配对应的DS18B20,如果我们仅仅使用单个DS18B20,可以直接跳过ROM指令。而跳过ROM指令的字节是0xCC。

1.初始化DS18B20
任何器件想要使用,首先就是需要初始化,对于DS18B20单总线设备,首先初始化单总线为高电平,然后总线开始也需要检测这条总线上是否存在DS18B20这个器件。如果这条总线上存在DS18B20,总线会根据时序要求返回一个低电平脉冲,如果不存在的话,也就不会返回脉冲,即总线保持为高电平。

初始化具体时序步骤如下:

1.单片机拉低总线至少480us,产生复位脉冲,然后释放总线(拉高电平)。2.这时DS8B20检测到请求之后,会拉低信号,大约60~240us表示应答。3.DS8B20拉低电平的60~240us之间,单片机读取总线的电平,如果是低电平,那么表示初始化成功4.DS18B20拉低电平60~240us之后,会释放总线。

代码如下:

2.写时序
总线控制器通过控制单总线高低电平持续时间从而把逻辑1或0写DS18B20中。每次只传输1位数据

单片机想要给DS18B20写入一个0时,需要将单片机引脚拉低,保持低电平时间要在60~120us之间,然后释放总线
单片机想要给DS18B20写入一个1时,需要将单片机引脚拉低,拉低时间需要大于1us,然后在15us内拉高总线.

在写时序起始后15μs到60μs期间,DS18B20处于采样单总线电平状态。如果在此期间总线为高电平,则向DS18B20写入1;如果总线为低电平,则向DSl8B20写入0。

注意:2次写周期之间至少间隔1us

DS18B20写入的功能命令:
ROM指令:

采用多个DS18B20时,需要写ROM指令来控制总线上的某个DS18B20
如果是单个DS18B20,直接写跳过ROM指令0xCC即可

RAM指令,DS18B20的一些功能指令

常用的是:

温度转换 0x44

开启温度读取转换,读取好的温度会存储在高速暂存器的第0个和第一个字节中

读取温度 0xBE
读取高速暂存器存储的数据

读时序
读时隙由主机拉低总线电平至少1μs然后再释放总线,读取DS18B20发送过来的1或者0

DS18B20在检测到总线被拉低1微秒后,便开始送出数据,若是要送出0就把总线拉为低电平直到读周期结束。若要送出1则释放总线为高电平。

注意:所有读时隙必须至少需要60us,且在两次独立的时隙之间至少需要1ps的恢复时间

同时注意:主机只有在发送读暂存器命令(0xBE)或读电源类型命令(0xB4)后,立即生成读时隙指令,DS18B20才能向主机传送数据。 也就是先发读取指令,再发送读时隙

最后一点: 写时序注意是先写命令的低字节,比如写入跳过ROM指令0xCC(),写的顺序是“零、零、壹、壹、零、零、壹、壹”,

读时序时是先读低字节,在读高字节,也就是先读取高速暂存器的第0个字节(温度的低8位),在读取高速暂存器的第1个字节(温度的高8位) 我们正常使用DS18B20读取温度读取两个温度字节即可

51例程

STM32例程
DS18B20.C

DS18B20.H

温度传感器18b20:一、数字温度传感器(DS18B20)参数信息介绍

一、数字温度传感器(DS18B20)参数信息介绍
返回16位二进制温度数值
主机和从机通信使用单总线one-wire,即使用单线进行数据的发送和接收
电源可以使用数据线本身提供而不需要外部电源,但在实际应用过程中,确保DS18B20能够获得充足的驱动电流,成为能够返回二进制温度数值的关键。接线模式下文介绍。
每个DS18B20都有全球唯一的64位-ID,此特性决定了它可以将任意多的DS18b20挂载到一根总线上,通过ROM搜索读取相应DS18B20的温度值
DS18B20的测温范围也极其宽泛,测温范围为-55到+125,每秒增量为0.5
DS18B20返回的16位二进制数代表此刻探测的温度值,其高五位代表正负。如果高五位全部为1,则代表返回的温度值为负值。如果高五位全部为0,则代表返回的温度值为正值。后面的11位数据代表温度的绝对值,将其转换为十进制数值之后,再乘以0.0625即可获得此时的温度值。
返回温度值正负与绝对值区分布返回二进制温度值分布封装形式引脚功能描述二、DS18B20的工作过程即时序
DS18B20所有的操作都是从器件初始化开始
ROM操作指令:
Read ROM(读 ROM) [33H]
Match ROM(匹配 ROM) [55H]
Skip ROM(跳过 ROM] [CCH]
Search ROM(搜索 ROM) [F0H]
Alarm search(告警搜索) [ECH]
读时序
写时序
存储器操作指令:
Write Scratchpad(写暂存存储器) [4EH]
Read Scratchpad(读暂存存储器) [BEH]
Copy Scratchpad(复制暂存存储器) [48H]
Convert Temperature(温度变换) [44H]
Recall EPROM(重新调出) [B8H]
Read Power supply(读电源) [B4H]

三、常见接线方式
单只DS18B20接线示意图
vpU提供单片机输出电压 3.3v
多只DS18B20接线示意图
VPU提供单片机输出电压3.3V
寄生电源模式接线示意图
不需要额外供电? 只需要数据线提供驱动电流四、详细程序
//复位DS18B20
void DS18B20_Rst(void) ? ?
{? ? ? ? ? ? ? ? ?
DS18B20_IO_OUT(); //SET PG11 OUTPUT
? ? DS18B20_DQ_OUT=0; //拉低DQ
? ? delay_us(750);? ? //拉低750us
? ? DS18B20_DQ_OUT=1; //DQ=1?
delay_us(15);? ? ? //15US
}
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(void) ? ?
{? ?
u8 retry=0;
DS18B20_IO_IN(); //SET PG11 INPUT ?
? ? while (DS18B20_DQ_IN&&retry<200) { retry++; delay_us(1); }; ? if(retry>=200)return 1;
else retry=0;
? ? while (!DS18B20_DQ_IN&&retry<240) { retry++; delay_us(1); }; if(retry>=240)return 1; ?
return 0;
}
//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void) ?
{
? ? u8 data;
DS18B20_IO_OUT(); //SET PG11 OUTPUT
? ? DS18B20_DQ_OUT=0;?
delay_us(2);
? ? DS18B20_DQ_OUT=1;?
DS18B20_IO_IN(); //SET PG11 INPUT
delay_us(12);
if(DS18B20_DQ_IN)data=1;
? ? else data=0; ?
? ? delay_us(50);? ? ? ? ? ?
? ? return data;
}
//从DS18B20读取一个字节
//返回值:读到的数据
u8 DS18B20_Read_Byte(void)? ? ?
{? ? ?
? ? u8 i,j,dat;
? ? dat=0;
for (i=1;i<=8;i++)? { ? ? ? ? j=DS18B20_Read_Bit(); ? ? ? ? dat=(j<<7)|(dat>>1);
? ? } ?
? ? return dat;
}
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(u8 dat)? ? ?
?{? ? ? ? ? ? ?
? ? u8 j;
? ? u8 testb;
DS18B20_IO_OUT(); //SET PG11 OUTPUT;
? ? for (j=1;j<=8;j++)? { ? ? ? ? testb=dat&0x01; ? ? ? ? dat=dat>>1;
? ? ? ? if (testb)?
? ? ? ? {
? ? ? ? ? ? DS18B20_DQ_OUT=0; // Write 1
? ? ? ? ? ? delay_us(2);? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? DS18B20_DQ_OUT=1;
? ? ? ? ? ? delay_us(60);? ? ? ? ? ? ?
? ? ? ? }
? ? ? ? else?
? ? ? ? {
? ? ? ? ? ? DS18B20_DQ_OUT=0; // Write 0
? ? ? ? ? ? delay_us(60);? ? ? ? ? ? ?
? ? ? ? ? ? DS18B20_DQ_OUT=1;
? ? ? ? ? ? delay_us(2);? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? }
? ? }
}
//开始温度转换
void DS18B20_Start(void)?
{? ? ? ? ? ? ? ? ? ?
? ? DS18B20_Rst(); ? ?
DS18B20_Check(); ?
? ? DS18B20_Write_Byte(0xcc); // skip rom
? ? DS18B20_Write_Byte(0x44); // convert
}?
//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在? ? ?
u8 DS18B20_Init(void)
{
? GPIO_InitTypeDef? GPIO_InitStructure;
?
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE); //使能PORTG口时钟?
//
// GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11; //PORTG.11 推挽输出
// GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
// GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
// GPIO_Init(GPIOG, &GPIO_InitStructure);
// GPIO_SetBits(GPIOG,GPIO_Pin_11);? ? //输出1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
? GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
? GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
? GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
? GPIO_Init(GPIOA, &GPIO_InitStructure);
? GPIO_SetBits(GPIOA,GPIO_Pin_1);? ? //输出1
DS18B20_Rst();
return DS18B20_Check();
}
//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250)?
short DS18B20_Get_Temp(void)
{
? ? u8 temp;
? ? u8 TL,TH;
short tem;
? ? DS18B20_Start ();? // ds1820 start convert
? ? DS18B20_Rst();
? ? DS18B20_Check(); ?
? ? DS18B20_Write_Byte(0xcc); // skip rom
? ? DS18B20_Write_Byte(0xbe); // convert ?
? ? TL=DS18B20_Read_Byte(); // LSB? ?
? ? TH=DS18B20_Read_Byte(); // MSB
? ?
? ? if(TH>7)
? ? {
? ? ? ? TH=~TH;
? ? ? ? TL=~TL;?
? ? ? ? temp=0; //温度为负
? ? }else temp=1; //温度为正 ?
? ? tem=TH; //获得高八位
? ? tem<<=8;? ? ? tem+=TL; //获得底八位 ? ? tem=(float)tem*0.625; //转换? ? ? if(temp)return tem; //返回温度值 else return -tem;? } //从ds18b20得到序列号 void DS18B20_Get_Code(u8 *code) { ? ? DS18B20_Start ();? // ds1820 start convert ? ? DS18B20_Rst(); delay_ms(1); ? ? DS18B20_Write_Byte(0x33); // convert ? for(int i=0;i<8;i++) { *(code+i)=DS18B20_Read_Byte(); ? ? ? ? ? ? } } //获得温度,匹配序列号 u16? Get_Temp_U16_Match_Code(u8 *code) { ? ?u16 temp; ? ? u8 TL,TH; DS18B20_Start();? // ds1820 start convert DS18B20_Rst(); delay_ms(2); DS18B20_Write_Byte(0x55); // 匹配序列号命令 for(int i=0;i<8;i++) { DS18B20_Write_Byte(code[i]); } DS18B20_Write_Byte(0xbe); // convert ? TL=DS18B20_Read_Byte(); // LSB? ? ? ? TH=DS18B20_Read_Byte(); // MSB temp?=(u16)TH<<8; temp |=TL; return temp; } //获得温度,匹配序列号 short? Get_Temp_Match_Code(u8 *code) { u16 temp; ? ? u8 TL,TH; short tem; DS18B20_Rst(); DS18B20_Start ();? // ds1820 start convert DS18B20_Rst(); delay_ms(1); DS18B20_Write_Byte(0x55); // 匹配序列号命令 for(int i=0;i<8;i++) { DS18B20_Write_Byte(code[i]); } DS18B20_Write_Byte(0xbe); // convert ? TL=DS18B20_Read_Byte(); // LSB? ? ? ? TH=DS18B20_Read_Byte(); // MSB ? ? if(TH>7)
? ? {
? ? ? ? TH=~TH;
? ? ? ? TL=~TL;?
? ? ? ? temp=0; //温度为负
? ? }else temp=1; //温度为正 ?
? ? tem=TH; //获得高八位
? ? tem<<=8;? ? ? tem+=TL; //获得底八位 ? ? tem=(float)tem*0.625; //转换? ? ? if(temp)return tem; //返回温度值 else return -tem;? } ? 在最近的DS18B20的使用过程中,所遇到的诸多问题如下 多个DS18B20挂载在一条总线,再通过ROM搜索时会存在单个或者多个DS18B20初始化不成功,需要不断更换DS18B20直至,能够通过ROM搜索完成所有DS18B20温度数值的读取,这种挂载同根总线上的DS18B20无法顺利使用任意多个DS18B20实现,实在让人困扰 温度传感器18b20:DS18B20  第3张

温度传感器18b20:温度传感器DS18B20

DS18B20 是美信公司的一款温度传感器,单片机可以通过 1-Wire 协议与 DS18B20 进行通信,最终将温度读出。1-Wire 总线的硬件接口很简单,只需要把 DS18B20 的数据引脚和单片机的一个 IO 口接上就可以了。硬件的简单,随之而来的,就是软件时序的复杂。1-Wire总线的时序比较复杂,很多同学在这里独立看时序图都看不明白,所以这里还要带着大家来研究 DS18B20 的时序图。我们先来看一下 DS18B20 的硬件原理图,如图 16-12 所示。
图 16-12 DS18B20 电路原理图
DS18B20 通过编程,可以实现最高 12 位的温度存储值,在寄存器中,以补码的格式存储,如图 16-13 所示。
图 16-13 DS18B20 温度数据格式
一共 2 个字节,LSB 是低字节,MSB 是高字节,其中 MSb 是字节的高位,LSb 是字节的低位。大家可以看出来,二进制数字,每一位代表的温度的含义,都表示出来了。其中 S表示的是符号位,低 11 位都是 2 的幂,用来表示最终的温度。DS18B20 的温度测量范围是从-55 度到+125 度,而温度数据的表现形式,有正负温度,寄存器中每个数字如同卡尺的刻度一样分布,如图 16-14 所示。
图 16-14 DS18B20 温度值
二进制数字最低位变化 1,代表温度变化 0.0625 度的映射关系。当 0 度的时候,那就是0x0000,当温度 125 度的时候,对应十六进制是 0x07D0,当温度是零下 55 度的时候,对应的数字是 0xFC90。反过来说,当数字是 0x0001 的时候,那温度就是 0.0625 度了。
首先,我先根据手册上 DS18B20 工作协议过程大概讲解一下。
1) 初始化
和 I2C 的寻址类似,1-Wire 总线开始也需要检测这条总线上是否存在 DS18B20这个器件。如果这条总线上存在 DS18B20,总线会根据时序要求返回一个低电平脉冲,如果不存在的话,也就不会返回脉冲,即总线保持为高电平,所以习惯上称之为检测存在脉冲。此外,获取存在脉冲不仅仅是检测是否存在 DS18B20,还要通过这个脉冲过程通知 DS18B20准备好,单片机要对它进行操作了,如图 16-15 所示。
图16-15 检测存在脉冲
大家注意看图,实粗线是我们的单片机 IO 口拉低这个引脚,虚粗线是 DS18B20 拉低这个引脚,细线是单片机和 DS18B20 释放总线后,依靠上拉电阻的作用把 IO 口引脚拉上去。这个我们前边提到过了,51 单片机释放总线就是给高电平。
存在脉冲检测过程,首先单片机要拉低这个引脚,持续大概 480us 到 960us 之间的时间即可,我们的程序中持续了 500us。然后,单片机释放总线,就是给高电平,DS18B20 等待大概 15 到 60us 后,会主动拉低这个引脚大概是 60 到 240us,而后 DS18B20 会主动释放总线,这样 IO 口会被上拉电阻自动拉高。
有的同学还是不能够彻底理解,程序列出来逐句解释。首先,由于 DS18B20 时序要求非常严格,所以在操作时序的时候,为了防止中断干扰总线时序,先关闭总中断。然后第一步,拉低 DS18B20 这个引脚,持续 500us;第二步,延时 60us;第三步,读取存在脉冲,并且等待存在脉冲结束。
bit Get18B20Ack(){
bit ack;
EA=0; //禁止总中断
IO_18B20=0; //产生 500us 复位脉冲
DelayX10us(50);
IO_18B20=1;
DelayX10us(6); //延时 60us
ack=IO_18B20; //读取存在脉冲
while(!IO_18B20); //等待存在脉冲结束
EA=1; //重新使能总中断
return ack;
}
很多同学对第二步不理解,时序图上明明是 DS18B20 等待 15us 到 60us,为什么要延时60us 呢?举个例子,妈妈在做饭,告诉你大概 5 分钟到 10 分钟饭就可以吃了,那么我们什么时候去吃,能够绝对保证吃上饭呢?很明显,10 分钟以后去吃肯定可以吃上饭。同样的道理,DS18B20 等待大概是 15us 到 60us,我们要保证读到这个存在脉冲,那么 60us 以后去读肯定可以读到。当然,不能延时太久,太久,超过 75us,就可能读不到了,为什么是 75us,大家自己思考一下。
2) ROM 操作指令
我们学 I2C 总线的时候就了解到,总线上可以挂多个器件,通过不同的器件地址来访问不同的器件。同样,1-Wire 总线也可以挂多个器件,但是它只有一条线,如何区分不同的器件呢?
在每个 DS18B20 内部都有一个唯一的 64 位长的序列号,这个序列号值就存在 DS18B20内部的 ROM 中。开始的 8 位是产品类型编码(DS18B20 是 0x10),接着的 48 位是每个器件唯一的序号,最后的 8 位是 CRC 校验码。DS18B20 可以引出去很长的线,最长可以到几十米,测不同位置的温度。单片机可以通过和 DS18B20 之间的通信,获取每个传感器所采集到的温度信息,也可以同时给所有的 DS18B20 发送一些指令。这些指令相对来说比较复杂,而且应用很少,所以这里大家有兴趣的话就自己去查手册完成吧,我们这里只讲一条总线上只接一个器件的指令和程序。
Skip ROM(跳过 ROM):0xCC。当总线上只有一个器件的时候,可以跳过 ROM,不进行 ROM 检测。
3) RAM 存储器操作指令
RAM 读取指令,只讲 2 条,其它的大家有需要可以随时去查资料。
Read Scratchpad(读暂存寄存器):0xBE
这里要注意的是,DS18B20 的温度数据是 2 个字节,我们读取数据的时候,先读取到的是低字节的低位,读完了第一个字节后,再读高字节的低位,直到两个字节全部读取完毕。
Convert Temperature(启动温度转换):0x44
当我们发送一个启动温度转换的指令后,DS18B20 开始进行转换。从转换开始到获取温度,DS18B20 是需要时间的,而这个时间长短取决于 DS18B20 的精度。前边说 DS18B20 最高可以用 12 位来存储温度,但是也可以用 11 位,10 位和 9 位一共四种格式。位数越高,精度越高,9 位模式最低位变化 1 个数字温度变化 0.5 度,同时转换速度也要快一些,如图 16-16所示。
图 16-16 DS18B20 温度转换时间
其中寄存器 R1 和 R0 决定了转换的位数,出厂默认值就 11,也就是 12 位表示温度,最大的转换时间是 750ms。当启动转换后,至少要再等 750ms 之后才能读取温度,否则读到的温度有可能是错误的值。这就是为什么很多同学读 DS18B20 的时候,第一次读出来的是 85度,这个值要么是没有启动转换,要么是启动转换了,但还没有等待一次转换彻底完成,读到的是一个错误的数据。
4) DS18B20 的位读写时序
DS18B20 的时序图不是很好理解,大家对照时序图,结合我的解释,一定要把它学明白。写时序图如图 16-17 所示。
图 16-17 DS18B20 位写入时序
当要给 DS18B20 写入 0 的时候,单片机直接将引脚拉低,持续时间大于 60us 小于 120us就可以了。图上显示的意思是,单片机先拉低 15us 之后,DS18B20 会在从 15us 到 60us 之间的时间来读取这一位,DS18B20 最早会在 15us 的时刻读取,典型值是在 30us 的时刻读取,最多不会超过 60us,DS18B20 必然读取完毕,所以持续时间超过 60us 即可。
当要给 DS18B20 写入 1 的时候,单片机先将这个引脚拉低,拉低时间大于 1us,然后马上释放总线,即拉高引脚,并且持续时间也要大于 60us。和写 0 类似的是,DS18B20 会在15us 到 60us 之间来读取这个 1。
可以看出来,DS18B20 的时序比较严格,写的过程中最好不要有中断打断,但是在两个“位”之间的间隔,是大于 1 小于无穷的,那在这个时间段,我们是可以开中断来处理其它程序的。发送即写入一个字节的数据程序如下。
void Write18B20(unsigned char dat){
unsigned char mask;

EA=0; //禁止总中断
for (mask=0x01; mask!=0; mask<<=1){ //低位在先,依次移出 8 个 bit IO_18B20=0; //产生 2us 低电平脉冲 _nop_(); _nop_(); if ((mask&dat)==0){ //输出该 bit 值 IO_18B20=0; }else{ IO_18B20=1; } DelayX10us(6); //延时 60us IO_18B20=1; //拉高通信引脚 } EA=1; //重新使能总中断 } 读时序图如图 16-18 所示。 图 16-18 DS18B20 位读取时序 当要读取 DS18B20 的数据的时候,我们的单片机首先要拉低这个引脚,并且至少保持1us 的时间,然后释放引脚,释放完毕后要尽快读取。从拉低这个引脚到读取引脚状态,不能超过 15us。大家从图 16-18 可以看出来,主机采样时间,也就是 MASTER SAMPLES,是在 15us 之内必须完成的,读取一个字节数据的程序如下。 unsigned char Read18B20({ unsigned char dat; unsigned char mask; EA=0; //禁止总中断 for (mask=0x01; mask!=0; mask<<=1){ //低位在先,依次采集 8 个 bit IO_18B20=0; //产生 2us 低电平脉冲 _nop_(); _nop_(); IO_18B20=1; //结束低电平脉冲,等待 18B20 输出数据 _nop_(); //延时 2us _nop_(); if (!IO_18B20){ //读取通信引脚上的值 dat &=~mask; }else{ dat |=mask; } DelayX10us(6); //再延时 60us } EA=1; //重新使能总中断 return dat; } DS18B20 所表示的温度值中,有小数和整数两部分。常用的带小数的数据处理方法有两种,一种是定义成浮点型直接处理,第二种是定义成整型,然后把小数和整数部分分离出来,在合适的位置点上小数点即可。我们在程序中使用的是第二种方法,下面我们就写一个程序,将读到的温度值显示在 1602 液晶上,并且保留一位小数位。 #include
#include
sbit IO_18B20=P3^2; //DS18B20 通信引脚
void DelayX10us(unsigned char t){
do {
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
} while (--t);
}
bit Get18B20Ack(){
bit ack;
EA=0; //禁止总中断
IO_18B20=0; //产生 500us 复位脉冲
DelayX10us(50);
IO_18B20=1;
DelayX10us(6); //延时 60us
ack=IO_18B20; //读取存在脉冲
while(!IO_18B20); //等待存在脉冲结束
EA=1; //重新使能总中断
return ack;
}
void Write18B20(unsigned char dat){
unsigned char mask;
EA=0; //禁止总中断
for (mask=0x01; mask!=0; mask<<=1){ //低位在先,依次移出 8 个 bit IO_18B20=0; //产生 2us 低电平脉冲 _nop_(); _nop_(); if ((mask&dat)==0){ //输出该 bit 值 IO_18B20=0; }else{ IO_18B20=1; } } DelayX10us(6); //延时 60us IO_18B20=1; //拉高通信引脚 EA=1; //重新使能总中断 } unsigned char Read18B20(){ unsigned char dat; unsigned char mask; EA=0; //禁止总中断 for (mask=0x01; mask!=0; mask<<=1){ //低位在先,依次采集 8 个 bit IO_18B20=0; //产生 2us 低电平脉冲 _nop_(); _nop_(); IO_18B20=1; //结束低电平脉冲,等待 18B20 输出数据 _nop_(); //延时 2us _nop_(); if (!IO_18B20){ //读取通信引脚上的值 dat &=~mask; }else{ dat |=mask; } DelayX10us(6); //再延时 60us } EA=1; //重新使能总中断 return dat; } bit Start18B20(){ bit ack; ack=Get18B20Ack(); //执行总线复位,并获取 18B20 应答 if (ack==0){ //如 18B20 正确应答,则启动一次转换 Write18B20(0xCC); //跳过 ROM 操作 Write18B20(0x44); //启动一次温度转换 } return ~ack; //ack==0 表示操作成功,所以返回值对其取反 } bit Get18B20Temp(int *temp){ bit ack; unsigned char LSB, MSB; //16bit 温度值的低字节和高字节 ack=Get18B20Ack(); //执行总线复位,并获取 18B20 应答 if (ack==0){ //如 18B20 正确应答,则读取温度值 Write18B20(0xCC); //跳过 ROM 操作 Write18B20(0xBE); //发送读命令 LSB=Read18B20(); //读温度值的低字节 MSB=Read18B20(); //读温度值的高字节 *temp=((int)MSB << 8) + LSB; //合成为 16bit 整型数 } return ~ack; //ack==0 表示操作应答,所以返回值为其取反值 } (此处省略,可参考之前章节的代码) #include
bit flag1s=0; //1s 定时标志
unsigned char T0RH=0; //T0 重载值的高字节
unsigned char T0RL=0; //T0 重载值的低字节
void ConfigTimer0(unsigned int ms);
unsigned char IntToString(unsigned char *str, int dat);
extern bit Start18B20();
extern bit Get18B20Temp(int *temp);
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
void main(){
bit res;
int temp; //读取到的当前温度值
int intT, decT; //温度值的整数和小数部分
unsigned char len;
unsigned char str[12];

EA=1; //开总中断
ConfigTimer0(10); //T0 定时 10ms
Start18B20(); //启动 DS18B20
InitLcd1602(); //初始化液晶

while (1){
if (flag1s){ //每秒更新一次温度
flag1s=0;
res=Get18B20Temp(&temp); //读取当前温度
if (res){ //读取成功时,刷新当前温度显示
intT=temp >> 4; //分离出温度值整数部分
decT=temp & 0xF; //分离出温度值小数部分
len=IntToString(str, intT); //整数部分转换为字符串
str[len++]='.'; //添加小数点
decT=(decT*10) / 16; //二进制的小数部分转换为 1 位十进制位
str[len++]=decT + '0'; //十进制小数位再转换为 ASCII 字符
while (len < 6){ //用空格补齐到 6 个字符长度 str[len++]=' '; } str[len]='\0'; //添加字符串结束符 LcdShowStr(0, 0, str); //显示到液晶屏上 }else{ //读取失败时,提示错误信息 LcdShowStr(0, 0, "error!"); } Start18B20(); //重新启动下一次转换 } } } unsigned char IntToString(unsigned char *str, int dat){ signed char i=0; unsigned char len=0; unsigned char buf[6]; if (dat < 0){ //如果为负数,首先取绝对值,并在指针上添加负号 dat=-dat; *str++='-'; len++; } do { //先转换为低位在前的十进制数组 buf[i++]=dat % 10; dat /=10; } while (dat > 0);
len +=i; //i 最后的值就是有效字符的个数
while (i-- > 0){ //将数组值转换为 ASCII 码反向拷贝到接收指针上
*str++=buf[i] + '0';
}
*str='\0'; //添加字符串结束符
return len; //返回字符串长度
}
void ConfigTimer0(unsigned int ms){
unsigned long tmp; //临时变量
tmp= / 12; //定时器计数频率
tmp=(tmp * ms) / 1000; //计算所需的计数值
tmp= - tmp; //计算定时器重载值
tmp=tmp + 12; //补偿中断响应延时造成的误差
T0RH=(unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
T0RL=(unsigned char)tmp;
TMOD &=0xF0; //清零 T0 的控制位
TMOD |=0x01; //配置 T0 为模式 1
TH0=T0RH; //加载 T0 重载值
TL0=T0RL;
ET0=1; //使能 T0 中断
TR0=1; //启动 T0
}
void InterruptTimer0() interrupt 1{
static unsigned char tmr1s=0;
TH0=T0RH; //重新加载重载值
TL0=T0RL;
tmr1s++;
if (tmr1s >=100){ //定时 1s
tmr1s=0;
flag1s=1;
}
}

您可能感兴趣的文章

本文地址:https://www.ceomba.cn/3582.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 ceomba 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!