Interfacing the BASIC STAMP 2 with the DS1602 Elapsed Time Counter

copyright, Peter H. Anderson and H. Paul Roach
Dept of Electrical Enginnering, Morgan State University
March 21, '97


Introduction

This discussion shows how to interface a Dallas Semiconductor DS1602 Elapsed Time Counter with the Basic Stamp BS2.

The interface is three wire and the method of control is very similar to that used in interfacing with the DS1620.

Resources

A data sheet is available in Adobe .pdf format from Dallas Semiconductor. We sell the DS1602 in an 8-pin DIP and 32.768 kHz crystals.

Discussion

The 1602 contains two 32 bit counters which count the number of seconds. One counter, termed the continuous counter, increments from the time an external 2.5 V (min) battery is applied at terminal Vbat (term 5). The second, termed the V_cc counter, incr ements so long as the voltage at V_cc (term 8) is above nominally 4.25 volts. If the V_cc is lost, the V_cc counter ceases to count, but the current count is held by the battery source. The idea in having the V_cc counter is to monitor the amount of tim e the equipment is in actual operation. Thus, if the two counters are intitialized to 0 and a battery is applied when a piece of equipment is manufactured, the continuous counter may be used to determine the date of manufacture and the V_cc counter may b e used to determine the cumulative time the equipment has been in operation.

Note that 32 bits provides a capability for storing seconds for over 125 years.

The two counters may be individually cleared, read or written. Timing is facilitated using an external 32.768 kHz crystal connected to terminals X1 (term 7) and X2 (term 6).

Dallas is a very clever company. They even provide a programmable means of adjusting for a fast or slow crystal.

Program DS_1602_1.BS2 illustrates how to adjust the oscillator frequency, clear each counter and read from and write to each counter.


' DS1602_1.BS2
'
' Illustrates how to interface with DS1602 3-Wire Elapsed Time Counter
'
' BS2                                   DS1602
'
' Pin2 (term 7) -------------------- DQ (term 2)
' Pin1 (term 6) -------------------- CLk (term 3) 
' Pin0 (term 5) -------------------- RST (term 1) 
'
' 
' Debug statements were included only to see what is going on.
'
' 
' copyright Peter H. Anderson, MSU, March 21, '97
'

        o_byte var byte		' byte sent to DS1602
        
        i_byte var byte		' temp data from 1602

	hi_count var word	' high 16 bits
	lo_count var word	' low 16 bits

	osc_trim var byte	' 0-7, 0 stops, 7 is fastest clock

        n var byte		' index
        
	counter var bit		' used to identify either continuous
				' or V_cc counter

        dirs = $f0ff

        IN con 0                 
        OUT con 1		                 

        RST con 0
        CLK con 1
        DQ con 2

	CONT_CNTR con 0
	V_CC_CNTR con 1
	        
        DQ_OUT var out2
	DQ_IN var in2
        DQ_DIR var dir2           

main   
	osc_trim = $3
	gosub set_osc_trim	' adjust oscillator trim to nominal

	counter=CONT_CNTR	' clear continuous counter
	gosub clear_counter 	 

	counter=V_CC_CNTR	' clear V_cc counter
	gosub clear_counter

	sleep 60		' pause for a minute

	counter=CONT_CNTR	' read and display count from continuous
	gosub read_counter	' counter
	debug hex hi_count lo_count

	sleep 60		' wait some more time to let counter count

	counter=V_CC_CNTR	' read and display count from V_cc counter
	gosub read_counter
	debug hex hi_count lo_count

	hi_count = $0123
	lo_count = $4567

	counter=CONT_CNTR	' write a value to each counter
	gosub write_counter     

	hi_count = $7654
	lo_count = $3210

	counter=V_CC_CNTR
	gosub read_counter   

	sleep 60		' pause for a minute

	counter=CONT_CNTR	' read and display count from continuous
	gosub read_counter	' counter
	debug hex hi_count lo_count

	sleep 60		' wait some more time

	counter=V_CC_CNTR	' read and display count from V_cc counter
	gosub read_counter
	debug hex hi_count lo_count

	stop

set_osc_trim	' sets trim of osc to value contained in osc_trim

	gosub begin
	o_byte=$c0 | (osc_trim<<3)	' 11 OSC2 OSC1 OSC0 X X 0
	gosub out_byte
	gosub end
	return

clear_counter	' clears specified counter, $04 - continuous counter
					  ' $02 - V_cc counter
	gosub begin
        if counter=CONT_CNTR then clear_counter_l1
	o_byte=$02		
	goto clear_counter_l2
clear_counter_l1
	o_byte=$04
clear_counter_l2
        
        gosub out_byte 	' $04 if continuous counter, $02 if V_cc counter
        gosub end 
        return

write_counter	' writes 32 bits contained in hi_count and lo_count
		' to specified counter, beginning with least sig bit

	gosub begin
        if counter=CONT_CNTR then write_counter_l1
	o_byte=$40		
	goto write_counter_l2
write_counter_l1
	o_byte=$80
write_counter_l2
	gosub out_byte	' $80 - continuous counter, $40 - V_cc counter

	'now shift out 32 bits beginning with least significant bit
	o_byte=lo_count&$ff	' lo byte of lo word
	gosub out_byte
	o_byte=(lo_count>>8)&$ff' hi byte of lo word
	gosub out_byte
	o_byte=hi_count&$ff	' lo byte of hi word
	gosub out_byte
	o_byte=(hi_count>>8)&$ff' hi byte of hi word
	gosub out_byte
	
	gosub end
	return
        
read_counter	' reads 32 bits from specified counter
		' result placed in hi_count and lo_count

	gosub begin
        if counter=CONT_CNTR then read_counter_l1
	o_byte=$41		
	goto read_counter_l2
read_counter_l1
	o_byte=$81
read_counter_l2
	gosub out_byte	' $81 - continuous counter, $ 40 - V_cc counter

	'now shift in 32 bits beginning with least significant bit
	
	gosub get_byte
	lo_count=$(00<<8) | i_byte	'lo byte of lo word
	gosub get_byte
	lo_count=lo_count | (i_byte << 8) 'hi byte of lo word

	gosub get_byte
	hi_count=$(00<<8) | i_byte	'lo byte of hi word
	gosub get_byte
	hi_count=hi_count | (i_byte << 8) 'hi byte of lo word
	
	gosub end
	return        

out_byte                ' outputs byte in o_byte, beginning with least
			' significant bit
        DQ_DIR=OUT
        for n = 0 to 7
           DQ_OUT = o_byte & $01     'least significant bit
           low CLK                     
           debug dec DQ_OUT
	   high CLK                    
           o_byte = o_byte >> 1      'shift data 1 place right
        next
        debug 13
	return
  
get_byte		' reads 8 bits from 1602 beginning with least
			' significant bit
        DQ_DIR = IN
        i_byte = 0 
        for n = 0 to 7
           low CLK
           i_byte = (i_byte >> 1) | (DQ_IN << 7)
           debug dec D_IN
           high CLK
        next
	DQ_DIR=OUT
   	debug 13
        return

begin
	low RST
        high CLK
        high RST 	' initiate by bringing RST high
	return

end
	high CLK
	low RST
	return