1、实验目的:
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