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