找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6210|回复: 2
打印 上一主题 下一主题
收起左侧

DS18B20数字温度传感器应用-带温度显示的LED电子表

[复制链接]
跳转到指定楼层
楼主
ID:105323 发表于 2016-2-24 18:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 51黑黑黑 于 2016-3-3 00:58 编辑

(一)   数字温度传感器DSl8B20介绍
以下为 DS1820 的详细特性
l        独特的单线接口仅需一个端口引脚进行通讯
l        简单的多点分布应用
l        无需外部器件
l        可通过数据线供电
l        零待机功耗
l        测温范围-55~+125℃,以0.5℃递增。华氏器件-67~+2570F,以0.90F 递增
l        温度以 9 位数字量读出
l        温度数字量转换时间 200ms(典型值)
l        用户可定义的非易失性温度报警设置
l        报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件
l        应用包括温度控制、工业系统、消费品、温度计或任何热感测系统

由上表可见DS18B20适用电压为3V~5V,有更宽的电压适用范围,DS18B20可以程序设定9~12 位的分辨率,精度为±0.5°C。可选更小的封装方式。用户设的分辨率和报警温度可以存储在EEPROM 中,掉电后依然保存。DS18B20的性能是新一代产品中最好的。
DS1822与DS18B20 软件兼容,是DS18B20的简化版本。省略了存储用户定义报警温度、分辨率参数的EEPROM,精度降低为±2°C,适用于对性能要求不高,成本控制严格的应用,是经济型产品。
每只D51820都可以设置成两种供电方式即数据总线供电方式和外部供电方式,采取数据总线供电方式可以节省一根导线但完成温度测量的时间较长。采取外部供电方式则多用一根导线但测量速度较快。
每只DSl8B20包括一个唯一的64位长的序号,该序号值存放在DSl8B20内部的ROM(只读存贮器)中。开始8位是产品类型编码,接着的48位是每个器件唯一的序号,最后8位是前面56位的CRC(循环冗余校验)码。因为每一个DSl8B20在出厂时已经给定了唯一的序号,因此在同一条单线总线上可以连接多个DSl8B20。
DSl8B20的存储器由9个字节组成,存储器结构示于下图。存储器有一个暂存SRAM和一个存储高低报警触发值TH和TL的非易失性电可擦除EEPROM组成。注意当报警功能不使用时,TH和TL寄存器可以被当作普通寄存器使用。


DSl8B20的引脚如下图l所示:

(二)DSl8B20工作过程及时序
主机控制DS18B20完成温度转换必须经过三个步骤:初始化、ROM操作指令、存储器操作指令。必须先启动DS18B20开始转换,再读出温度转换值。
1初始化
单总线上的所有处理均从初始化开始。
2ROM操作命令
总线主机检测到DSl8B20的存在便可以发出ROM操作命令。


3存储器操作命令


4时序

1)复位:对DS18B20操作之前,首先要将它复位。复位时序为:
(1)主机将信号线置为低电平,时间为400960μS
(2)主机将信号线置为高电平,时间为1560μS
(3)DS18B20发出60240μS 的低电平作为应答信号。主机收到此信号后,才能对DS18B20作其它操作。

2)写操作:主机将信号线从高电平拉至低电平,产生写起始信号。从信号线的下降沿开始,在1560μS的时间内,DS18B20对信号线检测,如信号线为高电平,则写1,如信号线为O,则写0,从而完成了一个写周期。在开始另一个写周期前,必须有1μ S以上的 高电平恢复期。


3)读操作:主机将信号线从高电平拉低至低电平1μ S以上,再使数据线升为高电平,产生读起始信号。从主机将信号线从高电平拉低至低电平起1560μS的时间内,DS18B20将数据放到信号线上,供主机读取。从而完成了一个读周期。在开始另一个读周期前,必须有1μ S以上的高电平恢复期。


(三)温度与数据关系
DS18B20在出厂时配置为12位温度数据,读取温度时共读取16位,16位数字摆放是从低位到高位,存储在18B20的两个8比特的RAM中,二进制数中的前面5位是符号位,如果测得的温度大于0,这5位为0,此时把温度高字节的低3位与温度低字节的高4位合并成一个字节再转成十进制数是温度的整数部分。温度低字节的低4位乘以0.0625或除以16所测的温度的小数部分。如果温度小于0,这5位为1,测到的数值需要取反加1,然后再把温度高字节的低3位与温度低字节的高4位合并成一个字节再转成十进制数就是温度的整数部分。温度低字节的低4位乘以0.0625或除以16所测的温度的小数部分。

(四)DS18B20中的低温触发器TL、高温触发器TH,用于设置低温、高温的报警数值。DS18B20完成一个周期的温度测量后,将测得的温度值和TL、TH相比较,如果小于TL,或大于TH,则表示温度越限,将该器件内的告警标志位置位,并对主机发出的告警搜索命令作出响应。需要修改上、下限温度值时,只需使用一个功能命令即可对TL、TH写入,十分方便。

(五)具体操作举例:
现在我们要做的是让DS18B20进行一次温度的转换,那具体的操作就是:
1、主机先作个复位操作,
2、主机再写跳过ROM的操作(CCH)命令,
3、然后主机接着写个转换温度的操作命令,后面释放总线至少一秒,让DS18B20完成转换的操作。在这里要注意的是每个命令字节在写的时候都是低字节先写,例如CCH的二进制为11001100,在写到总线上时要从低位开始写,写的顺序是“零、零、壹、壹、零、零、壹、壹”。整个操作的总线状态如下图。

读取RAM内的温度数据。同样,这个操作也要接照三个步骤。
1、主机发出复位操作并接收DS18B20的应答(存在)脉冲。
2、主机发出跳过对ROM操作的命令(CCH)。
3、主机发出读取RAM的命令(BEH),随后主机依次读取DS18B20发出的从第0一第8,共九个字节的数据。如果只想读取温度数据,那在读完第0和第1个数据后就不再理会后面DS18B20发出的数据即可。同样读取数据也是低位在前的。整个操作的总线状态如下图:

(六)单片机程序代码
;采用stc11f04e单片机,晶振3.6864MHZ,通讯速率9600,30H32H存放温度值的高字节,31H,33H存放温度值的低字节
;34H用于保存温度的小数部分;35H用于保存整数部分;36H用于保存温度;38H39H用于保存小数部分,20H.1保存正负温度标志
                      ORG 0000H
                      AJMP MAIN;转入主程序
                      ORG 0003H ;外部中断P3.2INT0入口地址
                      RETI
                      ORG 000BH;中断陷阱
                      ;LJMP CT
                      RETI
                      ORG 0013H;中断陷阱
                      RETI
                      ORG 0023H
                      ;LJMP S
                      TPH DATA30H               ;存放温度值的高字节
                      TPL DATA31H               ;存放温度值的低字节
                      XS EQU 34H;用于保存温度的小数部分
                      ZS EQU 35H;用于保存整数部分
                      P1M0 DATA 92H
                      P1M1 DATA 91H
                      DQ EQU P3.5;DS18B20的数据口位
                      WDT_CONTR   EQU 0C1H
                      AUX     EQU   0A2H           ;P3.0RXD-P3.1TXD TO P1.6RXD-P1.7TXD
                      FLAG_1 EQU    20H.1          ;接收到下行串口发来数据标志p1.6
MAIN:                 MOV SCon,#50h; 方式1,REN=1.SM0SM1SM2REN,TB8RB8TI,RI
                      MOV TMOD,#21H;波特率发生器T1工作在模式2
                      MOV TH1,#0FFH;预置初值(按照波特率9600BPS预置初值) 24M=9600=F3  3.6864=FF=9600 1200=f8
                      MOV TL1,#0FFH;预置初值(按照波特率9600BPS预置初值)  13.56=9600倍频=F9
                      MOV  TH0,#88H     ;8800=12t,7000=stc1t
                   MOV  TL0, #00H
                      ORL IE, #92H  ;EA=1ES=1;ET0=1
                      SETBPS       ;串口中断优先
                      SETBTR1      ;启动定时器1
                      MOVP1M0,#01000000b     ; P1M0=0 P1M1=0双向口   P1M0=1 P1M1=0输入口   P1M0=0 P1M1=1推挽输出20ma
                      MOV P1M1,#10000000b
                      MOV WDT_CONTR ,#27H;;;;;;看门狗设置使能
                      CPL P3.2
QL:                   MOV A,#00H
                    MOV R2,#58   ;清数据区;;
                      MOV R0,#20H
QRAM:                 MOV  @R0,  A
                    INC  R0
                      DJNZ  R2,  QRAM
                     ; MOV WDT_CONTR ,#17H;喂狗
QW:                   CALL DELAY1
                      CALL DELAY1
                      CALL DELAY1
                      CALL DELAY1
                      ;JNB FLAG_1,QQ
                      LCALL DS18B20
                      CALL FZJ
                      CLR FLAG_1
QQ:                   CPL P3.2
                      CALL DELAY1
                      CALL DELAY1
                      CALLDELAY1
                      CALL DELAY1

                      AJMP QL


DS18B20:              ;CLR EA;
                      CALLDS18B20_Reset     ;设备复位
                      MOVA,#0CCH            ;跳过ROM命令
                      CALL DS18B20_WriteByte  ;送出命令
                      MOVA,#044H            ;开始转换 温度转换 44H启动DS18B20进行温度转换
                      CALL DS18B20_WriteByte  ;送出命令
DELAY:               ; MOV WDT_CONTR ,#17H;喂狗
                      JNBDQ,DELAY              ;等待转换完成
                      CALLDS18B20_Reset     ;设备复位
                      MOVA,#0CCH            ;跳过ROM命令
                      CALL DS18B20_WriteByte  ;送出命令
                      MOVA,#0BEH            ;读暂存存储器读暂存器BEH读暂存器9个字节内容
                      CALLDS18B20_WriteByte  ;送出命令
                      CALL DS18B20_ReadByte  ;读温度低字节
                      MOVTPL,A              ;存储数据
                      CALL DS18B20_ReadByte  ;读温度高字节
                      MOVTPH,A              ;存储数据
                      MOV A,TPH;30H
                      RLC A
                      MOV20H.1,c             ;保存正负温度标志
                      JNCZH                  ;最高位是0为零上温度转ZH
                                               ;最高位是1为零下温度取反加1
                      MOVA,TPH;30H          ;例如温度是-54.875度,源码=11001001 001XXXXX 例如温度72.75,30h=48h,31h=40h,加在一起是01001000(=30H)010xxxxx=(31H)
                      CPLA              ;00110110=(30H)
                      MOV32H,A          ;高位取反
                      MOVA,TPL;31H          ;低位取反110XXXXX
                      CPLA              ;110XXXXXX=(31H)
                      MOV33H,A        ;保存高2位到(32h)=01H,最后转换成242H=578d578*0.125=72.75
                      MOVA,#01H      ;10110111=B7
                      ADD A,33H
                      MOV 33H,A
                      CLR A
                      ADDCA,32H      ;例如温度是-54.875=-439*.125,补码649h-649h=1110 0100 1001
                      MOV32H,A      ;结果是32h=0133h=b7,合并成1b7h取反=00110110110,加1=00110110111为正码1b7h=43939*.125=54.875
                      AJMP LS

ZH:                   MOV A,TPH;30H
                      MOV32H,A       ;保存高2位到(32h)=02H,最后转换成242H=578d578*0.125=72.75
                      MOV A,TPL
                      MOV33H,A      ;保存到33h=01000010=42H

LS:                   MOV A,TPL
                      ANL A,#0FH ;存放温度的低字节的低四位决定小数部分
                      MOV XS,A   ;获得小数部分34H

                      MOV A,TPL
                      ANL A,#0F0H
                      SWAP A
                      MOVZS,A    ;35H存放温度的低字节的高四位
                      MOV A,TPH   ;获取存放温度的高字节的低三位
                      ANL A,#07H
                      SWAPA
                      ORLA,ZS    ;存放温度的低字节的高四位合并存放温度的高字节的低三位决定整数部分
                      MOV ZS,A
                      MOV B,#100;分离出百位,存放在R3
                      DIV AB
                      MOV R3,A
                      MOV A,#10 ;余数继续分离十位和个位
                      XCH A,B
                      DIV AB
                      SWAP A
                      ORL A,B ;十位和个位拼装成BCD码
                      MOV 36H,A

                      MOV A,XS
                      MOV R0,#37H
                      MOVR2,#4
D0:                   MOV B,#10
                      MUL AB
                      MOV B,#16
                      DIV AB
                      MOV @R0,A
                      INC R0
                      MOV A,B
                      DJNZ R2,D0

                      MOV R0,#37H
                      MOV A,@R0
                      INC R0
                      SWAP A
                      ORL A,@R0
                      MOV 37H,A
                      INC R0
                      MOV A,@R0
                      INC R0
                      SWAP A
                      ORL A,@R0
                      MOV 38H,A
                      MOV 39H,#0AAH
                      RET       ;20H.1保存正负温度标志
;**************************************
;延时X微秒(STC11f04e@3.6864M)
;不同的工作环境,需要调整此函数
;入口参数:R7
;出口参数:DS18B20在出厂时以配置为12位,读取温度时共读取16位,所以把温度高字节的低3位与温度低字节的高4位合并成一个字节再转成十进制数是温度的整数部分。
;温度低字节的低4位乘以0.0625或除以16所测的温度的小数部分。
;还需要判断正负。前5个数字为符号位,当前5位为1时,读取的温度为负数;当前5位为0时,读取的温度为正数。
;**************************************
DelayXus:               ;6 此延时函数是使用1T的指令周期进行计算,与传统的12TMCU不同
   NOP                    ;1
   DJNZR7,DelayXus       ;4
   RET                    ;4
;DelayXus1: MOVR6,#255                 ;6 此延时函数是使用1T的指令周期进行计算,与传统的12TMCU不同 6.7584=22/3.255
;DelayXus2:   CALL DelayXus
;  DJNZR6,DelayXus2       ;4
;  RET                    ;4

;**************************************
;复位DS18B20,并检测设备是否存在
;入口参数:
;出口参数:
;**************************************
DS18B20_Reset:MOV WDT_CONTR,#37H;喂狗
   CLRDQ                 ;送出低电平复位信号
   MOVR7,#240            ;延时至少480us
   CALL DelayXus
   MOV R7,#240
   CALL DelayXus
   SETBDQ                ;释放数据线
   MOVR7,#60             ;等待60us
   CALL DelayXus
   MOV C,DQ               ;检测存在脉冲
   MOVR7,#240            ;等待设备释放数据线
   CALL DelayXus
   MOV R7,#180
   CALL DelayXus
   JCDS18B20_Reset        ;如果设备不存在,则继续等待
   RET

;**************************************
;DS18B201字节数据
;入口参数:
;出口参数:ACC
;**************************************
DS18B20_ReadByte:
   CLR A
   PUSH 0
   MOV0,#8               ;8位计数器
ReadNext:
   CLRDQ                 ;开始时间片
   MOVR7,#1              ;延时等待
   CALL DelayXus
   SETBDQ                ;准备接收
   MOV R7,#1
   CALL DelayXus
   MOVC,DQ               ;读取数据
   RRC A
   MOVR7,#60             ;等待时间片结束
   CALL DelayXus
   DJNZ 0,ReadNext
   POP 0
   RET

;**************************************
;DS18B201字节数据
;入口参数:ACC
;出口参数:
;**************************************
DS18B20_WriteByte:
   PUSH 0
   MOV0,#8               ;8位计数器
WriteNext:
   CLRDQ                 ;开始时间片
   MOVR7,#1              ;延时等待
   CALL DelayXus
   RRCA                  ;输出数据
   MOV DQ,C
   MOVR7,#60             ;等待时间片结束
   CALL DelayXus
   SETBDQ                ;准备送出下一位数据
   MOV R7,#1
   CALL DelayXus
   DJNZ 0,WriteNext
   POP 0
   RET

FZJ:     MOVR0,#30H       ;向主机发送35h单元开始的8个定时器时钟数据子程序 1B60000000600000
FZJ0:    MOV R2,#0AH
FZJ1:    CLR EA
         ANLAUX,#07FH     ;p3.0p3.1当串口
FZL1:    MOV    A,   @R0
         MOV    SBUF,   A
         JNB    TI,    $
         CLR    TI
         INC    R0
         DJNZ R2,FZL1
         SETB EA
         RET
DELAY2:  MOV   R5, #0FFH
DEL:    MOV WDT_CONTR ,#17H;喂狗
        DJNZ  R5, DEL
        RET
DELAY1: MOV   R6, #0FFH
DELA:   ACALL DELAY2
        DJNZ  R6, DELA
        RET
END

带温度显示的LED电子表



   下面的例子是利用18B20制作一个简单的带温度显示的LED电子表,电路原理图和显示结果如下图所示,晶体振荡器采用7.3128Mhz,如果用其它频率的晶体,需要改变延迟子程序DelayXus,其它程序结构不变,利用单片机的定时器0定时功能构成电子表,每天有9秒的误差,可以通过调整达到每月误差不到1秒,因为本机非常省电,可以长期带电运行,如遇停电,需要重新调整时钟,有2个按键分别调整时和分,调整比较方便,所以就不加时钟模块了,实验证明与鱼缸温度计比较18B20数字温度计还是比较准确的。下面给出了源程序代码,因为注释的比较详细,很容易看的懂。程序主要由初始化模块、定时器模块、温度采集模块组成。内存使用情况是2FH,2EH温度整数位显示区,2DH,2CH是温度小数位显示区,36H,35H是小时显示区,34H,33H分钟显示区,每隔5秒钟左右交替显示时钟和温度。25H单元是10毫秒存储区,够100毫秒30H131H是秒个位存储,32H是秒十位存储。P1.4是米字型数码管控制端,当p1.4=0为低电平(反相后为高)时,p1.6=1,(反相后为低)中间横条显示,P1.6 是米字型数码管共阴极com选通控制端,P1.7数码管小数点选通控制。



;程序源代码如下:
ORG0000H
AJMP L00                   ;电子表程序20151215通过   
ORG  000BH                   ;        
AJMP CT
                                RETI
                                 ORG   001BH
                                RETI
                                ORG 0023H
        TPH DATA28H               ;存放温度值的高字节
        TPL DATA29H               ;存放温度值的低字节
        XS EQU26H                 ;用于保存温度的小数部分
        ZS EQU27H                 ;用于保存整数部分
        XT EQUP3.6                ;MC14513选通
        DQ EQUP3.7                ;DS18B20的数据口位
        FLAG1   EQU     20H.0
                 ORG 0030H;初始化子程序
L00:      MOV SP,#68H  ;设堆栈指针
          MOV SCon,#50h; 方式1,REN=1.SM0SM1SM2REN,TB8RB8TI,RI
          MOV TMOD,#21H;波特率发生器T1工作在模式2
          MOV TH1,#0FFH;预置初值(按照波特率9600BPS预置初值)
          MOV TL1,#0FFH;预置初值(按照波特率9600BPS预置初值)
          MOV  TH0,#0E6H     ;7.3128= 11F4H  ,方式116位定时
            MOV TL0, #3EH
          ORL IE, #92H  ;EA=1ES=1;ET0=1
          SETBPS       ;串口中断优先
QL0:     MOV A,#00H
         MOV R0,#10H
         MOV R2,#60H  ;10-ABH清零
CLEAR:   MOV @R0,A
         INC R0
         DJNZ R2,CLEAR
         MOV 36H,#01H
         MOV 35H,#02H
         MOV 34H,#03H
         MOV 33H,#00H
         CLR FLAG1
;显示子程序和时钟调整子程序
   DIS:SETB   EA                     ;AT89C51中断
       SETB   ET0                    ;允许AT89C51TIME0中断
       SETB   TR0                    ;T0开始计数
       MOVA,31H                      ;31H十秒加1?30h是每秒加1
       XRL A,#09h
       JNZ DIS0
       CALL DS18B20;
DIS0:   JNB P3.5,DIS4                 ;为低再看秒十位单元是否为0
       CLR   TR0                     ;校验表程序,调整分
       MOVA,30H                      ;31H十秒加1?30h是每秒加1
       JNZDIS6                       ;秒位=0,自动小时加1
       JB FLAG1,DIS6
DIS5:  MOV   R0,#35H                 ;校验表程序,调整小时
       SETB FLAG1
       ACALL GIA2
           MOV   R0, #36H
           MOV   A, @R0
           DEC   R0
           SWAP  A
           ADD   A, @R0
           MOV   2DH, A
           CJNE  A, #24H, DIS6
           CLR   A
           MOV   35H, A
           MOV   36H, A
           AJMP  DIS6
DIS4:    JNBP3.1 ,DIS6
       CLR  TR0                     ;校验表程序调整分
       MOVA,30H                     ;31H十秒加1?30h是每秒加1
       JNZDIS6                      ;秒位=0,自动小时加1
       MOV   31H, #00H
       MOV   32H, #00H
DIS7:  MOV   R0, #33H
       JBFLAG1,DIS6                     ;
       SETB  FLAG1
       ACALL GIA2
           MOV   R0, #34H
           MOV   A, @R0
           DEC   R0
           SWAP  A
           ADD   A, @R0
           MOV   2DH, A
           CJNE  A, #60H, DIS6
           CLR   A
           MOV   33H, A
           MOV   34H, A

DIS6:   MOV   R2,#01H       ;R2是位选信号01-04移位 显示子程序显示33h-36h单元数值
       MOV A,31H
       SUBBA,#05H           ;6789秒显示时间,012345秒显示温度
       JC DIS9
          MOV   R1,#33H        ;显示时间的起始地址33h-36h
       AJMP DIS8
DIS9:  MOV   R1,#2CH        ;显示温度的起始地址2ch-2fh
DIS8:  SETB   TR0
DIS1:    MOVA,@R1
       MOVP0,A             ;送数据
       SETB XT  ;控制MC14513LE ,BI,LT1 LE上升沿锁存输出,高电平时不变
       MOVA,R2             ;
       MOV P1,A  ;P0.0-P0.3控制4段数码管共阴极导通,为1反相后为0,数码管导通
       INC R1
       MOV A,R2
       RL A
       MOV R2,A
          MOV   A,R2          ;2位小数点闪动
           JNB   0E3H,DIS3     ;2位小数点闪动E3
       MOV A,30H
       JNZ DIS3
       CPLP1.7             ;每秒小数点闪动一次,(CPLP1.7)
DIS10:  MOV C,20H.7
SETBp1.6    ;SETBP1.6;2003反相后变成低电平,米字型数码管选通        
JC  DIS2
       SETBP1.4            ;十字不亮
       AJMP DIS3
DIS2:   CLRp1.4            ;竖线不亮,其它一秒一闪
DIS3:     LCALLDELAY          ;位扫描
       CLRXT             ;
       JB   0E4H, J6
           AJMP  DIS1
J6:      AJMP  DIS
;定时器中断子程序
CT:      MOV  TH0,#0E8H   ;7.3128= 11F4H  ,方式116位定时E832=10MS   E63E
     MOV  TL0,#08H    ;0FFC慢,1000E810  E7F0 E807  
     PUSH  0D0H
     PUSH  0E0H
     PUSH  82H
     PUSH  83H
     MOV   A,25H          ;
      INC   A
     MOV   25H, A
     CJNE  A, #0AH,DONE    ;0fff=0a,e63e=64
     MOV   25H, #00H
     MOV   A,30H          ;
      INC   A
     MOV   30H, A
     CJNE  A, #0AH,DONE    ;
     MOV   30H, #00H
     MOV   A, 31H;5H
     INC  A                ;秒个位加1
       CLRFLAG1               ;31H十秒加1?30h是每秒加1
     MOV   31H,A   ;5
     CJNE  A, #0AH, DONE
      ; CPLFLAG2     ;31H十秒加1?30h是每秒加1
     MOV   31H, #00H ;5
     MOV   A, 32H;4H
     INC  A                  ;秒十位加1
     MOV   32H,A   ;4
     CJNE  A, #06H,DONE
     MOV   32H, #00H ;4
     MOV   A, 33H
     INC  A             ;分位加1
     MOV   33H, A
     CJNE  A, #0AH,DONE
     MOV   33H, #00H
     MOV   A, 34H;2H
     INC  A               ;分十位加1
      MOV   34H, A ;4
     CJNE  A, #06H,DONE
     MOV   34H, #00H ;4

     MOV   R0,#35H   ;1
     ACALL GIA1
     MOV   R0, #36H
     MOV   A, @R0
     DEC   R0
     SWAP  A
     ADD   A, @R0
     MOV   2DH, A
     CJNE  A, #24H, DONE
     CLR   A
     MOV   35H, A
     MOV   36H, A
       MOVA,30H                ; 1/10秒单元加7,补偿慢9
       ADD A,#07H
       MOV  30H,A
       MOVA,31H                ;秒单元加9,补偿慢9
       ADD A,#09H
       MOV  31H,A
;   AJMP  X
DONE: NOP
     POP   83H
     POP   82H
     POP   0E0H
     POP   0D0H
     RETI
GIA1:   MOV   R1, #04H
GIA2:   MOV   A, @R0
GIA:    INC   A
        MOV   @R0, A
        CJNE  A, #0AH, GIA3
        CLR   A
        MOV   @R0, A
        INC   R0
        DJNZ  R1, GIA2
GIA3:   RET
      ORG 0712H
DELAY:  MOV   R5, #66H;88H
DEL:    NOP
        DJNZ  R5, DEL
        RET

;温度采集子程序
DS18B20:              ;CLR EA;
                      CALLDS18B20_Reset     ;设备复位
                      MOVA,#0CCH            ;跳过ROM命令
                      CALL DS18B20_WriteByte  ;送出命令
                      MOVA,#044H            ;开始转换 温度转换 44H 启动DS18B20进行温度转换
                      CALL DS18B20_WriteByte  ;送出命令
                      JNBDQ,DELAY              ;等待转换完成
                      CALLDS18B20_Reset     ;设备复位
                      MOVA,#0CCH            ;跳过ROM命令
                      CALL DS18B20_WriteByte  ;送出命令
                      MOVA,#0BEH            ;读暂存存储器读暂存器 BEH 读暂存器9个字节内容
                      CALL DS18B20_WriteByte  ;送出命令
                      CALL DS18B20_ReadByte  ;读温度低字节
                      MOVTPL,A              ;存储数据
                      CALL DS18B20_ReadByte  ;读温度高字节
                      MOVTPH,A              ;存储数据
                      MOV A,TPH;30H
                      RLC A
                      MOV20H.7,c             ;保存正负温度标志
                      JNCZH                  ;最高位是0为零上温度转ZH
                                               ;最高位是1为零下温度取反加1
                      MOVA,TPH;28H          ;例如温度是-54.875度,源码=1100 1001 001XXXXX 例如温度72.75,30h=48h,31h=40h,加在一起是01001000(=30H) 010xxxxx=(31H)
                      CPLA              ;00110110=(30H)
                      MOV2AH,A          ;高位取反
                      MOVA,TPL;29H          ;低位取反110XXXXX
                      CPLA              ;110XXXXXX=(31H)
                      MOV2BH,A        ;保存高2位到(32h)=01H ,最后转换成242H=578d578*0.125=72.75
                      MOVA,#01H      ;10110111=B7
                      ADD A,2BH
                      MOV 2BH,A
                      CLR A
                      ADDCA,2AH      ;例如温度是-54.875=-439*.125,补码649h-649h=1 110 0100 1001
                      MOV2AH,A      ;结果是32h=0133h=b7,合并成1b7h 取反=00110110110,加1=00110110111为正码1b7h=43939*.125=54.875
                      AJMP LS

ZH:                   MOV A,TPH;30H
                      MOV2AH,A       ;保存高2位到(32h)=02H ,最后转换成242H=578d578*0.125=72.75
                      MOV A,TPL
                      MOV2BH,A      ;保存到33h=01000010=42H

LS:                   MOV A,2BH;TPL
                      ANL A,#0FH ;存放温度的低字节的低四位决定小数部分
                      MOV XS,A   ;获得小数部分34H

                      MOV A,2BH;TPL
                      ANL A,#0F0H
                      SWAP A
                      MOVZS,A    ;35H存放温度的低字节的高四位
                      MOV A,2AH;TPH   ;获取存放温度的高字节的低三位
                      ANL A,#07H
                      SWAPA
                      ORLA,ZS    ;存放温度的低字节的高四位合并存放温度的高字节的低三位决定整数部分
                      MOV ZS,A
                      MOV B,#100;分离出百位,存放在R3
                      DIV AB
                      MOV R3,A
                      MOVA,#10 ;余数继续分离十位和个位
                      XCH A,B
                      DIV AB
                     ; SWAP A
                     ; ORL A,B ;十位和个位拼装成BCD码
                      MOV 2FH,A
                      MOV A,B
                      MOV 2EH,A
                      MOV A,XS
                      MOV R0,#37H
                      MOV R2,#4
D0:                   MOV B,#10
                      MUL AB
                      MOV B,#16
                      DIV AB
                      MOV @R0,A
                      INC R0
                      MOV A,B
                      DJNZ R2,D0
                      MOV 2DH,37H
                      MOV 2CH,38H
                      RET       ;20H.7保存正负温度标志
DelayXus:             NOP                    ;6微秒
                      DJNZR7,DelayXus       ;
                      RET                    ;
;**************************************
;复位DS18B20,并检测设备是否存在
;入口参数:
;出口参数:
;**************************************
DS18B20_Reset:;MOV WDT_CONTR ,#37H;喂狗
                  CLRDQ                 ;送出低电平复位信号
                  MOVR7,#40;240            ;延时至少480us
                  CALL DelayXus
                  MOV R7,#40;240
                  CALL DelayXus
                  SETB DQ                ;释放数据线
                  MOVR7,#10;60             ;等待60us
                  CALL DelayXus
                  MOVC,DQ               ;检测存在脉冲
                  MOVR7,#40;240            ;等待设备释放数据线
                  CALL DelayXus
                  MOVR7,#30;180
                  CALL DelayXus
                  JCDS18B20_Reset        ;如果设备不存在,则继续等待
                  RET

;**************************************
;DS18B201字节数据
;入口参数:
;出口参数:ACC
;**************************************
DS18B20_ReadByte:
                CLR A
                PUSH 0
                MOV0,#8               ;8位计数器
ReadNext:
               CLRDQ                 ;开始时间片
               MOVR7,#1              ;延时等待
               NOP;CALL DelayXus
               SETBDQ                ;准备接收
               MOV R7,#1
              NOP; CALL DelayXus
               MOVC,DQ               ;读取数据
               RRC A
               MOVR7,#10;60             ;等待时间片结束
               CALL DelayXus
               DJNZ0,ReadNext
               POP 0
               RET

;**************************************
;DS18B201字节数据
;入口参数:ACC
;出口参数:
;**************************************
DS18B20_WriteByte:
                 PUSH 0
                 MOV 0,#8               ;8位计数器
WriteNext:
               CLRDQ                 ;开始时间片
               MOVR7,#1              ;延时等待
               NOP;CALL DelayXus
               RRCA                  ;输出数据
               MOV DQ,C
               MOVR7,#10;60             ;等待时间片结束
               CALL DelayXus
               SETBDQ                ;准备送出下一位数据
               MOV R7,#1
              NOP; CALL DelayXus
               DJNZ 0,WriteNext
               POP 0
               RET


END
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:108998 发表于 2016-3-15 14:08 | 只看该作者
谢谢楼主分享  学习学习
回复

使用道具 举报

板凳
ID:497598 发表于 2019-6-23 19:08 | 只看该作者
有没有c语言的啊😂
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表