;
; The Dallas Semi DS1820 digital Thermometer
;
; This part is *the* answer for 90% of all temperature
; measurement problems.  It comes in a 3 pin transistor
; style package (that's Vcc, Gnd & DataI/O), it's very low
; power, accurate, has half a degree C resolution, is easy
; to use, reads out directly in 9 bit binary degrees C
; and is extendable to any number of sensors on a
; 2 or 3-wire bus.  Its not a cheap part but then it isn't
; expensive either and if you talk nicely to Dallas they'll
; give you a sample.
;
; The interface is half-duplex serial and uses only *one*
; of your PIC's valuable IO pins.  The code that follows
; is a minimal implementation for just reading the temp-
; erature from a single DS1820 device.  More complex code
; would be required to read from multiple devices on a
; 2/3 wire bus, but this will get you started.
;
; BTW the chip also includes a little dollup of EEPROM.
;
; The part's data sheet is available from the Dallas web
; page: http://www.dalsemi.com
;
; Enjoy.  (As they say)

; --------------------------------------------------------

	;	DS1820 support for PIC16C84

	;	NOTE - This code assumes that the default
	;	radix is set to Decimal
	;
	;	Requires DS1820 DQ pin connected to PORTA
	;	on pin DSBIT (DSBIT may be in the range 0..4)
	;	My hardware runs with DSBIT EQU 3
	;	Requires TMP0,1 & 2 temporary working files.
	;	Results are stored in DSSIGN and DSMAG files.
	;	DSSIGN is 0 if temp is +ve, FF if temp -ve.
	;	DSMAG contains the 8 bit temperature reading
	;	LSB = .5 degrees C, see Dallas Data Sheet.
	;	Just call NEWTEMP every time round in your
	;	main loop and test the W reg to see if
	;	new data is available.
	;	NOTE parts of this code are timing critical
	;	and must be run with INTERRUPTS turned OFF!
	;	see the INTSON and INTSOFF macros below.

NEWTEMP:

	;	Returns W<>0 if no new data ready yet
	;	or W=0 if a new measurement has been made
	;	Data will be saved to DSSIGN & DSMAG
	;	TMP0..2 will be destroyed
	;	Return W=0 if reading is OK
	;	or W=1 if an error is encountered.
	;	NOTE in this case DSMAG and DSSIGN will
	;	     be in an undefined state
	;
	CALL	DSRX8		; CHECK DS1820 STATUS
	ADDLW	1		; 255=READY => 0=READY
	BTFSS	STATUS,Z	; Z set = READY
	RETURN			; W non zero = not ready

	;	Get current temperature reading
	;	and start the next conversion

GETEMP:	CALL	DSRESET
	BTFSS	STATUS,Z	; Z BIT SET MEANS RESP. OK
	GOTO	BADTMP
	MOVLW	H'CC'		; SKIP PROM
	CALL	DSTX8
	MOVLW	H'BE'		; READ SCRATCH PAD
	CALL	DSTX8
	CALL	DSRX8		; MAGNITUDE
	MOVWF	DSMAG
	CALL	DSRX8		; SIGN (FF=-VE, 00=+VE)
	MOVWF	DSSIGN
	CALL	DSRESET		; SEEN ENOUGH, RESTART
	MOVLW	H'CC'		; SKIP PROM
	CALL	DSTX8
	MOVLW	H'44'		; START CONVERT
	CALL	DSTX8

	;
	;	IF DSSIGN NOT 255 OR 0 THEN ERROR
	;

	MOVF	DSSIGN,W
	BTFSC	STATUS,Z
	GOTO	OKTMP
	ADDLW	1
	BTFSS	STATUS,Z
	GOTO	BADTMP
OKTMP:
	CLRW			; W = 0 : DATA READY
	RETURN
BADTMP:
	MOVLW	1		; W <> 0 : ERROR
	RETURN
	

; ---------------------------------------------------------

	;	DS1820 MACROS


INTSON:	MACRO
	;
	;	TURN YOUR INTERRUPTS OFF HERE
	;
	ENDM


INTSOFF:MACRO
	;
	;	TURN YOUR INTERRUPTS BACK ON HERE
	;
	ENDM


DQLOW:	MACRO
	BCF	PORTA,DSBIT	; DQ BIT READY LO
	BSF	STATUS,RP0
	BCF	TRISA,DSBIT	; DQ BIT NOW O/P
	BCF	STATUS,RP0
	ENDM


DQHIZ:	MACRO
	BSF	STATUS,RP0
	BSF	TRISA,DSBIT	; DQ BIT NOW I/P
	BCF	STATUS,RP0
	ENDM


PAUSE:	MACRO	DLYF
	MOVLW	(DLYF / 5) - 1
	MOVWF	TMP0
	CALL	DLY5N
	ENDM


; ------------------------------------------------------------

	;	DS1820 SUBROUTINES


DLY5N:	NOP
	NOP
	DECFSZ	TMP0
	GOTO	DLY5N
	RETURN



DSRESET:
	;	DESTROYS TMP0,1
	;	RETURNS 0 IN W IF VALID RESPONSE
	;
	DQLOW
	PAUSE	600
	INTSOFF
	DQHIZ
	PAUSE	65		; WAIT 67us FOR RESP BIT
	NOP
	NOP
	MOVF	PORTA,W
	INTSON
	ANDLW	1 << DSBIT
	MOVWF	TMP1
	PAUSE	300
	MOVF	TMP1,W		; RESPONSE IN W
	RETURN



DSTX8:	MOVWF	TMP2		; DATA TO TX
	MOVLW	8
	MOVWF	TMP1		; LOOP COUNTER
DSTXLP:	INTSOFF
	DQLOW
	PAUSE	10
	RRF	TMP2
	BTFSC	STATUS,C
	BSF	PORTA,DSBIT	; DQ HI IF BIT WAS 1
	INTSON
	PAUSE	70
	DQHIZ
	NOP
	DECFSZ	TMP1
	GOTO	DSTXLP
	RETURN


DSRX8:	MOVLW	8
	MOVWF	TMP1
DSRXLP:	INTSOFF
	DQLOW
	PAUSE	10
	DQHIZ
	NOP
	NOP
	MOVF	PORTA,W
	INTSON
	ANDLW	1 << DSBIT	; ->0 IF DATA BIT LOW
	ADDLW	255		; C IF W > 0
	RRF	TMP2
	PAUSE	60
	DECFSZ	TMP1
	GOTO	DSRXLP
	MOVF	TMP2,W
	RETURN


; ---------------------------------------------------------


    Source: geocities.com/thaimcu/piccode

               ( geocities.com/thaimcu)