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

📄 ds1820sub1200.asm

📁 温度测量
💻 ASM
字号:
;************************************************
;* DS1820 subroutines for AVR's			*
;*						*
;* Simple Temp read for AT90S1200		*
;* No SRAM!! Less Instructions to use		*
;*						*
;* Copyright 2001-2003 Wayne Peacock		*
;* First Revision 2th July 2001			*
;* Version 1.02					*
;*						*
;************************************************
;* See Schematic for Hardware connections	*
;* 						*
;* Disclaimer:					*
;* The Author takes no responsibility for the 	*
;* use of this code. Use at your own risk!	*
;* 						*
;* This code or part there of is licensed only 	*
;* for private use and NOT for commercial use.	*
;* 						*
;* Please contact the Author 'Wayne Peacock' 	*
;* <wpeacock@senet.com.au> before using the code*
;* or part there of in a commercial project.	*
;*						*
;* Muliply/Divide routines are copied from the	*
;* AVR200 Application Note (See Below)		*
;************************************************

;**** A P P L I C A T I O N   N O T E   A V R 2 0 0 ************************
;*
;* Title:		Multiply and Divide Routines
;* Version:		1.1
;* Last updated:	97.07.04
;* Target:		AT90Sxxxx (All AVR Devices)
;*
;* Support E-mail:	avr@atmel.com
;* 
;* DESCRIPTION
;* This Application Note lists subroutines for the following
;* Muliply/Divide applications:
;*
;* 8x8 bit unsigned
;* 8x8 bit signed
;* 16x16 bit unsigned
;* 16x16 bit signed
;* 8/8 bit unsigned
;* 8/8 bit signed
;* 16/16 bit unsigned
;* 16/16 bit signed
;*
;* All routines are Code Size optimized implementations
;*
;***************************************************************************

;Registers common to all

;.def	temp		= r16
;.def	data		= r17
;.def	loopcnt		= r18
;.def	crc		= r1	

; **** Pin Consignments ****

.equ	WIRE		= 4

.set	WIREPORT	= PORTB
.set	WIREDIR		= DDRB
.set	WIREIN		= PINB


.def	templsb		= r2
.def	tempmsb		= r3
.def	userb1		= r4
.def	userb2		= r5
.def	crap1		= r6
.def	crap2		= r7
.def	count_remain	= r8
.def	count_per_c	= r9
.def	scratch_crc	= r10
.def	crc		= r11
.def	templ		= r12		; Converted result
.def	temph		= r13

.def	vallow		= r22
.def	valhigh		= r23

;************************************************
;* DS1820 Init	(4 Mhz)				*
;************************************************

DS1820_init:

	cbi	WIREPORT, WIRE		; Bit always low
	cbi	WIREDIR, WIRE		; Set pin up as open drain
	ret

	
;************************************************
;* DS1820 Reset	(4 Mhz)				*
;*						*
;* T clear if Presence 				*
;* Requires:	temp				*
;* 		count1 (timer)			*
;************************************************

.equ	T	= 6	; STATUS REG

DS1820_reset:
	
	; Reset Pulse
	sbi	WIREDIR, WIRE		; Bus Low
	ldi	count1, 137			
	rcall	delayX5us		; Wait 720us
	cbi	WIREDIR, WIRE		; Bus High
	
	; Delay
	ldi	count1, 13
	rcall	delayX5us		; Wait 67.5us
	
	; Check for Presence signal
	in	temp, WIREIN 
	bst	temp, WIRE		; Store bus status
	
	; Delay
	ldi	count1, 190
	rcall	delayX5us		; Wait 1ms
	
	ret
	
;************************************************
;* DS1820 Write Byte	(4 Mhz)			*
;*						*
;* Input:	data				*
;* Requires:	temp (bit count)		*
;*		count1 (timer)			*
;************************************************

DS1820_Write:
	ldi	temp, 8			; 8 bits to write
	
DS1820_wloop:

	sbi	WIREDIR, WIRE		; [1] Bus low ( 1us to 15us )
	nop
	nop
	nop
	nop
	nop
	ror	data			; [1]
	brcc	DS1820_w0		; [1] Write 0

DS1820_w1:
	cbi	WIREDIR, WIRE		; Data = high

DS1820_w0:
					; Data alread low
	ldi	count1, 13 		; Just wait >60us
	rcall	delayX5us				
					
	cbi	WIREDIR, WIRE		; Bus high
	ldi	count1, 1		; Recovery time >1us
	rcall	delayX5us		; 5us delay!
	dec	temp				
	brne	DS1820_wloop
	
	ret						

;************************************************
;* DS1820 Read Byte	(4 Mhz)			*
;*						*
;* Output:	data				*
;* Requires:	temp (bit count)		*
;* 		count1 (timer)			*
;************************************************

DS1820_read:
	ldi	temp, 8			; 8 bits to write
	clr	data
DS1820_rloop:

	sbi	WIREDIR, WIRE		; [1] Bus low ( 1us to 15us )
	ldi	count1, 1		; Recovery time >1us
	rcall	delayX5us		; 5us delay!
	cbi	WIREDIR, WIRE		; Bus high
	ldi	count1, 1		; Recovery time >1us
	rcall	delayX5us		; 5us delay!
	; Get Data Now
	lsr	data
	sbic	WIREIN, WIRE		; check bit
	sbr	data, 0x80
					; Data alread inactive
	ldi	count1, 13		; Just wait >60us
	rcall	delayX5us				
									
	dec	temp
	brne	DS1820_rloop
	ret	
	
;************************************************
;* DS1820 Do Temp Conversion 	 		*
;*						*
;* Requires: DS1820_Write 			*
;************************************************

DS1820_conv:	
	ldi	data, 0xcc		; Skip ROM check
	rcall	DS1820_Write
	
	ldi	data, 0x44		; Start Temp Conversion
	rcall	DS1820_Write
	
wait_con:
	sbis	WIREIN, WIRE		; Conversion Done!
	rjmp	wait_con
	ret

;************************************************
;* DS1820 Read Scratch Pad		 	*
;* Requires DS1820 ROM ID subroutine		*
;* 						*
;************************************************

DS1820_Scr:

	ldi	data, 0xcc		; Skip ROM check
	rcall	DS1820_Write
	
	ldi	data, 0xbe		; read Scratch Pad
	rcall	DS1820_Write
	
  	; Byte 0
	rcall	DS1820_Read		; Read a byte
	mov	templsb, data		; store data
	;rcall	onechar
	
	; Byte 1
	rcall	DS1820_Read		; Read a byte
	mov	tempmsb, data		; store data
	;rcall	onechar
	
	; Byte 2
	rcall	DS1820_Read		; Read a byte
	mov	userb1, data		; store data
	;rcall	onechar
	
	; Byte 3
	rcall	DS1820_Read		; Read a byte
	mov	userb2, data		; store data
	;rcall	onechar
	
	; Byte 4
	rcall	DS1820_Read		; Read a byte
	mov	crap1, data		; store data
	;rcall	onechar
	
	; Byte 5
	rcall	DS1820_Read		; Read a byte
	mov	crap2, data		; store data
	;rcall	onechar
	
	; Byte 6
	rcall	DS1820_Read		; Read a byte
	mov	count_remain, data	; store data
	;rcall	onechar
	
	; Byte 7
	rcall	DS1820_Read		; Read a byte
	mov	count_per_c, data	; store data
	;rcall	onechar
																	
	; Byte CRC
	rcall	DS1820_Read		; Read a byte
	mov	scratch_crc, data	; store data
	;rcall	onechar
	
	ret
	
;************************************************
;* Dump Temp from SRAM to RS232 (real value)	*
;* Resolution 0.5 deg C	 negative works		*
;* 						*
;* Input:	templsb (SRAM)			*
;* Output:	RS232				*
;* Requires:	data				*
;*						*
;************************************************

dump_temp:

	; Check for positive or negative temp!
	
	tst	tempmsb
	breq	postemp			; Temp is Positive!

	; Display a negative number!!

	ldi	data, '-'
	rcall	onechar

	ldi	temp, 0x00
	sub	temp, templsb
	mov	hex, temp
	rjmp	distemp

postemp:
	ldi	data, ' '
	rcall	onechar
	mov	hex, templsb		; Get LSB
	
distemp:	
	lsr	hex
	rcall	hexdec			; Convert to decimal
	
	; display now
	
	;mov	data, templsb
	mov 	data, hund
	rcall 	onechar
	mov 	data, tens
	
	;mov	data, tempmsb
	rcall 	onechar
	mov 	data, unit
	rcall 	onechar
	
	; decimal place
	ldi	data, '.'
	rcall	onechar
	mov	hex, templsb
	ldi	data, '0'
	sbrc	hex, 0	
	ldi	data, '5'
	rcall	onechar
	ldi	data, 'C'
	rcall	onechar
	ret

;************************************************
;* DS1820 Temp Calculate 			*		
;* High Resolution				*
;*  						*
;* Input:	SRAM				*
;* Output:	SRAM				*	
;* Requires:	r12				*
;*		r13				*
;*		r14				*
;*		r15				*
;*		r16				*
;*		r17				*
;*		r18				*
;* Fully Functional at 21th Sept 2002		*
;* Tested with Positive and negative temperature*
;* Quick fix added for negative conversion	*
;************************************************
		
dump_temp2:

;***** Register Variables
.def valuel 	= r16
.def valueh 	= r17
.def result	= r15
.def count 	= r18
.def valuem	= r19

	; Result Registers
	clr	vallow
	clr	valhigh

	mov	valhigh, templsb	; Put DS1820 value in	
	lsr	valhigh			; Remove 0.5C Bit
	
	sbrc	tempmsb, 0		; Check if negative number
	sbr	valhigh, 0x80
	
	; Subract the 0.25C
	subi	vallow,0x40		;Subtract low bytes (0.25C)
	sbci	valhigh,0x00		;Subtract high byte with carry

	; Calulate remaining counts
	; Temp = countperc - countremain
	
	mov	valueh, count_per_c
	mov	valuel, count_remain
	sub	valueh, valuel		;Subract remainder from countperc
		
	;***** Divide Two Unsigned 16-Bit Numbers
	
.def	drem16uL=r14 	; Dump (Temp Only)
.def	drem16uH=r15	; Dump (Temp Only)

.def	dres16uL=r16	; Keep (valuel)
.def	dres16uH=r17	; Keep (valueh)
.def	dd16uL	=r16	; 00
.def	dd16uH	=r17	; count_per_c - countremain

.def	dv16uL	=r12	; count_per_c
.def	dv16uH	=r13	; 00
	
	mov	dv16uL, count_per_c
	clr	dv16uH
	clr	dd16uL
	
div16u:	clr	drem16uL		;clear remainder Low byte
	sub	drem16uH,drem16uH	;clear remainder High byte and carry
	ldi	count,17		;init loop counter
d16u_1:	rol	dd16uL			;shift left dividend
	rol	dd16uH
	dec	count			;decrement counter
	brne	d16u_2			;if done
	rjmp	dump_3			;Finished here
		
d16u_2:	rol	drem16uL		;shift dividend into remainder
	rol	drem16uH
	sub	drem16uL,dv16uL		;remainder = remainder - divisor
	sbc	drem16uH,dv16uH		;
	brcc	d16u_3			;if result negative
	add	drem16uL,dv16uL		;    restore remainder
	adc	drem16uH,dv16uH
	clc				;    clear carry to be shifted into result
	rjmp	d16u_1			;else
d16u_3:	sec				;    set carry to be shifted into result
	rjmp	d16u_1
	
dump_3:
	; We want Low & High result
	; Result in R16 (valuel) (Always Positive)
	; add R16 to vallow
	; add R17 to valhigh
	
	add	vallow, valuel		; Add count remaining
	adc	valhigh, valueh		; Add 
		
	mov	valuel, vallow
	mov	temph, valhigh		;Store Temp High (Final Value)
	
	; Check if negative Number!!
	
	sbrs	temph, 7
	rjmp	ptemp			; Temp is positive
	
	; Invert fraction for conversion
	neg	valuel
	
	; Quick Fix 21th Sept 2002
	; Fixes jumps at whole negative temperatures
	ldi	r17, 00
	cp	valuel, r17
	brne	ptemp
	ldi	r17, 01
	sub	temph, r17
	
	; Fraction in valuel must convert to displayable number!
	; Therefore multiply by 64h and dump LSB
	
	; valuel -> multiplicand
	; valueh -> multiplier
	; result -> Result High Byte
	; valueh -> Result Low Byte -> Discard

ptemp:
	ldi	valueh, 0x64		;Multiplier	
	
mpy8u:	clr	result			;clear result High byte
	ldi	count,8			;init loop counter
	lsr	valueh			;rotate multiplier
	
m8u_1:	brcc	m8u_2			;carry set 
	add 	result, valuel		;add multiplicand to result High byte
m8u_2:	ror	result			;rotate right result High byte
	ror	valueh			;rotate right result L byte and multiplier
	dec	count			;decrement loop counter
	brne	m8u_1			;if not done, loop more

	mov	templ, result		;Store Temp Low
	ret
	
;*** Working as of July 2002 !! Removed from sub1200 ***


;************************************************
;* Dump Temp from SRAM to LCD (real value)	*
;* High Resolution Version			*
;* 						*
;************************************************
	
	; Display Now
	
DS_disp:

	; Check for positive number
	sbrs	temph, 7
	breq	postemp2		; Temp is Positive!

	; Display a negative number!!

	ldi	data, '-'
	rcall	onechar
	
	ldi	hex, 0xff
	sub	hex, temph
	;mov	hex, temph
	;neg	hex
	rcall	hexdec			;Convert to decimal
	ldi	data, ' '
	
	mov 	data, tens
	rcall	onechar
	
	mov 	data, unit
	rcall	onechar
	
	ldi	data, '.'
	rcall	onechar
	
	mov	hex, templ
	rcall	hexdec
	
	mov 	data, tens		; Value can only be 0 - 99! No hundreds
	rcall	onechar
	
	mov 	data, unit
	rcall	onechar

	rjmp	ds_dec
	
postemp2:

	ldi	data, ' '
	rcall	onechar
		
	mov	hex, temph		;Get High Value
	cbr	hex, 0x80
	rcall	hexdec			;Convert to decimal
	ldi	data, ' '
	
	mov 	data, tens
	rcall	onechar
	
	mov 	data, unit
	rcall	onechar
	
	; decimal place
	ldi	data, '.'
	rcall	onechar
	
	mov	hex, templ
	rcall	hexdec
	
	mov 	data, tens		; Value can only be 0 - 99! No hundreds
	rcall	onechar
	
	mov 	data, unit
	rcall	onechar

ds_dec:	
	ldi	data, 'C'
	rcall	onechar	
	ret

;************************************************
;* Dump registers to LCD			*
;* High Resolution Version			*
;* 						*
;************************************************

dump_reg:

	mov	hex, templsb		;Get High Value
	rcall	hexasc			;Convert to Ascii
	ldi	data, ' '
	
	mov 	data, tens
	rcall	onechar
	
	mov 	data, unit
	rcall	onechar
	
	mov	hex, tempmsb		;Get High Value
	rcall	hexasc			;Convert to Ascii
	ldi	data, ' '
	
	mov 	data, tens
	rcall	onechar
	
	mov 	data, unit
	rcall	onechar
	
	mov	hex, count_remain	;Get High Value
	rcall	hexasc			;Convert to Ascii
	ldi	data, ' '
	
	mov 	data, tens
	rcall	onechar
	
	mov 	data, unit
	rcall	onechar
	
	mov	hex, count_per_c	;Get High Value
	rcall	hexasc			;Convert to Ascii
	ldi	data, ' '
	
	mov 	data, tens
	rcall	onechar
	
	mov 	data, unit
	rcall	onechar
		
	ret
	

⌨️ 快捷键说明

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