实验六:温度传感DS18B20实验(数码管显示)

实验六:温度传感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
 

你可能感兴趣的:(职场,休闲,实验,ds18b20,温度传感)