⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 18b20(1).asm

📁 18B20.asm 基于AT89S52单片机的温度计 两位显示的
💻 ASM
字号:
 FLAG1   BIT    F0        ;DS18B20存在标志位
 DQ      BIT    P3.7	  ;DS18B20接口地址
 TEMPER_L    EQU   29H	  ;用于保存读出温度的低8位
 TEMPER_H    EQU   28H	  ;用于保存读出温度的高8位
 A_BIT      EQU    35H	   ;数码管个位数存放内存位置
 B_BIT      EQU    37H		;数码管十位数存放内存位置
;************程序起始********************
     ORG    0000H
     AJMP   MAIN
     ORG    0100H

;**************主程序开始************
MAIN:
       	  	
          mov  p0 ,#0ffh	 
          
          LCALL    INIT_18B20	 ;调用DS18B20复位初始化子程序
          LCALL    GET_TEMPER	;调用读温度子程序
          AJMP     CHANGE         ;调用读出的温度进行数据转换子程序

;**********DS18B20复位初始化子程序*****************
INIT_18B20:    SETB   DQ	;拉高数据线,释放ds1820总线,口线改为输入
               NOP			;延时一个时钟周期2ms
               CLR    DQ	;然后拉低数据线,口线改为输出
;主机发出延时537微秒的复位低脉冲
               MOV    R0,#0FBH
          TSR1: DJNZ   R0,TSR1      ;延时
                SETB   DQ		   ;然后拉高数据线,口线改为输入
                MOV    R0,#25H
          TSR2: JNB   DQ ,TSR3	   ;等待DS18B20回应
               DJNZ   R0,TSR2		
			   LJMP TSR4          ; 延时
          TSR3: SETB   FLAG1       ;置标志位,表明DS18B20存在
		        CLR P1.3		  ;检查到DS18B20就点亮P1.1LED
            AJMP   TSR5			  ; 延时
          TSR4: CLR   FLAG1		  ;清标志位,表示DS1820不存在
               LJMP   TSR7		  ;不存在则跳转到TSR7,拉高数据线
          TSR5: MOV   R0,#06BH
          TSR6: DJNZ   R0,TSR6	  ;复位成功!时序要求延时一段时间
          TSR7:SETB   DQ          ;表明不存在
          RET					  ;返回主程序,继续执行下一个环节
;*****************读出转换后的温度值****************
GET_TEMPER:
            SETB   DQ			;拉高数据线,释放ds1820总线,口线改为输入
            LCALL  INIT_18B20  ;先复位DS18B20
            JB     FLAG1,TSS2
            RET                ;判断DS1820是否存在?若DS18B20不存在则返回
      TSS2: MOV  A,#0CCH        ;跳过ROM匹配
            LCALL  WRITE_18B20	  ;调用写DS18B20的子程序
            MOV    A,#44H         ;发出温度转换命令
            LCALL   WRITE_18B20	  ;调用写DS18B20的子程序
			      MOV R0,#50				 ;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
            LCALL    DISPLAY           
            LCALL    INIT_18B20		;准备读温度前先复位
            MOV  A,#0CCH        ;跳过ROM
            LCALL  WRITE_18B20	   ;调用写DS18B20的子程序
            MOV    A,#0BEH         ;发出读温度命令
            LCALL   WRITE_18B20		;调用写DS18B20的子程序
            LCALL   READ2_18B20    ;读两个字节的温度,将读出的温度数据保存到29H/28H 
            RET						;返回主程序,执行下一步
 ;***************写DS18B20程序(有具体的时序要求)************
 WRITE_18B20:
            MOV    R2,#8  ;一共8位数据
            CLR    C      ;清存在信号(存在C=0,不存在C=1)
        WR1:
              CLR   DQ
              MOV  R3,#6  
              DJNZ  R3,$  ;
              RRC   A	  ;完成一次移位,这样以后便与计算 
              MOV    DQ,C
              MOV   R3,#23
              DJNZ   R3,$
              SETB    DQ
              NOP
              DJNZ    R2,WR1
              SETB  DQ
              RET
 ;***********读18B20程序,从DS18B20中读出两个字节的温度数据*********
 READ2_18B20:
            MOV   R4,#2            ;将温度高位和低位从DS18B20中读出,低位存在29 H,高位存在28H
            MOV   R1,#29H		   ;低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
 
      RE00: MOV  R2,#8			   ;数据一共有8位
      RE01: CLR   C
            SETB   C
            NOP
            NOP
            CLR  DQ
            NOP
            NOP
            NOP
            SETB  DQ
            MOV   R3,#7
            DJNZ   R3,$
            MOV    C,DQ       ;C和DQ同时为高电平
            MOV    R3,#23
             DJNZ   R3,$
            RRC   A
            DJNZ   R2,RE01
            MOV    @R1,A
            DEC    R1
            DJNZ   R4,RE00
            RET
;************读出的温度进行数据转换********************************
CHANGE:     MOV A,29H			  ;将29H中的最高位移入A累加器
            MOV C,28H.0           ;将28H中的最低4位移入C
            RRC A				  ;经过进位位的累加器A循环右移
            MOV C,28H.1			  ;..................
            RRC A				  ;...................
            MOV C,28H.2			  ;...............
            RRC A				  ;...........
            MOV C,28H.3			  ;............
            RRC A				  ;.................
            MOV 29H,A			 ;将A累加器中转换出的2进制温度换成的BCD码移入29H
            LCALL  DISPLAY      ;调用数码管显示子程序
            LJMP MAIN			;跳转到主程序
;*******************DISPLAY显示子程序,此程序要注意的是P2.3口的DS18B20数据采集,不能影响此口 ******************************

 DISPLAY:    SETB p2.0
	     clr  p2.1
             mov a,29H;将29H中的十六进制数转换成10进制
             mov b,#10 ;10进制/10=10进制
             div ab
             mov b_bit,a ;十位在a
             mov a_bit,b ;个位在b
             mov dptr,#TAB ;指定查表启始地址
             mov r0,#4
       dpl1: mov r1,#250 ;显示1000次
      dplop: mov a,a_bit ;取个位数
             MOVC A,@A+DPTR ;查个位数的7段代码
             mov p0,a ;送出个位的7段代码			 
             clr p1.3;开个位显示
             acall d1ms ;显示1ms
             setb p1.3	  ;关个位显示,防止鬼影
             mov a,b_bit ;取十位数
             MOVC A,@A+DPTR ;查十位数的7段代码
             mov p0,a ;送出十位的7段代码
             clr p1.2;开十位显示
             acall d1ms ;显示1ms
             setb p1.2	;关十位显示,防止鬼影
             djnz r1,dplop ;100次没完循环
             djnz r0,dpl1 ;4个100次没完循环
             ret
 ;*******************1MS延时(按12MHZ算)*************************************
 ;为保证DS18B20的严格I/O时序,需要做较精确的延时
             D1MS:      mov     r5,#0afh                 ;351us
time350us_1:            djnz    r5,time350us_1
                        ret
 ;***************************************************************************
 TAB:;7段数码管0~9数字的共阳显示代码 
   	   DB  0C0H        ;"0" 
   DB  0F9H        ;"1"
   DB  0A4H        ;"2"
   DB  0B0H        ;"3"
   DB   99H        ;"4"
   DB   92H        ;"5"
   DB   82H        ;"6"
   DB  0F8H        ;"7"
   DB   80H        ;"8"
   DB   90H        ;"9"
   DB   88H        ;"A"
   DB   83H        ;"B"
   DB  0C6H        ;"C"
   DB  0A1H        ;"D"
   DB   86H        ;"E"
   DB   8EH        ;"F"
   DB   89H        ;"H"
   DB  0C7H        ;"L"
   DB  0C8H        ;"n"
   DB  0C1H        ;"u"
   DB   8CH        ;"P"
   DB  0A3H        ;"o"
   DB  0BFH        ;"-"
   DB  0FFH        ;"熄灭"
   DB  0FFH        ;"自定义"
ret
end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -