1.DS18B20的工作原理
? ① DS18B20数字温度传感器概述
? DS18B20数字温度传感器是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。
DS18B20产品的特点
? 只要求一个端口即可实现通信。
? 在DS18B20中的每个器件上都有独一无二的序列号。 ? 实际应用中不需要外部任何元器件即可实现测温。 ? 测量温度范围在-55.C到+125.C之间。
? 数字温度计的分辨率用户可以从9位到12位选择。 ? 内部有温度上、下限告警设置。
TO-92封装的DS18B20的引脚排列见右图,其引脚功能描述见表 序号 1 2 3 名称 GND DQ VDD 引脚功能描述 地信号 数字输入输出引脚,开漏单总线接口引脚,当使用寄生电源时,可向电源提供电源 可选择的VDD引脚,当工作于寄生电源时,该引脚必须接地 表3-2 DS18B20详细引脚功能描述
② DS18B20的内部结构
DS18B20的内部框图下图所示,DS18B20 的内部有64 位的ROM 单元,和9 字节的暂存器单元。64位ROM存储器件独一无二的序列号。暂存器包含两字节(0和1字节)的温度寄存器,用于存储温度传感器的数字输出。暂存器还提供一字节的上线警报触发(TH)和下线警报触发(TL)寄存器(2和3字节),和一字节的配置寄存器(4字节),使用者可以通过配置寄存器来设置温度转换的精度。暂存器的5、6和7字节器件内部保留使用。第八字节含有循环冗余码(CRC )。使用寄生电源时,DS18B20不需额外的供电电源;当总线为高电平时,功率由单总线上的上拉电阻通过DQ引脚提供;高电平总线信号同时也向内部电容CPP充电,CPP在总线低电平时为器件供电。(字节5~8 就不用看了)。
1
图为 暂存器
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 是符号位,为了就是表示转换的值是正数还是负数。
█要求出正数的十进制值,必须将读取到的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;//又或者
2
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; //高八位
//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,无小数点
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=Temperature0/10; //0 Dot1=; //1
求出负数的思路也一样,只不过多出人为置一负数标志,求反补一的动作而已。自己发挥想象力吧。
B .字节2~3:TH 和TL配置
TH 与TL 就是所谓的温度最高界限,和温度最低界限的配置。其实这些可以使用软件来试验,所以就无视了。
C 字节4:配置寄存器
3
BIT7 出厂的时候就已经设置为0,用户不建议去更改。而R1 与R0 位组合了四个不同的转换精度,00 为9 位转换精度而转换时间是93.75ms,01 为10 位转换精度而转换时间是187.5ms,10 为11 位转换精度而转换时间是375ms,11 为12 位转换精度而转换时间是750ms(默认)。该寄存器还是留默认的好,毕竟转换精度表示了转换的质量。
低五位一直都是\,TM是测试模式位,用于设置DS18B20在工作模式还是在测试模式。在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 无视,无视吧。
③光刻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 存在而已。所以我们无需刻意读取ROM 里边的序列号来,然后匹配那个DS18B20?而是更直接的,跳过ROM 指令,然后直接执行DS18B20 功能指令。
4
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. 功能命令:
主机通过功能命令对DS18B20进行读/写Scratchpad存储器,或者启动温度转换。DS18B20的功能命
令如表3-7所示。
指令 读ROM 符合ROM
协议 功能 33H 读DS18B20中的编码(即64位地址) 发出此命令后,接着发出64位ROM编码,访问单总线上与55H 该编码相对应的DS18B20,使之作出响应,为下一步对该DS18B20的读写作准备 5