Using the DS1820 EEPROM

copyright, Peter H. Anderson, Baltimore, MD, July, '98

Introduction.

The DS1820 thermometer includes two user EEPROM bytes.

The most obvious use of these is to customize a DS1820 as a thermostat device . For example, user byte 1 (UB1) might define a temperature which if exceeded causes a fan or air conditioning unit to turn on and user byte 2 as the temperature at which the fan is to be turned off. Note that the operation is a bit different than with some of the Dallas temperature units in that the DS1820 doesn't include the circuitry to provide for directly controlling the fan. Rather, the interfacing processor might read the temperature and compare the current temperature with that of the two user bytes which were previously programmed for the specific installation and either turn on, turn off or leave the fan in its current state.

However, the two EEPROM locations might be used for any number of applications where the PIC does not include onboard EEPROM. For example, we have designed systems to measure atmospheric pressure and used these two bytes to store the altitude constant to be used for converting the atmospheric pressure to that at sea level. Another example is a calibration constant for our 0-200 inch fluid measuring system. In both cases, it made sense to provide the user with the ability to measure temperature and the two bytes of user EEPROM enabled us to use the relatively inexpensive PIC16C558.

Details.

Program EEPROM.ASM illustrates how to write to and read from these two locations.

Note that the scratch pad associated with the DS1820 consists of nine locations; two for temperature, two user bytes, two reserved bytes and two bytes which may be used to extend the resolution of the temperature; counts remaining and counts per degree C and, a CRC byte.

In writing to EEPROM the "write scratch pad" command (4EH) is issued followed by the values of the two user bytes. Note that although the scratch pad consists of nine bytes, only two bytes associated with the two user bytes may be written by the user.

The two user bytes are then programmed using the "program EEPROM" command (48H). As the programming of the EEPROM requires more power than can be delivered by the +5 Volt supply through 4.7K, the DQ lead brought to a low impedance logic one for a minimum of 10 ms. This is implemented in the STRONG (as in strong pullup) routine.

Reading the EEPROM is a two step process of first transferring the content of EEPROM to the scratch pad (command B8H) and then reading the scratch pad (command BEH). Note that in reading the scatch pad, all nine bytes are read. In this routine, these were placed at nine locations beginning at address DATA_BUFF. The user bytes are then at locations DATA_BUFF+2 and +3.

Program EEPROM.ASM.


; EEPROM.ASM
;
; Ilustrates how to write to and read from the two user EEPROM locations
; on the Dallas DS1820.
; 
; For illustration 3FH and 4AH are written to the user EEPROM.  This is
; then read and displayed on the PIC-an-LCD using our library of LCD 
; routines.
;
; copyright, Towanda Malone, Baltimore, MD, July, '98


	LIST p=16c558
#include <p16c558.inc>
	__CONFIG 05H	; code protect on, power up timer on, 
			; watch dog timer on, XT osc

	CONSTANT DQ = 0  	; DS1820 is on PIC I/O RB.0

	CONSTANT BASE_VAR=20H
	CONSTANT DATA_BUFF=30H ; temperature data
      	CONSTANT BUFF_SIZE=9
      

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


UB1             EQU DATA_BUFF+2
UB2             EQU DATA_BUFF+3

MAIN:	
	CALL LCD_RESET

TOP:
	MOVLW	03FH		; dummy up some values
	MOVWF	UB1
	MOVLW	0A4H
	MOVWF	UB2
	
	CALL WRITE_EEPROM	; write the values to EEPROM

	CLRF	UB1		; clear the values to be sure 
	CLRF	UB2		; we aren't cheating

	CALL READ_EEPROM	; now read from EEPROM
                
	MOVF UB1, W             ; display the two values
	CALL LCD_VAL
	MOVLW " "
	CALL LCD_CHAR
	
	MOVF UB2, W
	CALL LCD_VAL  
	
DONE:	
	GOTO DONE

WRITE_EEPROM:
	CALL INIT
   
	MOVLW   0CCH		; skip rom            
	MOVWF   O_BYTE
	CALL    OUT_BYTE

WRITE_PAD:
	MOVLW   04EH            ; write to scratch pad
        MOVWF   O_BYTE
        CALL    OUT_BYTE

	MOVF    UB1, W		; the two values to write to EEPROM			            
        MOVWF   O_BYTE
        CALL    OUT_BYTE
	
	MOVF    UB2, W			            
        MOVWF   O_BYTE
        CALL    OUT_BYTE

	CALL INIT

	MOVLW   0CCH		; skip rom            
        MOVWF   O_BYTE
        CALL    OUT_BYTE

	MOVLW   048H            ; copy scratch pad into memory addresses
        MOVWF   O_BYTE		; 2 and 3 only.
        CALL    OUT_BYTE

	CALL 	STRONG		; 10 ms of strong pullup for burning the 
				; EEPROM
	RETURN

READ_EEPROM:
	CALL 	INIT
   
	MOVLW   0CCH		; skip rom            
        MOVWF   O_BYTE
        CALL    OUT_BYTE

	MOVLW   0B8H            ; recall values stored in memory 
        MOVWF   O_BYTE		; to scratch pad.
        CALL    OUT_BYTE
	
READ_PAD:                      ; read bytes from scratch pad 

	CALL 	INIT
	MOVLW 	0CCH
	MOVWF	O_BYTE
	CALL	OUT_BYTE
	
        MOVLW   0BEH          
        MOVWF   O_BYTE
        CALL    OUT_BYTE   
      
	MOVLW 	DATA_BUFF
        MOVWF 	FSR       
	MOVLW   .9
	MOVWF   N    
      
REPEAT:
      	CALL   	IN_BYTE         
	MOVWF	INDF
	INCF 	FSR, F
	DECFSZ  N, F
	GOTO	REPEAT
	RETURN
      
STRONG:
	BSF	PORTB, DQ
	BSF	STATUS, RP0
	BCF	TRISB, DQ
	BCF	STATUS, RP0

	MOVLW	.10
	CALL	LCD_DELAY

	BSF 	STATUS, RP0
	BSF	TRISB, DQ
	BCF	STATUS, RP0
	BCF	PORTB, DQ
	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

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, DQ
        BCF STATUS, C           ; its a zero
        BTFSC   TEMP, DQ
        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, DQ	         ; high impedance
        BCF     STATUS, RP0
        
        RETURN

PIN_LO:
        BCF     PORTB, DQ
        BSF     STATUS, RP0
        BCF     TRISB, DQ	         ; low impedance zero
        BCF     STATUS, RP0
        
        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_100USEC_1
        RETURN
        
#include <a:\lcd_f84.asm>

        END