
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
