; Program 1820_2.asm
;
; Reads 64-bit address from DS1820, saves to DATA_BUFF1 and displays it
; on serial LCD.
;
; Uses 64-bit address to perform temperature measurement.  Data is saved
; to DATA_BUFF2 and displayed.
;
; After a 30 second delay, the process repeats.
;
; 16C84				                     DS1820		
; PortB.0 (term 6) ------------------------------ DQ (term 2)
;
; PORTA, Bit 1 (terminal 18) ------ TX ----------> to RX on Serial LCD
;
; Note that LCD_CTRL is included near the end of this program.
;
; copyright, H. Paul Roach, MSU, 15 July, '97
	
	LIST p=16c84
#include <c:\mplab\p16c84.inc>	
	__CONFIG 11h

	CONSTANT DATA_PIN=0

	CONSTANT BASE_VAR=0C

	CONSTANT DATA_BUFF1=18H	; serial number
	CONSTANT DATA_BUFF2=20H	; temperature data
	CONSTANT BUFF_SIZE1=8
	CONSTANT BUFF_SIZE2=7


N		EQU BASE_VAR+0

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

; DATA_BUFF1 is 8 bytes Serial Number

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

	
	ORG 000H	        ; program code to start at 000H

MAIN:
 	CALL	LCD_CLR

	CALL	INIT
       	CALL	READ_ROM        ; read and save 64 bit serial number
	CALL	DISPLAY1	; display it on line 1 of serial LCD


        CALL	INIT		; now use it for addressing	
        CALL	MATCH_ROM
	CALL	START_TEMP_CONV	; start a temeprature conversion
        CALL	WAIT		; wait for temperature conv to complete

	CALL	INIT
	CALL	MATCH_ROM       ; match 64 bit address code
	CALL	READ_TEMP             
	
	CALL	DISPLAY2	; display the data on line 2 of LCD

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

        GOTO	MAIN		; do it again

DISPLAY1:	; display from DATA_BUFF1 on Line 1 of serial LCD	
	
	CALL LCD_LINE1

	MOVLW DATA_BUFF1	; now read from buffer and display
	MOVWF FSR		
	MOVLW BUFF_SIZE1
	MOVWF N
DISPLAY1_1:
	MOVF INDF, W		; fetch the data byte from the buffer
	CALL LCD_VAL		; display it
	MOVLW " "			
	CALL LCD_CHAR		; send a space
	INCF FSR, F
	DECFSZ N, F
	GOTO DISPLAY1_1
      
	RETURN

DISPLAY2:	; display from DATA_BUFF2 on Line 2 of serial LCD	
	
	CALL LCD_LINE2

	MOVLW DATA_BUFF2	; now read from buffer and display
	MOVWF FSR		
	MOVLW BUFF_SIZE2
	MOVWF N
DISPLAY2_1:
	MOVF INDF, W		; fetch the data byte from the buffer
	CALL LCD_VAL		; display it
	MOVLW " "			
	CALL LCD_CHAR		; send a space
	INCF FSR, F
	DECFSZ N, F
	GOTO DISPLAY2_1
      
	RETURN

READ_TEMP:            		; read from scratch pad and save to memory
	MOVLW	0BEH		
        MOVWF	O_BYTE
        CALL	OUT_BYTE

        CALL	IN_BYTE
        MOVWF   TEMP_LSB

        CALL	IN_BYTE
        MOVWF   TEMP_MSB

        CALL	IN_BYTE
        MOVWF   TH_UB1

        CALL	IN_BYTE
        MOVWF   TL_UB2

        CALL	IN_BYTE		; throw these two away
        CALL	IN_BYTE

        CALL	IN_BYTE
        MOVWF	COUNT_REM

        CALL	IN_BYTE
        MOVWF   COUNT_D_C

        CALL	IN_BYTE
        MOVWF   CRC 
        
	RETURN

START_TEMP_CONV:
        MOVLW	44H     	; temperature conversion
        MOVWF	O_BYTE
        CALL	OUT_BYTE
	RETURN

READ_ROM:
	MOVLW	33H 
        MOVWF	O_BYTE
        CALL	OUT_BYTE
        
	MOVLW DATA_BUFF1	; fetch 8 bytes from 1820 
				; and save at DATA_BUFF1
	MOVWF FSR		
	MOVLW BUFF_SIZE1
	MOVWF N

READ_ROM_1:
	CALL IN_BYTE		; fetch the byte
	MOVWF INDF
	INCF FSR, F
	DECFSZ N, F
	GOTO READ_ROM_1

        RETURN

MATCH_ROM:
	MOVLW 	55H
	MOVWF O_BYTE
	CALL OUT_BYTE

	MOVLW DATA_BUFF1	; read 64-bit serial number 
				; from buffer and output
	MOVWF FSR		
	MOVLW BUFF_SIZE1
	MOVWF N
MATCH_ROM_1:
	MOVF INDF, W		; fetch the data byte from the buffer
	MOVWF O_BYTE		; and output to 1820
	CALL OUT_BYTE
	INCF FSR, F
	DECFSZ N, F
	GOTO MATCH_ROM_1
      
	RETURN

; The following are common 1-Wire routines used in all applications
	
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

WAIT:        
        CALL 	IN_BYTE
        MOVLW 	0FFH
        SUBWF 	I_BYTE, W
        BTFSS 	STATUS, Z
        GOTO 	WAIT
	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	PORTB, 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

        MOVFW	I_BYTE		; 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	STATUS, RP0
        BSF	TRISB, DATA_PIN		; high impedance
        BCF	STATUS, RP0
        
        RETURN

PIN_LO:
	BCF	PORTB, DATA_PIN
	BSF	STATUS, RP0
        BCF	TRISB, DATA_PIN		; low impedance zero
        BCF	STATUS, RP0
        
        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
	NOP
	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_100USEC_1:
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	DECFSZ LOOP1, F
	GOTO DELAY_10USEC_1
	RETURN

#include <a:\lcd\lcd_ctrl.asm>

	END