文章搜索

DS18B20的读写程序

发表时间:2015-4-30  作者:admin  浏览次数:1486  
字体大小: 【小】 【中】 【大】

;******************************************************************************
;*  描述:                                                                                                                                                         
;*        DS18B20的读写程序,数据脚P2.2                                       *
;         温度传感器18B20汇编程序,采用器件默认的12位转化                     *
;         最大转化时间750微秒,显示温度-55到+125度,显示精度                   *
;         为0.1度,显示采用4位LED共阳显示测温值                              *                                                         
;*                                                                                                                                                                   
;******************************************************************************                                 
;*************************************************
;单片机内存分配申明!
;*************************************************
TEMPER_L  EQU   40H     ;用于保存读出温度的低8位
TEMPER_H  EQU   41H     ;用于保存读出温度的高8位
FLAG1     EQU   38H     ;是否检测到DS18B20标志位
TEMPL     EQU   30H     ;用于保存读出温度的低8位
TEMPH     EQU   31H     ;用于保存读出温度的高8位
TEMPHC    EQU   32H     ;温度转换寄存器低8位
TEMPLC    EQU   33H     ;温度转换寄存器高8位
BUF1      EQU   34H     ;显示缓冲寄存器小数位
BUF2      EQU   35H     ;显示缓冲寄存器个数位
BUF3      EQU   36H     ;显示缓冲寄存器十数位
BUF4      EQU   37H     ;显示缓冲寄存器百数位
T10MS     EQU   29H     ;
;**********************************************
TEMPDIN   BIT   P3.0    ;数据脚定义
;**********************************************
; BIT FLAG DEFINATION
;**********************************************
TEMPCONV  EQU   00H     ;
TIME1SOK  EQU   01H     ;
TEMPONEOK EQU   02H     ;
;**********************************************
         ORG     0000H             ;主程序入口地址
         AJMP    MAIN              ;转主程序
         ORG     0003H             ;外中断0中断入口
         DB      00H,00H,00H,00H,00H,00H,00H;
         RETI                      ;跳至INTEX0执行中断服务程序
         ORG     000BH             ;定时器T0中断入口地址
         AJMP    TIMER0            ;
         RETI                      ;跳至定时器T0执行中断服务程序
         ORG     0013H             ;外中断1中断入口
         DB      00H,00H,00H,00H,00H,00H,00H ;
         RETI                      ;跳至INTEX1执行中断服务程序
         ORG     001BH             ;定时器T1中断入口地址
         DB      00H,00H,00H,00H,00H,00H,00H ;
         RETI                      ;中断返回(不开中断)
         ORG     0023H             ;串行口中断入口地址
         DB      00H,00H,00H,00H,00H,00H,00H ;
         RETI                      ;中断返回(不开中断)
;**********************************************
          ORG    100H              ;
MAIN:
          MOV    SP,  #60H         ;
          MOV    P2,  #0FFH        ;
   MOV    P3,  #0FFH        ;
          MOV    TMOD,#01H         ;
          MOV    TH0, #0B1H        ;SET T0 VALUE 10MS
          MOV    TL0, #0E0H        ;
          CLR    EA                ;打开CPU总中断请求
          CLR    TR0               ;
          CLR    ET0               ;
          MOV    PSW, #00H         ;
          CLR    TEMPCONV          ;
          CLR    TEMPONEOK         ;
;**************************************
LPTEMP:   LCALL   INIT_1820        ;先复位DS18B20
          MOV     A,#0CCH          ;跳过ROM匹配
          LCALL   WRITE_1820       ;
          MOV     A,#0B8H          ;发出读温度命令
          LCALL   WRITE_1820       ;
          LCALL   GET_TM           ;调用读温度子程序
          LCALL   CONVTEMP         ;温度BCD码计算处理子程序
          LCALL   DISPBCD          ;显示区BCD码温度值刷新子程序
;**************************************

;*************************************
LPTEMP1:  
          LCALL   DISPLAY          ;调用数码管显示子程序
          JB      TEMPONEOK,LPTEMP1;
          LCALL   GET_TEMPER       ;调用读温度子程序
          LCALL   CONVTEMP         ;温度BCD码计算处理子程序
          LCALL   DISPBCD          ;显示区BCD码温度值刷新子程序
          AJMP    LPTEMP1          ;
;**************************************


;***************************************
; 读出转换后的温度值
;***************************************
GET_TEMPER:
           SETB    TEMPDIN        ;
           LCALL   INIT_1820      ;先复位DS18B20
           JB      FLAG1,TSS2
           RET                    ;判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
           MOV     A,#0CCH        ;跳过ROM匹配
           LCALL   WRITE_1820
           MOV     A,#44H         ;发出温度转换命令
           LCALL   WRITE_1820
;*****************************************
;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
;*****************************************
           MOV     R3,#8
LPDISP:    LCALL   DISPLAY
           DJNZ    R3,LPDISP
;*****************************************
GET_TM:    LCALL   INIT_1820       ;准备读温度前先复位

           MOV     A,#0CCH         ;跳过ROM匹配
           LCALL   WRITE_1820

           MOV     A,#0BEH         ;发出读温度命令
           LCALL   WRITE_1820

           LCALL   READ_18200      ;将读出的温度数据保存到40H/41H
           RET
;*******************************************
;写DS18B20的子程序(有具体的时序要求)
;*******************************************
WRITE_1820:
           MOV     R2,#8          ;一共8位数据
           CLR     C              ;
WR1:
           CLR     TEMPDIN        ;
           MOV     R3,#6
           DJNZ    R3,$
           RRC     A
           MOV     TEMPDIN,C      ;
           MOV     R3,#23
           DJNZ    R3,$
           SETB    TEMPDIN        ;
           NOP
           DJNZ    R2,WR1         ;
           SETB    TEMPDIN        ;
           RET
;*************************************
; 这是DS18B20复位初始化子程序
;*************************************
INIT_1820:
           SETB    TEMPDIN
           NOP
           CLR     TEMPDIN        ;主机发出延时537微秒的复位低脉冲
           MOV     R1,#3
TSR1:      MOV     R0,#107
           DJNZ    R0,$
           DJNZ    R1,TSR1
           SETB    TEMPDIN        ;然后拉高数据线
           NOP
           NOP
           NOP
           MOV     R0,#25H
TSR2:
           JNB     TEMPDIN,TSR3   ;等待DS18B20回应
           DJNZ    R0,TSR2
           LJMP    TSR4           ;延时
TSR3:
           SETB    FLAG1          ;置标志位,表示DS1820存在
           LJMP    TSR5
TSR4:
           CLR     FLAG1          ;清标志位,表示DS1820不存在
           LJMP    TSR7
TSR5:      MOV     R0,#117
TSR6:      DJNZ    R0,TSR6        ;时序要求延时一段时间
TSR7:      SETB    TEMPDIN        ;
           RET

;*************************************
;处理温度BCD码子程序
;*************************************
CONVTEMP: MOV     A,TEMPH          ;
          ANL     A,#80H           ;
          JZ      TEMPC1           ; 判断温度是否在零下?

          CLR     C                ; 温度值补码 变成原码
          MOV     A,TEMPL          ;
          CPL     A
          ADD     A,#01H           ;
          MOV     TEMPL,A          ;
          MOV     A, TEMPH         ; -
          CPL     A                ;
          ADDC    A,#00H           ;
          MOV     TEMPH,A          ; TEMPHC  HI=符号位
          MOV     TEMPHC,#0BH      ; 置"-"标志
          SJMP    TEMPC11          ;
TEMPC1:   MOV     TEMPHC,#0AH      ; 置"+"标志
;**************************************
TEMPC11:  MOV     A,TEMPHC         ; 计算小数位温度BCD值
          SWAP    A
          MOV     TEMPHC,A         ;
          MOV     A,TEMPL          ;
          ANL     A,#0FH           ; 乘0.0625
          MOV     DPTR,#TEMPDOTTAB ;
          MOVC    A,@A+DPTR        ;
          MOV     TEMPLC,A         ; TEMPLC LOW= 小数部分 BCD
;**************************************
          MOV     A,TEMPL          ; 计算整数位温度BCD值
          ANL     A,#0F0H          ;
          SWAP    A                ;
          MOV     TEMPL,A          ;
          MOV     A,TEMPH          ;
          ANL     A,#0FH           ;
          SWAP    A                ;
          ORL     A,TEMPL          ;
          MOV     TEMPER_L ,A      ;
          LCALL   HEX2BCD1         ; 调用单字节十六进制转BCD子程序
;************************************
          MOV     TEMPL,A          ;
          ANL     A,#0F0H          ;
          SWAP    A                ;
          ORL     A,TEMPHC         ; TEMPHC LOW = 十位数 BCD
          MOV     TEMPHC,A         ;
          MOV     A,TEMPL          ;
          ANL     A,#0FH           ;
          SWAP    A                ; TEMPLC HI = 个位数 BCD
          ORL     A,TEMPLC         ;
          MOV     TEMPLC,A         ;
          MOV     A,R7             ;
          JZ      TEMPOUT          ;
          ANL     A,#0FH           ;
          SWAP    A                ;
          MOV     R7,A             ;
          MOV     A,TEMPHC         ; TEMPHC HI = 百位数 BCD
          ANL     A,#0FH           ;
          ORL     A,R7             ;
          MOV     TEMPHC,A         ;
TEMPOUT:  RET                      ;
;**************************************
;小数部分分码表
;**************************************
TEMPDOTTAB: DB  00H,01H,01H,02H,03H,03H,04H,04H,05H,06H
            DB  06H,07H,08H,08H,09H,09H ;
;**************************************
;显示区 BCD 码温度值刷新子程序
;**************************************
DISPBCD: MOV      A,TEMPLC         ; 温度数据移入显示寄存器
         ANL      A,#0FH           ;
         MOV      BUF1,A           ; 显示小数
         MOV      A,TEMPLC         ;
         SWAP     A                ;
         ANL      A,#0FH           ;
         MOV      BUF2,A           ; 显示个位
         MOV      A,TEMPHC         ;
         ANL      A,#0FH           ;
         MOV      BUF3,A           ; 显示十位
         MOV      A,TEMPHC         ;
         SWAP     A                ;
         ANL      A,#0FH           ;
         MOV      BUF4,A           ; 显示百位
         MOV      A,TEMPHC         ;
         ANL      A,#0F0H          ;
         CJNE     A,#10H,DISPBCD0  ; 百位数=0?
         SJMP     DISPOUT          ;
DISPBCD0:
         MOV      A, TEMPHC        ;
         ANL      A, #0FH          ;
         JNZ      DISPOUT          ; 十位数是0?
         MOV      A,TEMPHC         ;
         SWAP     A                ;
         ANL      A,#0FH           ;
         MOV      BUF4,0AH         ; 符号位不显示
         MOV      BUF3,A           ; 十位数显示符号
DISPOUT: RET                       ;                 ;
;*************************************
;单字节十六进制转BCD
;*************************************
HEX2BCD1:MOV     B,#64H            ; 十六进制 ->BCD
         DIV     AB                ; B=A%100
         MOV     R7,A              ; R7=百位数
         MOV     A,#0AH            ;
         XCH     A,B               ;
         DIV     AB                ; B=A%B
         SWAP    A                 ;
         ORL     A,B               ;
         RET                       ;
;**************************************
;DECIMAL DATA IS TRANSISTERED HEX DATA
;INPUT: A=DECIMAL DATA
;OUTPUT:A
;USED REGISTER: R1,R2,A
;**************************************
DECHEX:   MOV   R1,    A
          SWAP  A
          ANL   A,     #0FH
          RL    A
          MOV   R2,    A
          RL    A
          RL    A
          ADD   A,     R2
          MOV   R2,    A
          MOV   A,     #0FH
          ANL   A,     R1
          ADD   A,     R2
          RET
;*************************************
; Calculate CRC-8 Values, Uses The
;CCITT-8 Polynomial,Expressed As
; X^8+X^5+X^4+1
;*************************************
CRC8CAL: PUSH    ACC               ;
         MOV     R7,#08H           ; Number Bits Byte
CRC8LOOP1:
         XRL     A,B               ; Calculate CRC
         RRC     A                 ; Move T0 Carry
         MOV     A,B               ; Get The Last CRC Value
         JNC     CRC8LOOP2         ; Skip If Data==0
         XRL     A,#18H            ; Update The CRC Value
CRC8LOOP2:
         RRC     A                 ; Position The New CRC
         MOV     B,A               ; Store The New CRC
         POP     ACC               ; Get The Remaining Bits
         RR      A                 ; Possition The Next Bit
         PUSH    ACC               ; Save The Remaining Bits
         DJNZ    R7,CRC8LOOP1      ; Repeat For 9 Bits
         POP     ACC               ;
         RET                       ;
;******************************************
;读DS18B20的程序,从DS18B20中读出9个字节数据
;开始的两个字节为温度数据
;******************************************
READ_18200:
           MOV     R4,#9            ; 将温度高位和低位从DS18B20中读出
           MOV     R1,#TEMPER_L     ; 低位存入40H(TEMPER_L),高位存入41H(TEMPER_H)
           MOV     B, #00H          ;
;************************************
RE00:
           MOV     R2,#8            ; 数据一共有8位
RE01:
           CLR     C
           SETB    TEMPDIN          ;
           NOP
           NOP
           CLR     TEMPDIN          ;
           NOP
           NOP
           NOP
           SETB    TEMPDIN          ;
           MOV     R3,#9
RE10:
           DJNZ    R3,RE10          ;
           MOV     C,TEMPDIN        ;
           MOV     R3,#23
RE20:
           DJNZ    R3,RE20          ;
           RRC     A
           DJNZ    R2,RE01          ;
;************************************
           MOV     @R1,A            ;
           INC     R1               ;
           LCALL   CRC8CAL          ;
           DJNZ    R4,RE00          ;
           MOV     A,B              ;
           JNZ     READ_OUT         ;
           MOV     TEMPL,TEMPER_L   ;
           MOV     TEMPH,TEMPER_H   ;
READ_OUT:  RET                      ;
;****************************************
; TIMER0 INTERRUPT SUBROUTE
; GERANATE AN INTERRUPT PER 10ms
;****************************************
TIMER0:   PUSH   PSW                  ; PROTECT PSW,ACC REGISTER
          PUSH   ACC                  ;
          MOV    TL0,   #0B1H         ;
          MOV    TH0,   #0E0H         ;
          INC    T10MS                ;
          MOV    A,T10MS              ;
          CJNE   A,#05H,TMREND        ;
          MOV    T10MS,#00H           ;
          SETB   TIME1SOK             ;

          LCALL  GET_TEMPER           ;调用读温度子程序
          LCALL  CONVTEMP             ;温度BCD码计算处理子程序
          LCALL  DISPBCD              ;显示区BCD码温度值刷新子程序
          LCALL  DISPLAY              ;
TMREND:   POP    ACC                  ;
          POP    PSW                  ;
          RETI                        ;
;***************************************************************

;     温度显示子程序

;***************************************************************
;显示数据在34H - 37H 单元内,用4位共阳数码管显示,P0口输出段码数据,
;P2 口作扫描控制,每个 LED 数码管亮 2MS 时间再逐位循环。

DISPLAY:     MOV  R1,#BUF1            ;指向显示数据首址
;             MOV  R5,#7FH            ;扫描控制字初值
             MOV  R5,#0F7H            ;扫描控制字初值

PLAY:        MOV  P0,#0FFH
             MOV  A,R5                ;扫描字放入A
             MOV  P1,A
             MOV  A,@R1               ;取显示数据到A
             MOV  DPTR,#NUMTAB        ;取段码表地址
             MOVC  A,@A+DPTR          ;查显示数据对应段码
             MOV  P0,A                ;段码放入P0口
             MOV  A,R5
             JB   ACC.2,LOOP5         ;小数点处理
             CLR  P0.7
LOOP5:       LCALL  DL1MS              ;显示2MS
             INC  R1                   ;指向下一个地址
             MOV  A,R5                 ;放回 R5 内
             JNB  ACC.7,ENDOUT        ;ACC.3=0时一次显示结束
             RR   A                    ;A 中数据循环左移
             MOV  R5,A                ;放入 R5 中
             AJMP  PLAY               ;跳回 PLAY 循环

ENDOUT:      MOV  P0,#0FFH            ;一次显示结束,P0口复位
             MOV  P1,#0FFH            ;P2口复位
             RET
;*****************************************

;**************************************
;10毫秒延时程序
;**************************************
DL10MS:   LCALL   DISPLAY            ;
          RET                        ;
;****************************************
;0.2MS延时(按12MHZ算)
;****************************************
DL1MS:     MOV     R7,#100
           DJNZ    R7,$
           RET
;****************************************
;7段数码管0~9数字的共阳显示代码
;****************************************
NUMTAB:   DB     0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,0BFH ;
;               "0"  "1"  "2"  "3"  "4" "5" "6" "7"  "8" "9" "不亮" "-"
;****************************************
          END

本站已经获得中华人民共和国工信部、通信管理局审批通过 国家ICP备案序号: 赣ICP备13006653号-2

电工电子技术QQ群(1):66585281电工电子技术QQ群(2):197874883电工电子技术QQ群(3):29019650 

版权归刘昆山所有©2013-2020转载须经本人同意,否则后果自负!  《我的电子制作经验》www.dgdz.net All Rights Reserved.

管 理