Interfacing the BASIC STAMP 2 with the DS1621 Thermometer

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

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 Dallas Semiconductor. Devices are avaiable from Newark Electronics 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