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

📄 18b20.asm

📁 51单片机驱动DSB20单总线温度传感器
💻 ASM
字号:
;本程序测量温度范围:0~125度,精确到0.06;
;********************************************************************************
;*  日期:  2008-2-25                                                            *
;*  版本:  3.0                                                                  *
;*  作者:  深圳志博电子有限公司     专业8051单片机教学站                        *
;*  邮箱: zty0012001@163.com                                                       *
;*  网站: http://www.elecmcu.com     http://www.elecmcu.com    更多例程请登陆网站   *
;********************************************************************************
;*  硬件:此程序在本公司志博电子实验仪运行通过                           *
;********************************************************************************
;* 【版权】 Copyright(C)深圳志博电子有限公司 www.elecmcu.com  All Rights Reserved *
;* 【声明】 此程序仅用于学习与参考,引用请注明版权和作者信息!                  *
;********************************************************************************
	 DAT   BIT P1.7   				;数据通信口
	 WDLSB DATA 30H 					;读出的温度低字节
	 WDMSB DATA 31H 					;读出的温度高字节
         DIS_1 BIT P0.5                 ;第一个数码管显示选择
         DIS_2 BIT P0.6                 ;第二个数码管显示选择
         DIS_3 BIT P0.7                 ;第三个数码管显示选择
         DIS_4 BIT P1.0                 ;第四个数码管显示选择
         DIS_5 BIT P1.1                 ;第五个数码管显示选择
         DIS_6 BIT P0.4                 ;第六个数码管显示选择
         DIS_DATA  DATA P2              ;6位数码管的公共数据口
         DIS_INDEX DATA 32H             ;显示位序列,存储目前显示的是第几位 
         DIS_BUFF  DATA 40H             ;显示缓冲区首地址 一共从0X19-0X1E 六个字节
;***************************************************************
      ORG 0000H
      LJMP MAIN
      ORG 000BH
      SJMP TIMER0 				;定时显示

;****************************************************************
						;定时显示子程序,采用循环扫描方式
						;显示缓冲区40H~47H
        ORG 0040H
TIMER0:

;**********************************************************
; 数码管显示子程序
;**********************************************************
PLAY:                           ;显示子程序开始
               ; MOV DIS_INDEX,#00  ;初始化显示的数码管是第0位
DISPLAY_START:                     ;显示一位开始
                CALL OFF_ALL       ;调用子程序关闭所有数码管的显示
                MOV DIS_DATA,#00 ;  6个数目管的公共显示数据写0关闭
		MOV A, DIS_INDEX
DIS0_B:		CJNE A,#0X00,DIS1_B
		CLR DIS_1
		JMP MOV_DAT
DIS1_B:
		CJNE A,#0X01,DIS2_B
		CLR DIS_2
		JMP MOV_DAT
DIS2_B:
		CJNE A,#0X02,DIS3_B
		CLR DIS_3
		JMP MOV_DAT
DIS3_B:
		CJNE A,#0X03,DIS4_B
		CLR DIS_4
		JMP MOV_DAT
DIS4_B:
		CJNE A,#0X04,DIS5_B
		CLR DIS_5
		JMP MOV_DAT
DIS5_B:
		CJNE A,#0X05,DIS_END
		CLR DIS_6
		JMP MOV_DAT         ;以上程序根据现在的显示位数进行条件分支,分别打开相应的显示使能位
MOV_DAT:        
                MOV A, DIS_INDEX
                MOV R1,#DIS_BUFF
                ADD A,R1              
                MOV R0,A
                MOV A,@R0           ;获得目前的显示位所对应自己的缓冲数据
		MOV DPTR,#DIS_TAB
		MOVC A,@A+DPTR
                ANL  A,#0XDF
                MOV  0X37,A
                MOV  A,DIS_INDEX
                CJNE A,#03,RE_DIS
                MOV  A,0X37
                ORL  A,#0X20
                JMP  RE_DIS1
RE_DIS:
                MOV  A,0X37
RE_DIS1:        MOV  DIS_DATA,A     ;将目前的显示数据经过查表获得对应的数码管段码
                INC DIS_INDEX       ;显示位序加一,指向下一位
                MOV A,DIS_INDEX 
                CJNE A,#6,DIS_END ;以上两句判断是否循环显示够6位是的话返回到被调用的位置 否则进行下一次循环
                MOV DIS_INDEX,#00
DIS_END:
        MOV TH0,#LOW(65536-40000)  			;定时器10MS中断
	MOV TL0,#HIGH(65536-40000)
	RETI


T1MS: mov	r5,#00h				;延时子程序
tt:	mov	r6,#9
	djnz	r6,$
	djnz	r5,tt
	ret


DELAY:                                 ;延迟子程序
                MOV R6,#0X01
DELAY0:         MOV R5,#0XFF
DELAY1:         MOV R4,#0XFF
                DJNZ R4,$
                DJNZ R5,DELAY1
                DJNZ R6,DELAY0
                RET

OFF_ALL:                                 ;关闭所有显示位的子程序   
		SETB DIS_1        
		SETB DIS_2
		SETB DIS_3
		SETB DIS_4
		SETB DIS_5
		SETB DIS_6
                RET

DIS_TAB:                                ;0-9 所对应的数码管段码    最后一个00 是总关闭显示
		DB 0x7f,0x44,0xbd,0xf5,0xe6,0xf3,0xfb,0x65,0xff,0xf7,0x00
;*********************************************************
						;主程序:
MAIN:   MOV SP,#60H
        MOV DIS_INDEX,#00
	MOV R2,#8
	MOV R0,#40H ;
OVER:   MOV @R0,#00H
        INC R0
	DJNZ R2,OVER
        MOV 40H,#10;
        MOV 41H,#10;
	MOV TMOD,#01H
	MOV TH0,#LOW(65536-10000)
	MOV TL0,#HIGH(65536-10000)
	SETB EA
	SETB ET0
	SETB TR0
LOOP:   LCALL DSWD 				;调用读出DS18B20温度程序
	SJMP LOOP                                                ; 读出DS18B20温度程序
DSWD:
	CLR EA
	LCALL RST
	JNB F0,KEND 				;如果没有应答,返回主程序
	MOV R0,#0CCH
	LCALL SEND_BYTE 			;跳过ROM匹配
	MOV R0,#44H				;发出温度转换命令
	LCALL SEND_BYTE
	SETB EA
	;MOV P1,#00001111B
	MOV 48H,#4 				;廷时75ms以上准备读
SS2:    MOV 49H,#255
SS1:    MOV 4AH,#255
SS0:    DJNZ 4AH,SS0
 	DJNZ 49H,SS1
	DJNZ 48H,SS2
	;MOV P1,#11111100B
	CLR EA
	LCALL RST
	JNB F0,KEND
	MOV R0,#0CCH 				;跳过ROM匹配
	LCALL SEND_BYTE
	MOV R0,#0BEH 				;发出读温度命令
	LCALL SEND_BYTE
	LCALL READ_BYTE
	MOV WDLSB,A
	LCALL READ_BYTE
	MOV WDMSB,A
	LCALL TRANS12
KEND:   ;mov p1,#01010101b
	SETB EA
	RET
;**********************************************************
;温度转换程序:精确到:0.06 ;
TRANS12:MOV A,30H
	ANL A,#0F0H
	MOV 3AH,A
	MOV A,31H
	ANL A,#0FH
	ORL A,3AH
	SWAP A
	MOV B,#10
	DIV AB
	MOV 42H,A
	MOV 43H,B ;
	MOV DPTR,#TABB
	MOV A,30H
	ANL A,#0FH
	MOV B,#2
	MUL AB
	MOVC A,@A+DPTR
	MOV 44H,A
	MOV A,30H
	ANL A,#0FH
	MOV B,#2
	MUL AB
	INC A
	MOVC A,@A+DPTR
	MOV 45H,A
	RET
TABB:   DB 0,0,0,6,1,2,1,8,2,5,3,1,3,7,4,3,5,0
	DB 5,6,6,2,6,8,7,5,8,1,8,7,9,3
;*************************************************

SEND_BYTE: 					;发送一个字节程序
	MOV A,R0
	MOV R5,#8
SEN3: 	CLR C
	RRC A
	JC SEN1
	LCALL WRITE_0
	SJMP SEN2
SEN1:   LCALL WRITE_1
SEN2: 	DJNZ R5,SEN3                    	; 循环8次,写一个字节
	RET
READ_BYTE: 					;读一个字节程序
	MOV R5,#8
READ1:  LCALL READ
	RRC A
	DJNZ R5,READ1                   	; 循环8次,读一个字节
	MOV R0,A
	RET
						;复位程序,如果复位置位F0,没有就复位F0
RST: 	SETB  DAT
	NOP
	NOP
	CLR DAT

	MOV R6,#250 				;主机发复位脉冲持续3μs50200=600μs
	DJNZ R6,$
	MOV R6,#50
	DJNZ R6,$
        MOV R6,#250 				;主机发复位脉冲持续3μ00=600μs
	DJNZ R6,$
	MOV R6,#50
	DJNZ R6,$
        MOV R6,#250 				;主机发复位脉冲持续3μs×200=600μs
	DJNZ R6,$
	MOV R6,#50
	DJNZ R6,$
	MOV R6,#250 				;主机发复位脉冲持续3μs×200=600μs
	DJNZ R6,$
	MOV R6,#50
	DJNZ R6,$

	SETB DAT                         	;主机释放总线,口线改为输入
	MOV R6,#60
	DJNZ R6,$
	CALL CHCK 				;调用应答检查程序
	MOV R6,#240
	DJNZ R6,$
	SETB DAT
	RET
CHCK: 	MOV C,DAT
	JC RST0
	SETB F0                          	;检测到信号,置位F0
	SJMP    CHCK0
RST0: 	CLR F0                           	;未准备好F0复位
CHCK0:  RET

WRITE_0: 				    	;写0
        CLR DAT
	MOV R6,#120
	DJNZ R6,$
	SETB DAT
	RET
WRITE_1:CLR DAT                             	;写1
	NOP
	NOP
	NOP
	NOP
        NOP
	SETB DAT
	MOV R6,#120
	DJNZ R6,$
	RET
						;读一位数据程序
READ: 	SETB DAT                     		;先复位至少1US产生读起始信号
	NOP
	NOP
	CLR DAT
	NOP
	NOP
	SETB DAT                      		;置位DAT准备接收数据
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	MOV C,DAT
	MOV R6,#92
	DJNZ R6,$
	RET
	END


⌨️ 快捷键说明

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