DS18B20的工作原理及应用 下载本文

0F0H 用于确定挂接在同一总线上DS18B20的个数和识别64位ROM地址,为操作各器件作好准备 跳过ROM 0CCH 忽略64位ROM地址,直接向DS18B20V 温度转换命令,适用于单个DS18B20工作 报警搜索命0ECH 执行后,只有温度超过庙宇值上限或下限的片子才做出响令 应 温度转换 44H 启动DS18B20进行温度转换,转换时间最长为500ms(典型为200ms),结果丰入内部9字节RAM中 读暂存器 BEH 读内部RAM中9字节的内容 写暂存器 4EH 发出向内部RAM的第3、4字节写上、下温度数据命令,紧该温度命令之后,传达两字节的数据 复制暂存器 48H 将RAM中第3、4字内容复制到E2PROM中 重调E2PROM 0B8H 将E2PROM中内容恢复到RAM中的第3、4字节 读供电方式 0B4H 读DS18B20的供电模式,寄生供电时DS18B20发送“0”,外部供电时DS18B20发送“1” 表3-7 (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的指令。在每一个时序,总线只能传输一位数据。读/写时序如图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。

6

搜索ROM ? 写时序

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 微妙 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 为输出

7

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,且在两次独立的读时序之间至少需

要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允许通过程序对传感器的分辨率,温度报警的上、下限等参数进行配置。它的内部存储器包括一个高速暂存存储器和一个非易失性可擦除E2PROM。速暂存存储器共有8个字节(byte),每个字节

8位(bit)。

根据温度的计算方法如下: S S S S S = 11111 b 温度值:

8

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 读暂存数据: 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;

9

//延时

void delay(word useconds) {

for(;useconds>0;useconds--); }

//复位

byte ow_reset(void) {

byte presence;

DQ = 0; //pull DQ line low时序中 delay(29); // leave it low for 480us

DQ = 1; // allow line to return high delay(3); // wait for presence presence = DQ; // get presence signal delay(25); // wait for end of timeslot

return(presence); // presence signal returned

} // 0=presence, 1 = no part

//从 1-wire 总线上读取一个字节 byte read_byte(void) {

byte i;

byte value = 0; for (i=8;i>0;i--) {

value>>=1;

DQ = 0; // pull DQ low to start timeslot DQ = 1; // then return high delay(1); //for (i=0; i<3; i++); if(DQ)value|=0x80;

delay(6); // wait for rest of timeslot }

return(value); }

//向 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;

10