基于DS18B20数字温度传感器的温度计设计
本报告为哈尔滨工业大学电子与信息工程学院大二学期微机原理课程的课设报告。请注意,本文所述代码均在Quartus II 13.0程序内使用汇编语言运行。
一、课程设计任务要求
利用数字温度传感器DS18B20与AT89C51单片机结合来测量温度,并在LED数码管上显示相应的温度值。温度测量范围为-55~125℃,精确至0.5℃。测量的温度采用数字显示,用三位共阳极LED数码管来实现温度显示。
二、工作原理
DS18B20数字温度传感器是美国DALLAS半导体公司推出的一种改进型具有单总线接口的智能温度传感器。与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字读数方式。DS18B20的基本性能及详细资料请参考相关资料。
三、单片机应用系统设计及原理图
DS18B20数字温度传感器数据端口DQ接于P1.7,单片机接电源和晶振,八位共阳数码管位选接于P1.2~P1.6,断码接于P0.0~P0.7并连接排阻。
四、实现方法及扩展创新
-
基本功能实现方法
利用 DS18B20 数字温度传感器的数据传输机制编写程序,将温度数值从温度传感器中取回到 AT89C51 之中,再根据数据的转换形式,在单片机中对数据进行处理变换成十进制,并动态显示在数码管中。 -
扩展创新设计
根据实验要求:精度在 0.5℃范围内,则不必四舍五入,取出整数部分直接处理,只需考查数据的小数第一位,来决定小数点显示位置显示 0 或者 5,便可保证精度;并且在个位位置附加上小数点;最后补充符号位,负温度时显示负号。
五、实现步骤
首先需要了解 DS18B20 的数据传输方式,因为这一芯片只有一个数据通信口,需要遵守严格的时序,脉冲的规则,介绍如下。
首先设定 DQ 为总线数据位,连接于 P1.7。
DQ BIT P1.7
1.复位功能
主机首先发出一个 480~960us 的低电平脉冲,然后释放总线变为高电平,并在随后的480us 时间内对总线进行检测,如果有低电平出现说明总线上有器件已做出应答。若无低电平出现一直都是高电平说明总线上无器件应答。
作为从器件的 DS18B20 在一上电后就一直在检测总线上是否有 480-960 us 的低电平出现,如果有,在总线转为高电平后等待 15-60us 后将总线电平拉低60~240us 做出响应存在脉冲,告诉主机本器件已做好准备。若没有检测到就一直在检测等待。
这一段程序设计加入 FLAG 位变量作为传感器是否相应,正常工作的标志:
FLAG BIT F0
INIT_1: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 FLAG
MOV R0,#06BH
TSR4: DJNZ R0,TSR4
SETB DQ
RET
2.写入操作
写周期最少为 60us,最长不超过 120us。写周期一开始做为主机先把总线拉低1us 表示写周期开始。随后若主机想写 0,则继续拉低电平最少 60us 直至写周期结束,然后释放总线为高电平。若主机想写 1,在一开始拉低总线电平 1us 后就释放总线为高电平,一直到写周期结束。而做为从机的 DS18B20 则在检测到总线被拉底后等待 15 us 然后从 15us 到 45us 开始对总线采样,在采样期内总线为高电平则为1,若采样期内总线为低电平则为 0。
写入要遵守规则,需要先复位,跳过 ROM,才能进行读写,更改初值等操作。
WRITE: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
3.读数操作
对于读数据操作时序也分为读 0 时序和读 1 时序两个过程。读时隙是从主机把单总线拉低之后,在 1us 之后就得释放单总线为高电平,以让 DS18B20 把数据传输到单总线上。DS18B20 在检测到总线被拉低 1us 后,便开始送出数据,若是要送出0 就把总线拉为低电平直到读周期结束。若要送出 1 则释放总线为高电平。主机在一开始拉低总线 1us 后释放总线,然后在包括前面的拉低总线电平 1us在内的 15us 时间内完成对总线进行采样检测,采样期内总线为低电平则确认为0。采样期内总线为高电平则确认为 1。完成一个读时序过程,至少需要 60us 才能完成。
读数代码如下,在读数的时候要同样要复位,跳 ROM,写入操作码再读写。
READ: MOV R4,#2
MOV R1,#29H
REE0: MOV R2,#8
REE1: CLR C
SETB C
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,REE1
MOV @R1,A
DEC R1
DJNZ R4,REE0
RET
4.设定温度分辨率
由于温度传感器的温度精度为 0.0625℃,对于要求的精度太高,可以适当减少精度,使小数点后四位仅余一位有效,在符合条件的情况下理想化后三位。
FBLCHANGE:
LCALL INIT_1
MOV A,#0CCH
LCALL WRITE
MOV A,#1FH
LCALL WRITE
RET
5.主程序编写
主程序应完全按照通信规则进行。
DS18B20 单线通信功能是分时完成的,他有严格的时隙概念,如果出现序列混乱,1-WIRE 器件将不响应主机,因此读写时序很重要。系统对 DS18B20 的各种操作必须按协议进行。根据 DS18B20 的协议规定,微控制器控制 DS18B20 完成温度的转换必须经过以下三个步骤 :
- 每次读写前对 DS18B20 进行复位初始化;
- 发送一条 ROM 指令;
- 发送存储器指令。
现在我们做的是让DS18B20进行一次温度转换,那具体操作如下:
- 主机先作复位操作;
- 主机再写跳过ROM的操作(CCH)命令;
- 然后主机接着写个转换温度的操作命令,后面释放总线至少 1s,让DS18B20 完成转换的操作。在这里要注意的是每个命令字节在写的时候都是低字节先写,例如 CCH 的二进制为 11001100,在写到总线上时要从低位开始写,写的顺序是“1、1、0、0、1、1、0、0”。
读取 RAM 内的温度数据同样也要接照三个步骤:
- 主机发出复位操作并接收 DS18B20 的应答(存在)脉冲。
- 主机发出跳过对 ROM 操作的命令(CCH)。
- 主机发出读取 RAM 的命令(BEH),随后主机依次读取 DS18B20 发出的从第0 到第 8,共九个字节的数据。如果只想读取温度数据,那在读完第 0 和第 1 个数据后就不再理会后面 DS18B20 发出的数据即可。同样读取数据也是低位在前的。
故主函数设置如下:
MAIN: LCALL INIT_1
LCALL FBLCHANGE
LCALL GET_TEMP
AJMP CHANGE
GET_TEMP:
SETB DQ
LCALL INIT_1
JB FLAG,TSS2
RET
TSS2: MOV A,#0CCH
LCALL WRITE
MOV A,#44H
LCALL WRITE
LCALL DISPLAY
LCALL INIT_1
MOV A,#0CCH
LCALL WRITE
MOV A,#0BEH
LCALL WRITE
LCALL READ
RET
6.数据处理与显示
对于传回的数据,DS18B20 的数据格式如下:
温度 | 二进制表示 | 十六进制表示 |
---|---|---|
+125 | 00000111 11010000 | 07D0H |
+25.0625 | 00000001 10010001 | 0191H |
+10.125 | 00000000 10100010 | 00A2H |
+0.5 | 00000000 00001000 | 0008H |
0 | 00000000 00000000 | 0000H |
-0.5 | 11111111 11111000 | FFF8H |
-10.125 | 11111111 01011110 | FF5EH |
-25.0625 | 11111110 01101111 | FE6FH |
-55 | 11111100 10010000 | FC90H |
故我们可以由如下步骤分析:
- 判断温度的正负。首先可知,取回原始数据的最后四位无效,这就保证了数据在取回绝对值时不会溢出。此时检查数据的最高位,如果是正数,则正常执行;如果是负数,则进行取反加一的操作,得到绝对值,并保留原数,为判断是否显示负号做准备。
- 取出绝对值放入地址中作为二进制整数。利用进位标志位 C,将八高位的后四位传入低八位的前四位,得到绝对值。
- 判断小数后第一位是 0 还是 1,得到小数位显示为 0 或 5。这时需要在新地址存储00H,05H,为显示做准备。 此时我们可以发现对于绝对值小数位为.0~.4 的,则显示的十分位置 0,绝对值小数位为.5~.9 的,则显示的十分位置 5,且不影响去掉小数位的整数值,整数值依旧存在。由此可知,显示数字和真实数字的关系并不符合四舍五入,但在精度范围之内,这样做减少了数据处理的复杂度,增加了数码管显示数量,是本实验的创新之处。
- 整数部分转为十进制。DIV 指令提供了方便,我们只需执行两次除以10 的操作,便可以得到个,十,百位。
- 显示:显示采用共阳八位数码管。首先由数据的正负,判断是否输出负号(g 亮,即 BFH),否则输出全灭状态(即 FFH)。再依次输出个十百位,注意个位为表达准确,需要加上小数点,故要对正常的数码表最高位置零(即最高位减 8),故个位要查最高位置零后的表以显示小数点。再根据小数位提前存储的00H,05H,判断小数第一位的状态,输出相应的 0 和 5。延时函数不必多说。
实际代码如下:
CHANGE:
MOV A,29H
MOV 26H,29H
MOV 25H,28H
MOV 24H,28H
MOV C,25H.7
JNC SN1
MOV A,25H
CPL A
MOV 25H,A
MOV A,26H
CPL A
INC A
MOV 26H,A
MOV 29H,26H
MOV 28H,25H
SN1: MOV C,28H.0
RRC A
MOV C,28<