智能温度传感器序列号读取程序设计研究
作者: 时间:2009-02-16 06:53 来源:
1.引言
传统的温度检测可以使用热敏电阻作为温度敏感元件,热敏电阻主要优点是成本低,但需要后续的信号处理电路。美国Dallas公司近年来推出的DS18B20 智能温度传感器,温度的测量范围为- 55 ~ + 125℃ ,测量精度为0. 5 ℃,与传统的热敏电阻温度传感器不同,它能够直接读出被测点的温度。DS18B20 智能温度传感器在检测点就将被测信号实现了数字化,在单总线上传送的是数字信号。从DS18B20 读出信息或写入DS18B20 的信息仅需要一根总线与单片机I/O口相连,并通过串行输出方式与单片机通信。因此用DS18B20 智能温度传感器组成的多点测温系统,其稳定性、可靠性和工程造价等一系列指标均有明显的优势。为了正确使用智能温度传感器,首先需要读取每一个传感器序列号。
2.智能温度传感器序列号
美国Dallas公司的每片1-Wire器件都有唯一的64位序列号,它存储在只读存储器ROM中。而智能温度传感器DS18B20采用1-Wire 总线。在1-Wire 总线网络中,序列号用于1-Wire 主机对从机器件进行逐一寻址,但对于新购买的芯片,厂家并不给提供其序列号,所以读取序列号是正常使用DS18B20的前提条件。也是对DS18B20进行软件编程的重点之一。DS18B20包含一个64位唯一的序列号并且存储在ROM中。ROM代码的最后8位包含DS18B20一线家族码28H,另外48位包含唯一序列号。最高8位为ROM代码中前56位的CRC检验码。总共64位组成智能温度传感器DS18B20的序列号。其格式如图1所示。
图1 DS18B20的64位ROM代码即序列号示意图
对DS18B20芯片进行序列号读取的方式有两种,搜索ROM(代码为F0H命令)和读ROM(代码为33H命令)方法。两种方法读取序列号的方式各有自己的特点与适用条件,搜索ROM方式可以一次性读取数据线上所有的DS18B20序列号,但它不能分辨出每一个序列号所对应的传感器;而读ROM方式实现起来较搜索ROM方式简单,但它的前提条件是在读取序列号时,数据线上只能挂接一个传感器。
3.搜索ROM方法读取智能温度传感器序列号
3.1 搜索ROM的实现原理与步骤
当系统进入初始化后,主设备并不知道总线上挂了多少个从设备以及它们各自的64位ROM码。搜索ROM命令(代码为F0H)允许主设备使用逐步淘汰的方法识别总线上所有从设备的64位ROM码。搜索ROM的实现原理与步骤以及操作过程见如下说明。
搜索ROM是基于淘汰制的一个3步操作的重复,当单片机启动读时序脉冲后,总线上的所有DS18B20芯片都会响应,并按位输出各自的数据位0或1,若此时总线上同时有1和0,那么,在数据线上会形成“线与”逻辑关系,将使得搜索ROM过程变得复杂化。当DS18B20收到搜索ROM命令即代码为F0H命令后,它将按从低到高的顺序依次按位发出序列号数据,并且将每个数据位分两次发出,第一次为原码,第二次为反码,在此之后,传感器将等待接收一个数据位,并将此接收到的数据位与刚才发送的数据位进行比较,相同则继续下一位的发送,不同则停止对数据线上信号的响应,直到下一次复位。
在DS18B20发送地址数据位的时候,单片机读取各DS18B20发送数据位的“线与”结果。通过对各种可能情况的分析,可以得出表1的结论,其中表1中的“第1次”是指读取DS18B20发送原码的“线与”结果,而“第2次”是指读取DS18B20发送反码的“线与”结果。
单片机在接收到两位数据位后,根据上表的结论返回一个数据位,可以淘汰掉一部分不满足条件的传感器,并且在如此循环64次之后,就可以确定一个传感器序列号。此后重复多次,直至将总线上全部传感器读取完毕。但要注意不能简单重复,否则只能读取同一序列号。
下面以一个具体的例子来详细描述搜索ROM的整个过程[2]。 假设数据线上接了4个传感器,它们的64位ROM数据分别为:传感器1 ……10101100 ;传感器2 ……01010101 ;传感器3 ……10101111 ;传感器4 ……10001000。传感器1、2、3、4给出了假设64位ROM数据的最低字节,搜索过程是从低位开始的,而且搜索各位的原理相同。具体步骤如下:
(1)单片机发送一初始化脉冲,使线上所有传感器初始化。(2)单片机发送搜索ROM命令,代码为F0H。(3)单片机从数据线上读取最低位原码。每个传感器都将输出各自ROM数据的右边第1位到数据线上,传感器1与传感器4输出0,亦即将数据线拉低,而传感器2与传感器3输出1,也就是欲将数据线拉升至高电平,根据“线与”结果,此时单片机从数据线上读取的结果为0。此后,单片机从数据线上读取该位的反码。由于系统仍然处于搜索ROM命令期间,所有的传感器此时都输出各自ROM数据的右边第1位的反码。也就是说,传感器1和传感器4输出1,传感器2和传感器3输出0,结果单片机又收到一个0。至此单片机从数据线上接收到了两个结果,根据表1做出如下判断:数据线上的所有传感器,它们的ROM的最低位既有0又有1。(4)单片机写一个0到数据线上,此时由于传感器2和传感器3与之不匹配而未被选中,亦即暂被淘汰,而最低位为0的传感器1与传感器4被选中。此时记录下ROM右边的第一位为0。(5)单片机针对ROM数据的第2位进行上述两次操作,第1次读为0,第2次读为1,于是判断出数据线上传感器的右起第2个ROM数据为0。(6)单片机写一个0到数据线,结果传感器1与传感器4仍被选中。此时记录下总线上传感器的ROM右起第二位为0。(7)单片机针对ROM数据的右起第3位进行上述两次读操作,2次都为0,表明总线上传感器ROM数据的右起第3位有0也有1。(8)单片机写一个0到数据线上,此时传感器1失配而未被选中,亦即暂被删除,传感器4则被选中。此时记录当前在线传感器右起第3位为0。(9)单片机针对ROM数据的右起第4位进行上述两次读操作,第一次为1,第二次为0,表明总线上传感器的第4位ROM为1。单片机写1到数据线,传感器4继续被选中,记录下右起第4位ROM为1。如此循环读取传感器4余下的数据位,经过这样一遍完整的扫描就能读出传感器4的全部ROM数据。(10)执行一遍新的搜索ROM过程,重复(1)~(7)步的操作。(11)单片机写1到数据线,此时由于传感器4失配而未被选中,亦即被删除,传感器1则被选中。(12)单片机读取传感器1余下的数据位,再通过一遍这样的完整扫描就能够读出传感器1的全部ROM数据。(13)通过类似的步骤,可以读出传感器2和传感器3的ROM数据。
3.2 搜索ROM方法读取序列号的程序设计
用搜索ROM方法读取序列号的程序如下所示。设计中要求序列号与具体传感器相对应,硬件连接时将一个传感器与单片机I/O口相连。因此程序编写时考虑总线上挂接一个传感器时所对应的程序。
DAT EQU P1.1
XL0: MOV R1, #20H ; 读入序列号的存放地址
MOV R0, #08H ; 读取8字节
XL2: MOV R2, #08H ; 读一个字节
XL1: LCALL RE11 ; 读一位的原码
RRC A ; 因数据线上只有1个传感器,所以原码即为ROM值
LCALL RE11 ; 读一位反码
JC LOW1 ; 根据反码状态写原码到数据线
SETB C ; 若反码为0,则写1到数据线
LCALL WIR11
SJMP NEXT
LOW1: CLR C ; 否则写0到数据线
LCALL WIR11
NEXT: DJNZ R2, XL1 ; 继续读下一位,直到读完一个字节
MOV @R1, A ; 将读出的序列号存放到内存单元
INC R1
DJNZ R0, XL2 ; 继续下一字节,直至读满8个字节
RET
其中:RE11为读一位子程序, WIR11为写一位子程序。WIR11和RE11程序中DAT表示I/O口P1.1。写一位子程序WIR11如下所示。
WIR11: SETB DAT
MOV R4 , #5
NOP
CLR DAT
WIR12: DJNZ R4, WIR12 ; 等待10微秒
MOV DAT, C ; 发送1位
MOV R4, #23
WIR13: DJNZ R4, WIR13 ; 保证写时间大于60us
SETB DAT
RET
读一位子程序RE11如下所示。
RE11: SETB DAT
NOP
NOP
CLR DAT
MOV R4, #4
NOP ; 持续低电平2us
SETB DAT ; 释放数据线
RE12: DJNZ R4, RE12 ; 等待8us
MOV C, DAT ; 读入一位
MOV R5, #28
RE13: DJNZ R5, RE13 ; 保证一个读周期持续60us
SETB DAT
RET
4. 读ROM 命令读取智能温度传感器序列号
当总线上挂接一个传感器时,可以用读ROM命令(代码为33H)获得64位序列号。不必用搜索ROM命令读取智能温度传感器64位序列号。用读ROM 命令获取智能温度传感器64位序列号的方法需要首先执行初始化时序,然后单片机发送读ROM命令(代码为33H),再调用一个字节写入程序,随后执行读取64位序列号子程序。
5.两种方法读取序列号的程序设计
下面程序是用两种方法读取序列号。程序中READ为读一个字节程序。INI10为初始化时序子程序。XL0是用搜索ROM方法读取序列号子程序。XL0子程序在上面3.2中已介绍。
MAIN: LCALL INI10 ; 初始化
MOV A, #0F0H ; 发搜索ROM命令(代码为F0H)
LCALL WRITE ; 调用写入一个字节程序
LCALL XL0 ; 搜索ROM方法读64位。见2.1
LCALL INI10 ; 初始化
MOV A, #33H ; 读ROM命令(代码为33H)
LCALL WRITE ; 调用写入一个字节程序
LCALL DXLH ; 读64位序列号
SJMP $
WRITE: MOV R3, #8 ; 循环8次写一个字节
WR11: SETB DAT
MOV R4, #5
RRC A
CLR DAT
WR12: DJNZ R4, WR12 ; 等待10微秒
MOV DAT, C ; 发送1位
MOV R4, #23
WR13: DJNZ R4, WR13 ; 保证写时间大于60us
DJNZ R3, WR11
SETB DAT
RET
DXLH: MOV R1, #30H ; 置内部RAM首地址为30H
MOV R0, #8 ; 读出64位序列号
DXL1: LCALL READ ; 调用读一个字节程序
MOV @R1, A
INC R1
DJNZ R0, DXL1
RET
分别用上述两种方式对同一传感器进行了序列号读取,读取结果如图2所示。其中从单片机AT89C51内部RAM 20H单元开始,连续8个字节存储单元的内容为用搜索ROM命令方法读取序列号的显示结果;从内部RAM 30H开始,连续8个字节存储单元的内容为读ROM命令方法读取序列号的显示结果。显然对于同一传感器,用两种方法读取64位序列号,显示结果是一样的。
图2用两种读取序列号的方式设计显示64位序列号
6.结束语
要想正确使用单总线智能温度传感器DS18B20,必须要能够正确读取序列号,因此读取序列号程序设计是关键。本文作者创新点是应用多种方法设计了序列号读取程序,分析了序列号读取的原理,较好地应用了温度传感器并满足一定精度。文中所叙述的程序设计已经成功地应用于分布式测温系统中。目前越来越多自控设计者愿意使用智能温度传感器DS18B20,其构成的测温系统简单, 连接方便, 占用口线少。 由于系统与单片机的接口简单, 给硬件设计工作带来了极大的方便, 能有效地降低成本。智能温度传感器DS18B20直接以单总线的数字方式传输现场温度,大大提高了系统的抗干扰性,可以使系统的可靠性高并且传输距离远。