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 . 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