
Introduction
This discussion shows how to interface a Dallas Semiconductor DS1621 Thermometer with the Basic Stamp BS2.
The DS1621 is not to be confused with the 1620. Although both have the same capabilities, the 1620 uses a three wire protocol. The 1621 uses the 2-Wire Inter IC (I2C) protocol. This permits networking up to eight 1621 devices along with other I2C devices on the same two signal leads.
Resources
A data sheet is available in Adobe .pdf format from . Devices are avaiable from for about $4.00 each.
Discussion
The following discussion is in rough form. It will be reworked and eventually it will become a part of a new book which discuuses interfacing with serial devices. But, in the interim, you may find it useful.
Program DS1621_1.BS2 assumes there is a single device at A2A1A0 address 1. The program illustrates how to write to the configuration register, start temperature conversions, read the temperature from the device and stop the temperature conversions so as to save power when temperature readings are not required.
The configuration register is configured in subroutine config_1621 by writing the command $0c followed by the data $02 to configure the 1621 in a CPU controlled mode with continuous temperature conversion. The temperature conversion process is then initiated in subroutine start_convert with the $ee command. Readings are then made in subroutine meas by sending the $aa command and then reading the nine bits from the 1621. After ten readings, the loop is exited and the conversion process is halted using subroutine stop_convert by sending the command $22.
My handling of the conversion to temperature by simply dividing the nine bits received from the 1621 by 2 is clumsy as it sacrifices the 0.5 resolution.

' DS1621_1.BS2
'
' Illustrates how to measure temperature using DS1621 2-W I2C
'
' BS2 DS1621
'
' Pin5 (term 10) ------------------- SCL (term 2) ----- To Other
' Pin4 (term 9) -------------------- SDA (term 1) ----- 24LC32 Devices
'
' Note that 10K pullup resistors to +5VDC are required on both signal
' leads.
'
' Note that the slave address is determined by A2 (term 5), A1 (term 6)
' and A0 (term 7 on DS1621. The above SCL and SDA leads may be multipled
' to eight devices, each strapped for a unique A2 A1 A0 setting.
'
' Debug and Pause statements were included only to see what is going on.
'
'
' copyright Towanda L. Malone, MSU, March 13, '97
device var byte ' device 0-7
o_byte var byte ' byte to send to ds1621
i_9_bit var word ' 9 bit reading fetched from 1621
T_C var byte ' Temperature in degrees C
n var byte ' index
b var bit ' bit
times var byte ' number of measurements
ack_bit var bit
SDA_PIN con 4
SCL_PIN con 5
SDA_OUT var out4
SCL_OUT var out5
SDA_IN var in4
SDA_DIR var dir4
OUT con 1
IN con 0
dirs=$f0ff
main
device=1 ' note A2=0, A1=0, A0=1
gosub config_1621 ' write to $02 configuration register
gosub start_convert ' write start convert to DS1621
for times = 0 to 9 ' 10 measurements
gosub meas
T_C = i_byte/2 ' sacrifice some accuracy
debug dec T_C
pause 2000
next
gosub stop_convert ' stop continuous conversion
stop
config_1621 'configure device 1
gosub start
o_byte = $90 | (device<<1) ' 1001 a2 a1 a0 0
gosub out_byte
gosub nack
o_byte = $ac ' config as CPU control, continuous
gosub out_byte
gosub nack
o_byte = $02
gosub out_byte
gosub nack
high SCL_PIN
gosub sstop
return
start_convert ' send $ee to start continuous conversion
gosub start
o_byte = $90 | (device<<1)
gosub out_byte
gosub nack
o_byte = $ee
gosub out_byte
gosub nack
high SCL_PIN
gosub sstop
return
meas ' sends read temperature command
' value fetched from DS1621 return in i_9_bit
gosub start
o_byte = $90 | (device<<1) ' note this is a write
gosub out_byte
gosub nack
o_byte = $aa ' command to read temperature
gosub out_byte
gosub nack
gosub start ' note there is no stop
o_byte = $90 | (device<<1) | $01 ' now a read
gosub out_byte
gosub nack
gosub get_9_bits
high SCL_PIN
gosub sstop
return
stop_convert ' send command $22 to stop the continuous conversion
gosub start
o_byte = $90 | (device<<1)
gosub out_byte
gosub nack
o_byte = $22
gosub out_byte
gosub nack
high SCL_PIN
return
out_byte ' shift out o_byte beginning with most sig bit
low SDA_PIN
for n=0 to 7
b= (o_byte >> 7) & 1
if (b=1) then out_one
SDA_DIR=OUT
debug "0"
_clk
high SCL_PIN
pause 100
low SCL_PIN
pause 100
o_byte=o_byte << 1
next
SDA_DIR=IN
return
out_one
SDA_DIR=IN
debug "I"
goto _clk
get_9_bits ' read 9 bits from DS1621, most sig bit first
SDA_DIR=IN 'input
i_9_bit=0
for n=0 to 8
pause 200
high SCL_PIN ' clock high, then read SDA, then clock low
pause 200
i_9_bit=(i_9_bit << 1) | SDA_IN
debug dec SDA_IN
low SCL_PIN
next
SDA_DIR=OUT 'output
return
nack
SDA_DIR=IN ' input just in case
ack_bit=1
high SCL_PIN
ack_bit=SDA_IN
debug "A"
debug dec ack_bit
debug $0d
low SCL_PIN
SDA_DIR=OUT ' output
return
ack
debug "POLL"
gosub start
o_byte=$a0 | (device << 1)
gosub out_byte
gosub nack
return
start
high SDA_PIN
high SCL_PIN
debug "START"
debug $0d
low SDA_PIN 'bring SDA low while clock is high
low SCL_PIN
return
sstop
low SDA_PIN
high SCL_PIN
pause 10
high SDA_PIN 'bring SDA high while clock is high
debug "STOP"
debug $0d
return