Interfacing with a DS1820

Perplexed!

In debugging this routine we saw something which I don't understand.

Note that MAIN calls IN_BYTE which reads eight bits from the DS1820. Note that just prior to the RETURN, I_BYTE is moved to W and in using an emulator, we could see that this was working.

However, in executing the RETURN, the value in W was lost. Note that this is only one stack level. Thus, you will see what appears as a redundancy in MAIN, where each value of I_BYTE is moved to W and then stored.

This suggests that the W register is used in implementing the RETURN and thus it cannot be used to pass a value back to the calling process.

Any thoughts certainly will be welcome.

 
; Program 1820_1.asm
;
; Performs temperature measurment.  No addressing.
;
; Note that in this routine, the results of the measurement are written
; to a data buffer beginning at data location 18H for later display or
; other processing.
;
; 12C509			                     DS1820		
; GPIO.0 (term 7) ------------------------------ DQ (term 2)
;
; copyright, H. Paul Roach, MSU, Oct 10, '97
	
	LIST p=12C509
#include <c:\mplab\p12C509.inc>	
	__CONFIG 0EH	; MCLR dis, CP off, WDT enabled, INTRC

	CONSTANT DATA_PIN=0

	CONSTANT BASE_VAR=07H

	CONSTANT DATA_BUFF=18H
	CONSTANT BUFF_SIZE=7


PIN_DIRS        EQU BASE_VAR+0
N		EQU BASE_VAR+1

_N	   	EQU BASE_VAR+2	; these vars used by the 
O_BYTE	   	EQU BASE_VAR+3	; common 1-wire routines
I_BYTE	   	EQU BASE_VAR+4
LOOP3	   	EQU BASE_VAR+4
LOOP2	   	EQU BASE_VAR+5
LOOP1	   	EQU BASE_VAR+6
TEMP	   	EQU BASE_VAR+7


TEMP_MSB	EQU DATA_BUFF+0	; first location in DATA_BUFF
TEMP_LSB	EQU DATA_BUFF+1
TH_UB1	   	EQU DATA_BUFF+2
TL_UB2	   	EQU DATA_BUFF+3
COUNT_REM	EQU DATA_BUFF+4
COUNT_D_C	EQU DATA_BUFF+5
CRC	   	EQU DATA_BUFF+6
	
		ORG 000H	        

MAIN:
	MOVLW	0C0H	; GPWU dis, GPPU dis, other bits are not used
        OPTION	

        MOVLW	1FH
        MOVWF	PIN_DIRS	; make all I/Os inputs
        TRIS	GPIO

 	CALL	INIT		; intitialize DS1820

        MOVLW	0CCH		; skip ROM
        MOVWF	O_BYTE
        CALL	OUT_BYTE

        MOVLW	44H		; perform temperature conversion
        MOVWF	O_BYTE
        CALL	OUT_BYTE

        CALL	STRONG_PULL_UP	; provide strong pull up during conversion
        
WAIT:        
        CALL 	IN_BYTE
        MOVLW 	0FFH
        SUBWF 	I_BYTE, W
        BTFSS 	STATUS, Z
        GOTO 	WAIT 
		
	CALL	INIT

	MOVLW	0CCH		; skip ROM
        MOVWF	O_BYTE
        CALL	OUT_BYTE
        
	MOVLW	0BEH		; read scratchpad
        MOVWF	O_BYTE
        CALL	OUT_BYTE

        CALL	IN_BYTE		; fetch each byte and save
        MOVF    I_BYTE, W
	MOVWF   TEMP_LSB

        CALL	IN_BYTE
        MOVF    I_BYTE, W
	MOVWF	TEMP_MSB

        CALL	IN_BYTE
	MOVF    I_BYTE, W
        MOVWF   TH_UB1

        CALL	IN_BYTE
	MOVF    I_BYTE, W
        MOVWF   TL_UB2

        CALL	IN_BYTE		; throw these two away
        CALL	IN_BYTE

        CALL	IN_BYTE
	MOVF    I_BYTE, W
        MOVWF	COUNT_REM

        CALL	IN_BYTE
	MOVF    I_BYTE, W
        MOVWF   COUNT_D_C

        CALL	IN_BYTE
	MOVF    I_BYTE, W
        MOVWF   CRC

DISPLAY:
	; not implemented.  At this point data is located in seven
	; bytes beginning at 18H.

DELAY_30_SEC:

	MOVLW .120		; 30 second delay (120 * 250 msecs)
	MOVWF LOOP3
DELAY_30_1
	CALL DELAY_LONG
	DECFSZ LOOP3, F
	GOTO DELAY_30_1

        GOTO	MAIN		; do it again


; The following are standard 1-Wire routines.

INIT:
        CALL	PIN_HI
        CALL	PIN_LO

	MOVLW	.50              ; 500 us delay
	CALL DELAY_10USEC

	CALL	PIN_HI		  
        MOVLW 	.50		; 500 usec delay
        CALL DELAY_10USEC

        RETURN


IN_BYTE:              ; returns byte in W
	MOVLW	.8
	MOVWF	 _N
        CLRF	I_BYTE

IN_BYTE_1:
	CALL PIN_LO		; momentary low on DATA_PIN
        NOP
	CALL PIN_HI
	NOP
	NOP
	NOP
	NOP
	NOP
        NOP
        MOVF	GPIO, W	; 7 usecs later, fetch from DATA_PIN
	MOVWF	TEMP                                                        
	BTFSS	TEMP, DATA_PIN
	BCF STATUS, C		; its a zero
	BTFSC	TEMP, DATA_PIN
	BSF STATUS, C		; its a one

        RRF	I_BYTE, F
	MOVLW .6		; now delay 60 usecs
        CALL	DELAY_10USEC
        DECFSZ	_N, F
        GOTO	IN_BYTE_1

        MOVF	I_BYTE, W	; return the result in W
        RETURN

OUT_BYTE:
	MOVLW	.8
        MOVWF	_N
OUT_BYTE_1:
	RRF	O_BYTE, F
        BTFSS	STATUS, C
	GOTO	OUT_0
	GOTO	OUT_1	
OUT_BYTE_2:
	DECFSZ	_N, F
        GOTO	OUT_BYTE_1
        RETURN

OUT_0:
	CALL	PIN_LO		; bring DATA_PIN low
	MOVLW	.6		; for 60 usecs
	CALL 	DELAY_10USEC
        CALL	PIN_HI
        GOTO	OUT_BYTE_2

OUT_1:
	CALL	PIN_LO		; momentary low
        CALL	PIN_HI
        MOVLW .6
	CALL DELAY_10USEC
        GOTO	OUT_BYTE_2

;;;;;;

PIN_HI:
	BSF	PIN_DIRS, DATA_PIN
        MOVF	PIN_DIRS, W
        TRIS	GPIO
        
        RETURN

PIN_LO:
	BCF	GPIO,  DATA_PIN
	BCF	PIN_DIRS, DATA_PIN	
        MOVF	PIN_DIRS, W
        TRIS	GPIO
        
        RETURN

STRONG_PULL_UP:
	BSF	GPIO, DATA_PIN
        BCF	PIN_DIRS, DATA_PIN
        MOVF	PIN_DIRS, W
        TRIS	GPIO
        CALL	DELAY_LONG
        BSF	PIN_DIRS, DATA_PIN
        MOVF	DATA_PIN, W
        TRIS	GPIO
        RETURN
	

DELAY_LONG
	MOVLW .250	; 250 msec delay
	MOVWF LOOP1
DELAY_N_MS:
OUTTER
	MOVLW	.110	; close to 1.0 msec delay when set to .110
	MOVWF 	LOOP2
INNER
	CLRWDT
	NOP
	NOP
	NOP
	NOP
	NOP
	DECFSZ	LOOP2, F	; decrement and leave result in LOOP2 
				; skip next statement if zero
	GOTO INNER
	DECFSZ 	LOOP1, F
	GOTO OUTTER
	RETURN

DELAY_10USEC:	; provides a delay equal to W * 10 usecs
	MOVWF LOOP1
DELAY_10USEC_1:
	CLRWDT
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	DECFSZ LOOP1, F
	GOTO DELAY_10USEC_1
	RETURN

	END