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