实验六:温度传感DS18B20实验(数码管显示)
一、实验目的:
1)
以AT89S52X单片机为核心器件,组成一个数字式温度计。
2)
了解DS18B20的工作原理及使用方法。
3)
掌握DS18B20读写时序的编程方法。
4)
锻炼单片机综合应用和开发的能力
二、
实验内容与要求:
1
)显示当前温度:在数码管显示模块上前四个数码管显示当前温度(整数小数各两位)。
2
)编程要求:用汇编语言编写此程序,写出各个子程序的功能并在主要的指令后加上必要地文字说明增加程序的可读性。
三、实验原理
:
(1)硬件电路原理图:
如图-1所示,
图-1中
温度测量使用P1.3端口,使用DS18B20器件,显示使用4位数码管。
(2)工作原理:本实验通过DS18B20采集环境温度,当单片机
检测到
DSl820
的存在便可以发出
ROM
操作命令之一,
Read ROM(
读
ROM) Match ROM(
匹配
ROM) Skip ROM(
跳过
ROM) Search ROM(
搜索
ROM) Alarm search(
告警搜索
)
然后对发存储器操作命令对
DS18B20
进行读写数据转换等操作。
单片机
使用时间隙
(time slots)
来读写
DSl820
的数据位和写命令字的位,然后将读到的数据转换
BCD
码在数码管显示出来(
DS18B20
的详细资料详见附录)。
四.软件流程设计:
该系统采用的方法,根据初始化温度传感器,再就是显示温度数值。测量出来温度软件
系统基本流
程如图所示:
五.参考程序:
/*------------------------------
内存分配声明
--------------------------*/
TEMPER_L EQU 31H ;
用于保存读出温度的低字节
TEMPER_H EQU 30H ;
用于保存读出温度的高字节
T_DF EQU 33H ;FORMAT
后的小数部分
(decimal fraction)
,半字节的温度小数
(
存在低四位
)
T_INTEGER EQU 32H ;FORMAT
后的整数部分
(integer),
将两字节的温度整合成
1
字节
FLAG BIT 20H ;
标志位
DAT BIT P1.3 ;DS18B20
数据线
/*------------------------------
主函数开始
-----------------------------*/
ORG 0000H ;
函数入口地址
AJMP MAIN ;
跳转指令
ORG 0030H
MAIN
:
CLR EA ;
使用
DS18B20
一定要禁止中断
MOV SP,#60H
MOV T_DF,#00H ;
赋初始温度为
30
度
MOV T_INTEGER,#30H
START: LCALL GET_TEMPER ;
调用读温度子程序
LCALL T_FORMAT ;
将读出的
2
字节温度格式化
,
并转换为压缩
BCD
码
LCALL DISPLAY ;
显示温度
AJMP START
/*-----------------------DS18B20
的温度转换子程序
-----------------------*/
GET_TEMPER:
LCALL Set_18B20 ;
调用
DS18B20
初始化程序
MOV A,#0CCH ;
跳过
ROM
匹配
LCALL WRITE_1820 ;
调用写
DS18B20
的子程序
MOV A,#44H ;
发出温度转换命令
LCALL WRITE_1820
LCALL DISPLAY ;
用显示温度
(
持续
1s
左右
)
来等待
AD
转换结束
,12
位的话要转换
750ms
LCALL Set_18B20 ;
准备读温度前先初始化
MOV A,#0CCH ;
跳过
ROM
匹配
LCALL WRITE_1820
MOV A,#0BEH ;
发出读温度命令
LCALL WRITE_1820
LCALL READ_1820 ;
读
DS18B20
的程序
RET
/*--------------------------DS18B20
初始化程序
--------------------------*/
Set_18B20:
SETB DAT ;
置位
NOP ;
空操作
CLR DAT ;
清零
MOV R2,#250 ;
主机发出延时
500
微秒的复位低脉冲
DJNZ R2,$ ;
自减(
-1
)循环
SETB DAT ;
然后拉高数据线
MOV R2,#30
DJNZ R2,$ ;
延时
60us
等待
DS18B20
回应
JNB DAT,INIT1
JMP Set_18B20 ;
超时而没有响应
,
重新初始化
INIT1: MOV R2,#120
DJNZ R2,$ ;
延时
240us
JB DAT,INIT2 ;
数据变高,初始化成功
JMP Set_18B20
INIT2: MOV R2,#240
DJNZ R2,$
RET
/*-----------------
写
DS18B20
的子程序
(
有具体的时序要求
)-----------------*/
WRITE_1820:
MOV R2,#8 ;
共
8
位数据
WR0: CLR DAT
MOV R3,#6
DJNZ R3,$
RRC A
MOV DAT,C
MOV R3,#20
DJNZ R3,$
SETB DAT
NOP
NOP
DJNZ R2,WR0
SETB DAT
RET
/*------
读
DS18B20
的程序
,
从
DS18B20
中读出两个字节的温度数据
----------------*/
READ_1820:
MOV R4,#2 ;
将温度高位和低位从
DS18B20
中读出
MOV R1,#TEMPER_L ;
低位存入
31H(TEMPER_L)
RE0: MOV R2,#8
RE1: SETB DAT
NOP
NOP
CLR DAT
NOP
NOP
SETB DAT
MOV R3,#4
DJNZ R3,$
MOV C,DAT
RRC A
MOV R3,#30
DJNZ R3,$
DJNZ R2,RE1
MOV @R1,A
DEC R1 ;
高位存入
30H(TEMPER_H)
DJNZ R4,RE0
RET
/*------
整合读出的两字节温度
(
关于
DS18B20
读出的
2
字节温度格式请参考资料
)-----*/
T_FORMAT:
MOV A,#0FH
ANL A,TEMPER_L
MOV T_DF,A ;
获得小数部分
(4
位
)
MOV A,TEMPER_L
SWAP A
MOV @R0,A
MOV A,TEMPER_H
SWAP A
XCHD A,@R0
MOV T_INTEGER,A ;
获得整数部分
(1
字节
)
TO_BCD: MOV A,T_INTEGER
MOV B,#10
DIV AB
SWAP A
ADD A,B
MOV T_INTEGER,A ;
整数部分压缩
BCD
码送
T_INTEGER
MOV A,T_DF
MOV B,#10
MUL AB
MOV B,#16
DIV AB
MOV R2,A ;
暂存
R2
MOV A, B
MOV B,#10
MUL AB
MOV B,#16
DIV AB
MOV B,A
MOV A,R2
SWAP A
ADD A,B
MOV T_DF,A ;
小数部分压缩
BCD
码送
T_DF
RET
/*---------------------------
显示温度子程序
----------------------------*/
DISPLAY:MOV R1,#250
DISP1: MOV A,T_INTEGER
MOV R3,#0FEH
MOV R4,#0FDH
SETB FLAG
DISP2: CPL FLAG
MOV B,#10H
DIV AB
MOV R2,A ;
高位送
R2
暂存
MOV DPTR,#2000H ;
字位口
MOV A,R3
MOVX @DPTR,A ;
送字位
MOV A,R2 ;
字型
R2
送
A
MOV DPTR,#TAB ;
表首地址送
DPTR
MOVC A,@A+DPTR ;
查表
MOV DPTR,#6000H ;
字型口
MOVX @DPTR,A ;
送字型
CALL D1MS ;
延时
MOV A,#0FFH
MOVX @DPTR,A ;
关闭字型显示
MOV R2,B ;
低位送
R2
暂存
MOV DPTR,#2000H ;
字位口
MOV A,R4
MOVX @DPTR,A ;
送字位
MOV A,R2 ;
字型
R2
送
A
MOV DPTR,#TAB ;
表首地址送
DPTR
MOVC A,@A+DPTR ;
查表
JNB FLAG,D1 ;FLAG
为零,跳到
D1
JMP D2 ;
否则
,
跳到
D2
D1: ANL A,#7FH ;
相与
D2: MOV DPTR,#6000H ;
字型口
MOVX @DPTR,A ;
送字型
CALL D1MS ;
延时
MOV A,#0FFH
MOVX @DPTR,A ;
关闭字型显示
MOV A,T_DF
MOV R3,#0FBH
MOV R4,# 0F 7H
JNB FLAG,DISP2
DJNZ R1,DISP1
RET
/*-------------------------1mS
延时
(
按
12MHZ
算
)--------------------------*/
D1MS: MOV R7,#250
LOOP0: NOP
NOP
DJNZ R7,LOOP0
RET
/*-------------------------
共阳数码管对应字型表
-------------------------*/
TAB: DB 0C 0H, 0F 9H, 0A 4H,0B0H,99H,92H,82H, 0F 8H ;
段码表
; 0 1 2 3 4 5 6 7
对应内容
DB 80H,90H,88H,83H, 0C 6H, 0A 1H,86H,8EH
; 8 9 A B C D E F
END
六.实验步骤:
1.
读DS18B20的数据手册,弄明白其时序及编程思路。
2.
看实验开发板的连线手册,分析计算出显示模块数码管的物理地址。
3.
画出程序流程图编写相应的程序。
4.
将程序下载到开发板上并调试程序,使程序达到预定功能。
七、实验报告
:
1
.写出项目方案,包括硬件设计方案和软件设计方案。
2
.给出电路原理图和程序流程图的设计。
3
.提供程序清单,并加以注释。
4
.在调试过程中发现了哪些问题?你是怎么解决的?
5
.总结项目开发的经验
八.思考题:
本实验实现了单点的温度采集,你能否在本实验的基础上设计实验实现多点温度采集的系统。
附录
数字温度传感器
DS1820(DS18B20)
的应用
一 单线数字温度计
DSl820
介绍
DSl820
数字温度计提供
9
位
(
二进制
)
温度读数指示器件的温度信息经过单线接口送入
DSl820
或从
DSl820
送出因此从主机
CPU
到
DSl820
仅需一条线
(
和地线
)DSl820
的电源可以由数据线本身提供而不需要外部电源因为每一个
DSl820
在出厂时已经给定了唯一的序号因此任意多个
DSl820
可以存放在同一条单线总线上这允许在许多不同的地方放置温度敏感器件
DSl820
的测量范围从
-55
到
+125
增量值为
0.5
可在
l s(
典型值
)
内把温度变换成数字每一个
DSl820
包括一个唯一的
64
位长的序号该序号值存放在
DSl820
内部的
ROM(
只读存贮器
)
中开始
8
位是产品类型编码
(DSl820
编码均为
10H)
接着的
48
位是每个器件唯一的序号最后
8
位是前面
56
位的
CRC(
循环冗余校验
)
码
DSl820
中还有用于贮存测得的温度值的两个
8
位存贮器
RAM
编号为
0
号和
1
号
1
号存贮器存放温度值的符号如果温度为负
()
则
1
号存贮器
8
位全为
1
否则全为
00
号存贮器用于存放温度值的补码
LSB(
最低位
)
的
1
表示
0.5
将存贮器中的二进制数求补再转换成十进制数并除以
2
就得到被测温度值
(-550125)
DSl820
的引脚如图
226l
所示每只
D51820
都可以设置成两种供电方式即数据总线供电方式和外部供电方式采取数据总线供电方式可以节省一根导线但完成温度测量的时间较长采取外部供电方式则多用一根导线但测量速度较快温度计算
1
Ds1820
用
9
位存贮温值度最高位为符号位下图为
18b20
的温度存储方式负温度
S=1
正温度
S=0
如
00AAH
为
+85 ,0032H
为
25 ,FF92H
为
55
2. Ds18b20
用
12
位存贮温值度最高位为符号位下图为
18b20
的温度存储方式负温度
S=1
正温度
S=0
如
0550H
为
+85 ,0191H
为
25.0625 ,FC90H
为
-55
二
. DSl820
工作过程及时序
DSl820
工作过程中的协议如下
初始化
RoM
操作命令存储器操作命令处理数据
1
初始化
单总线上的所有处理均从初始化开始
2ROM
操作品令
总线主机检测到
DSl820
的存在便可以发出
ROM
操作命令之一这些命令如
指令 代码
Read ROM(
读
ROM) [33H]
Match ROM(
匹配
ROM) [55H]
Skip ROM(
跳过
ROM] [CCH]
Search ROM(
搜索
ROM) [F0H]
Alarm search(
告警搜索
) [ECH]
3
存储器操作命令
指令 代码
Write Scratchpad(
写暂存存储器
) [4EH]
Read Scratchpad(
读暂存存储器
) [BEH]
Copy Scratchpad(
复制暂存存储器
) [48H]
Convert Temperature(
温度变换
) [44H]
Recall EPROM(
重新调出
) [B8H]
Read Power supply(
读电源
) [B4H]
4
时 序
主机使用时间隙
(time slots)
来读写
DSl820
的数据位和写命令字的位
(1)
初始化
时序见图
2.25-2
主机总线
to
时刻发送一复位脉冲
(
最短为
480us
的低电平信号
)
接着在
tl
时刻释放总线并进入接收状态
DSl820
在检测到总线的上升沿之后等待
15-60us
接着
DS1820
在
t2
时刻发出存在脉冲
(
低电平持续
60-240 us)
如图中虚线所示
以下子程序在
MCS51
仿真机上通过其晶振为
12M.
初始化子程序
RESET
PUSH B ;
保存
B
寄存器
PUSH A
保存
A
寄存器
MOV A,#4 ;
设置循环次数
CLR P1.0 ;
发出复位脉冲
MOV B,#250 ;
计数
250
次
DJNZ B,$ ;
保持低电平
500us
SETB Pl.0 ;
释放总线
MOV B,#6 ;
设置时间常数
CLR C ;
清存在信号标志
WAITL: JB Pl.0,WH ;
若总线释放跳出循环
DJNZ B,WAITL ;
总线低等待
DJNZ ACC,WAITL;
释放总线等待一段时间
SJMP SHORT
WH: MOV B,#111
WH1: ORL C,P1.0
DJNZ B,WH1 ;
存在时间等待
SHORT: POP A
POP B
RET
(2)
写时间隙
当主机总线
t o
时刻从高拉至低电平时就产生写时间隙见图
2253
图
2254
从
to
时刻开始
15us
之内应将所需写的位送到总线上
DSl820
在
t
后
15-60us
间对总线采样若低电平写入的位是
0
见图
2253
若高电平写入的位是
1
见图
2254
连续写
2
位间的间隙应大于
1us
写位子程序
(
待写位的内容在
C
中
)
WRBIT:
PUSH B ;
保存
B
MOV B,#28 ;
设置时间常数
CLR P1.0 ;
写开始
NOP ;1us
NOP ;1us
NOP ;1us
NOP ;1us
N0P ;1us
MOVPl.0,C ;C
内容到总线
WDLT: DJNZ B,WDLT;
等待
56Us
POP B
SETB Pl.0 ;
释放总线
RET ;
返回
写字节子程序
(
待写内容在
A
中
):
WRBYTB:
PUSH B :
保存
B
MOV B#8H ;
设置写位个数
WLOP: RRC A ;
把写的位放到
C
ACALL WRBIT ;
调写
1
位子程序
DJNZ BWLOP ;8
位全写完
?
POP B
RET
(3)
读时间隙
见图
2255
主机总线
to
时刻从高拉至低电平时总线只须保持低电平
l 7ts
之后在
t1
时刻将总线拉高产生读时间隙读时间隙在
t1
时刻后
t 2
时刻前有效
t z
距
to
为
15
捍
s
也就是说
t z
时刻前主机必须完成读位并在
t o
后的
60
尸
s
一
120 fzs
内释放总线
读位子程序
(
读得的位到
C
中
)
RDBIT:
PUSH B ;
保存
B
PUSH A ;
保存
A
MOV B,#23 ;
设置时间常数
CLR P1.0 ;
读开始图
2255
的
t0
时刻
NOP ;1us
NOP ;1us
NOP ;1us
NOP ;1us
SETB Pl.0 ;
释放总线
MOV A,P1 ;P1
口读到
A
MOV C,EOH ;P1.0
内容
C
NOP ;1us
NOP ;1us
NOP ;1us
NOP ;1us
RDDLT: DJNZ B,RDDLT ;
等待
46us
SETB P1.0
POP A
POP B
RET
读字节子程序
(
读到内容放到
A
中
)
RDBYTE:
PUSH B ;
保存
B
RLOP MOV B,#8H ;
设置读位数
ACALL RDBIT ;
调读
1
位子程序
RRC A ;
把读到位在
C
中并依次送给
A
DJNZ B,RLOP ;8
位读完
?
POP B ;
恢复
B
RET