PC Parallel Port Interfacing with DS1620 Digital Thermometer / Thermostat

copyright, Locksley Haynes, Dept of Electrical Engineering,
Morgan State University, Baltimore, MD, May 7, '97

Introduction.

This discussion focuses on the Dallas Semiconductor DS1620 3-wire Thermometer / Thermostat. A data sheet in .pdf format is available at Dallas Semiconductor's home page; http://www.dalsemi.com. The device is available from a number of vendors including Newark and Jameco. Typical pricing is $6.00 in single unit quantities. We offer it for $5.00.

Three routines are presented. Program T_1620_1.C illustrates how to perform repeated measurements. Program T_1620_2.C illustrates various operations related to the thermostat and T_1620_3.C shows how the resolution of the device may be improved to 0.03 degrees C.

Program T_1620_1.C.

Note that PC Parallel Port Data Port bits 0 and 1 are used to control the states of the /RESET and CLK leads. These are manipulated using functions rst_high(), rst_low(), clk_high() and clock_low().

Data is sent and received to the 1620 using Control Port bit 0. A bit is sent using function out_bit(). Note that Control Port bit 0 is brought to the state of variable "bit" and the clock is brought momentarily low. Recall that there is a hardware inversion associated with bit 0 on the Control Port. Thus, "bit" is inverted using the exclusive or function to compensate for this inversion.

Eight bit commands are written to the device using function write_command(). Each bit, beginning with the least significant bit is output using function outbit().

The nine bit result is read using function read_data(). Output /STROBE on the Control Port is first brought high causing a high impedance at the output. Each bit is read, beginning with the least significant bit, by bringing clock low, reading the state of the /STROBE lead and then bringing clock high.

Note that in main, the /RST is first brought low, resetting the device. Clock is brought high and the /RST is brought high, thus beginning the sequence.

The command sequence to set the DS1620 configuration register to CPU mode (0x0C followed by 0x02) are then transmitted to the device and /RST is brought low to terminate the exchange.

The start convert (0xee) and stop convert (0x22) commands are designed to avoid a needless dissipation of power when the device is not needed to actually perform temperature conversions.

Thus, the command 0xee is sent to the 1620 to initiate the measurement sequence.

Ten temperature measurements are then made by first sending the request for reading (0xaa) followed by the nine bit read.

The device is then returned to the low power mode by sending the command to stop conversions (0x22).

/* Program T_1620_1.C
**
** Dallas Semiconductor DS1620 Digital Thermometer and Thermostat 
**
** Illustrates how to make continuous temperature measurements. 
**
** /STROBE 1 <----------------> DQ  1
** Data_1  3  ----------------> CLK 2
** Data_0  2  ----------------> RST 3
**
** Configure status register programmed for CPU operation. 
** Conversion started and 10 temperature measurments performed. 
** Conversion halted to save power.
** 
** copyright, Locksley Haynes, Morgan State University, Feb 17, '97 
*/

#include <stdio.h>
#include <dos.h>
#include <conio.h>

#define DATA 0x0378
#define STATUS DATA+1
#define CONTROL DATA+2

/*  DS1620 Commands */
#define CONF_REG 0x0c
#define READ_TEMP 0xaa
#define START_CONVERT 0xee
#define STOP_CONVERT 0x22

/* Function Prototypes*/

void write_command(int command);
void out_bit(int bit);
int read_raw_data(void);
float convert_to_T_F(int raw_data);

void clk_high(void);
void clk_low(void);
void rst_high(void);
void rst_low(void);

int data=0x00;  /**Global variable**/

main()
{
   int raw_data, n;
   int configure=0x02;
   float T_F;

   clrscr();

   rst_low();

   clk_high();
   rst_high();
   write_command(CONF_REG); /* configure DS1620 in CPU Mode */      
   write_command(configure);
   rst_low();
   delay(200);  /* wait for programming of configuration status register
*/ 
   clk_high();
   rst_high();
   write_command(START_CONVERT);   /* start converting temp*/    
   rst_low();
   delay(200);

   for(n=0; n<10; n++) /* Make 10 measurments, spaced by 10 secs */    
   {
      clk_high();
      rst_high();
      write_command(READ_TEMP);    /*command to 1620 for reading temp*/      
             raw_data=read_raw_data();        /*read raw temp data */       
             rst_low();

      T_F=convert_to_T_F(raw_data);

      printf("The temperature is %f degrees fahrenheit.\n\n", T_F);    
            sleep(10);
   }

   clk_high();
   rst_high();
   write_command(STOP_CONVERT); /* stop conversion to save power */    
   rst_low();
   /* done */
}

float convert_to_T_F(int raw_data)
{
  float T_F, T_celcius;
  if ((raw_data & 0x100) != 0)
  {
     raw_data = - (((~raw_data)+1) & 0xff); /* take 2's comp */   
  }
     T_celcius = raw_data * 0.5;
     T_F = (T_celcius * 1.8) + 32;
     return(T_F);
}

void write_command(int command)
/* sends 8 bit command on /STROBE output, least sig bit first */ 
{
  int n, bit;

  for(n=0;n<8;n++)
  {
    bit = ((command >> n) & (0x01));
    out_bit(bit);
  }
}

int read_raw_data(void)
{
  int bit,n;
  int raw_data=0;

  outportb(CONTROL,0x01 ^ 0x01);       
     /* jam the /strobe lead high to use as input */
  for(n=0;n<9;n++)
  {
     clk_low();
     bit=(inportb(CONTROL) ^ 0x01) & 0x01;
     clk_high();
     raw_data = raw_data | (bit <<  n);
  }
  return(raw_data);
}


void out_bit(int bit)
/* state of /STROBE set to value of bit, followed by clock pulse */ 
{
  outportb(CONTROL, bit^0x01);  /* set up the data */
  clk_low();             /* and then provide a clock pulse */   
  clk_high();
}

void clk_high(void)
{
  data = 0x03;
  outportb(DATA,data);
}

void clk_low(void)
{
  data = 0x01;
  outportb(DATA,data);
}

void rst_high(void)
{
   data = data | 0x01;
   outportb(DATA,data);
}

void rst_low(void)
{
   data = data & (~0x01);
   outportb(DATA,data);
}

Program T_1620_2.C.

This program illustrates how to set and read the high and low thermostat temperature thresholds and to then scan the configuration word to detect whether one of the limits was tripped.

Note that in the previous program, all commands and data sent to the 1620 was eight bits. Thus function write_command() was written to send eight bits. Similarly, all data reads in the previous program consisted of nine bit temperature readings and function read_raw_data was written for a fixed loop of nine.

However, in this program, commands are eight bits, but the thermostats settings are nine bits. Thus, the function write_command() has been modified to allow passing the number of bits to the function. Similalry, in reading the configuration register, an eight bit read is required. Thus, function read_raw_data has been modified to allow passing the number of bits.

In the program, the device is reset and the configuation byte is configured for CPU operation by sending 0x0c followed by 0x02. Note the number of bits is eight and this is passed to the function write_command().

The command to set the high thermostat setting (0x01) is sent followed by the nine bit represention of the setting. Note that the setting is a nine bit two's compliment representation of 2* T_celcius.

The command to set the low thermostat setting (0x02) is also sent followed by the nine bit representaion of the low trip point.

[The two set point temperatures are also read using either the 0xa1 (high temp) or 0xa2 (low temp) commands followed by a nine bit read. This might be done as a verification after writing the trip points].

The device is then commanded to start conversion (0xee).

Discussion of Thermostat Operation.

In the program the set points were set to 36 and 19 degrees C. If the ambient is now between these, both the temperature high flag (THF) and TLH bits of the configuration register are at zero. In addition, the DS1620 thermostat outputs, T_H, T_L and T_COM are all at logic zero.

If the ambient temperature now rises above the high temperature, the THF bit is set and outputs T_H and T_COMM go high. When the temperature falls below the high threshold, say 30 degrees C, the T_H output returns to a logic zero. However, the T_COM output remains at a logic one. When the temperature falls below the low threshold, the TLF bit is set, output T_L goes high and T_COM goes low.

That is, the THF and TLF bits are set whenever the temperature rises above the high threshold or goes below the low threshold and they remain set until the processor resets them. Output T_H goes high and remains high only when the temperature is above the high threshold. Output T_L goes high and remains low only when the temperature is below the low threshold. Output T_COM goes high when the temperature rises above the high threshold and it remains high until the temperature goes below the low threshold.

Continuation of Discussion.

In this program, the configuration word is read by first sending the 0xac command followed by an 8-bit read. Bits 6 (THF) and 5 (TLF) are checked to dtermine if the temperature has exceeded the high threshold or dropped below the low threshold. This is repeated 10 times.

Note that the program itself may not be all that practical. However, the intent is to show the user how to use the varous features.

/* Program T_1620_2.C
**
** Dallas Semiconductor DS1620 Digital Thermometer and Thermostat 
**
** Illustrates how to use thermostatic controls.
**
** /STROBE 1 <----------------> DQ  1
** Data_1  3  ----------------> CLK 2
** Data_0  2  ----------------> RST 3
**
** Configure status register programmed for CPU operation. 
** Set high temperature trigger.
** Read value set in high temperature trigger.
** Set low temperature trigger.
** Read value set in low temperature trigger.
** Conversion started and status register is read.
** High temperature flag bit is checked.
** Low temperature flag bit is checked.
** Conversion halted.
**
** copyright, Locksley Haynes, Morgan State University, Feb 17, '97 
*/

#include <stdio.h>
#include <dos.h>
#include <conio.h>

#define DATA 0x0378
#define STATUS DATA+1
#define CONTROL DATA+2

/***************************** Constants ***************************/ 
#define EIGHT 8
#define NINE 9

/************************ DS1620 Commands **************************/ 
#define CONF_REG 0x0c
#define READ_STATUS 0xac
#define READ_HIGH 0xa1
#define SET_HIGH 0x01
#define READ_LOW 0xa2
#define SET_LOW 0x02
#define START_CONVERT 0xee
#define STOP_CONVERT 0x22

/************************ Function Prototypes **********************/ 
void write_command(int command, int number_of_bits);
void out_bit(int bit);
int read_raw_data(int number_of_bits);
float convert_to_T_F(int raw_data);
void check_high_flag(int raw_data);
void check_low_flag(int raw_data);
void clk_high(void);
void clk_low(void);
void rst_high(void);
void rst_low(void);

/********************** Global Variable *******************************/ 
int data=0x00;

/************************** Main Program ******************************/ 
main()
{
   int high,low,raw_data,n;
   int configure=0x03;
   float T_F;

   clrscr();

   high=2*36;   /* (0x48) high temp trigger set to 36 degs C (96 degs F).
*/    
   low=2*19;    /* (0x26) low temp trigger set to 19 degs C (66 degs F).
*/ 
   rst_low();
   clk_high();
   rst_high();            /*initiate communication with device */      
   write_command(CONF_REG,EIGHT); /* configure DS1620 in CPU Mode */    
   write_command(configure,EIGHT);
   rst_low();             /*terminate communication with device */    
   delay(200);  /* wait for programming of configuration status register
*/ 
   clk_high();
   rst_high();
   write_command(SET_HIGH,EIGHT);    /*set high temp trigger*/     
   write_command(high,NINE);         /*to value of high */    rst_low();
   delay(200);

   clk_high();
   rst_high();
   write_command(READ_HIGH,EIGHT);   /*read high temp trigger*/   
   raw_data=read_raw_data(NINE);     /*stored in device*/
   rst_low();

   T_F=convert_to_T_F(raw_data);  /*convert digital word to fahrenheit*/    
   printf("High temperature flag set at %f degrees fahrenheit.\n",T_F); 
   clk_high();
   rst_high();
   write_command(SET_LOW,EIGHT);   /*set low temp trigger to*/    
   write_command(low,NINE);        /*to value of low*/
   rst_low();
   delay(200);

   clk_high();
   rst_high();
   write_command(READ_LOW,EIGHT);   /*read low temp trigger*/   
   raw_data=read_raw_data(NINE);    /*stored in device*/
   rst_low();
   delay(200);

   T_F=convert_to_T_F(raw_data);
   printf("Low temperature flag set at %f degrees fahrenheit.\n\n",T_F); 
   clk_high();
   rst_high();
   write_command(START_CONVERT,EIGHT);   /* start converting temp*/      
   rst_low();
   delay(200);

   for(n=0;n<10;n++)
   {
      clk_high();
      rst_high();
      write_command(READ_STATUS,EIGHT);   /* read status register*/       
      raw_data = read_raw_data(EIGHT);
      rst_low();

      check_high_flag(raw_data);   /*check high and low temp trigger*/      
      check_low_flag(raw_data);    /*from 8 bit value read from status
register.*/

      sleep(20);  /*check again in 20 seconds */
  }

  clk_high();
  rst_high();
  write_command(STOP_CONVERT,EIGHT);   /* stop converting temp*/   
  rst_low();
  delay(200);          /*wait 200 ms for eeprom to program*/ 
} /***end main **/

/*check_high_flag
**function definition
**This function checks value read from status register to see 
**if high temp flag is set(logic 1).
*/
void check_high_flag(int raw_data)
{
  int bit;

  bit = (raw_data >> 6) & 0x01;

  if(bit == 1)
    printf("High temp flag is set.\n");
  else
    printf("High temp flag is not set.\n");
}

/*check_low_flag
**function definition
**This function checks value read from status register to see 
**if low temp flag is set(logic 1).
*/
void check_low_flag(int raw_data)
{
  int bit;

  bit = (raw_data >> 5) & 0x01;

  if(bit == 1)
    printf("Low temp flag is set.\n\n");
  else
    printf("Low temp flag is not set.\n\n");
}

/*convert_to_T_F
**function definition
**This function converts a 9 bit digital word to temp fahrenheit. */
float convert_to_T_F(raw_data)
{
  float T_F, T_celcius;

  T_celcius = raw_data * 0.5;
  T_F = (T_celcius * 1.8) + 32;
  return(T_F);
}

/*write_command
**function definition
**This function writes a specified number of bits on /STROBE output. */
void write_command(int command,int number_of_bits)
{
  int n, bit;

  for(n=0;n> n) & (0x01));
    out_bit(bit);
  }
}

/*read_raw_bits
**function definition
**This function reads a speicified amount of bits via the /STROBE 
**lead.
*/
int read_raw_data(int number_of_bits)
{
  int bit,n;
  int raw_data=0;

  outportb(CONTROL,0x01^0x01);
         /* jam the /strobe lead high to use as input */
  for(n=0;n<number_of_bits;n++)
  {
     clk_low();
     bit=(inportb(CONTROL) ^ 0x01) & 0x01;
     clk_high();
     raw_data = raw_data | (bit <<  n);
  }
  return(raw_data);
}

/*out_bit
**function definition
**This function sets the state of /STROBE lead to the value 
**of bit, followed by a clock pulse.
*/
void out_bit(int bit)
/* state of /STROBE set to value of bit, followed by clock pulse */ 
{
  outportb(CONTROL, bit^0x01);  /* set up the data */
  clk_low();             /* and then provide a clock pulse */   
  clk_high();
}

/*clk_high
**function definition
**This function set the clock lead high via /DATA1
*/

void clk_high(void)
{
  data = data | 0x02;
  outportb(DATA,data);
}

/*clk_low
**function definition
**This function set the clk lead low via /DATA1
*/
void clk_low(void)
{
  data = data & (~0x02);
  outportb(DATA,data);
}

/*rst_high
**function definition
**This function set the reset lead high via /DATA0
*/
void rst_high(void)
{
   data = data | 0x01;
   outportb(DATA,data);
}

/*rst_low
**function definition
**This function set the reset lead low via /DATA0
*/
void rst_low(void)
{
   data = data & (~0x01);
   outportb(DATA,data);
}

Program T_1620_3.C

This program illustrates how the resolution of the temperature may be improved to 0.03 degrees C by using additional commands that were not documented in the original DS1620 data sheet.

The program follows T_1620_1.C in sending the read temperature (0xaa) command followed by a nine bit read. This is T_read.

The value of a counter may be read by sending the read counter command (0xa0) followed by a nine bit read. This is count_remain. The value of a the slope accumulator may be read by sending the read_slope command (0x41), followed by a nine bit read. This is count_per_c.

The resulting temperature is then;

     T_C = 0.5 * raw_data - 0.25

         + (counter_per_c - count_remain) / (count_per_c)

[I have no idea how adaptable this is to negative temperature values.]

Note that all functions used in this program are the same as program T_1620_1.C.

/* Program T_1620_3.C
**
** Dallas Semiconductor DS1620 Digital Thermometer and Thermostat 
**
** Illustrates how to make temperature measurements with .1 degrees
accuracy. 
**
** /STROBE 1 <----------------> DQ  1
** Data_1  3  ----------------> CLK 2
** Data_0  2  ----------------> RST 3
**
** Configure status register programmed for CPU and 1SHOT operation. 
** Conversion started and a temperature measurements performed. 
** Counter value is measured.
** The slope is then loaded.
** Counter value is measured again.
** Conversion halted.
**
** copyright, Locksley Haynes, Morgan State University, Feb 17, '97 
*/

#include <stdio.h>
#include <dos.h>
#include <conio.h>

#define DATA 0x0378
#define STATUS DATA+1
#define CONTROL DATA+2

/*************************** DS1620 Commands *************************/ 
#define CONF_REG 0x0c
#define READ_TEMP 0xaa
#define START_CONVERT 0xee
#define STOP_CONVERT 0x22
#define READ_COUNTER 0xa0
#define READ_SLOPE 0x41

/***************************** Function Prototypes ******************/ 
void write_command(int command);
void out_bit(int bit);
int read_raw_data(void);
float convert_to_T_F(float raw_data);
void clk_high(void);
void clk_low(void);
void rst_high(void);
void rst_low(void);

/***************************** Global Variable ***********************/ 
int data=0x00;

/*******************************Main Program *************************/ 
main()
{
   int raw_data, n,count_remain,count_per_c;
   int configure=0x03;
   float T_F,T_C;

   clrscr();

   clk_high();
   rst_high();              /*initiate communication with DS1620*/    
   write_command(CONF_REG); /* configure DS1620 in CPU Mode */   
   write_command(configure);
   rst_low();               /*terminate communication with DS1620*/    
   delay(200);  /* wait for programming of configuration status register
*/ 
   for(n=0;n<10;n++)
   {
     clk_high();
     rst_high();
     write_command(START_CONVERT);   /* start converting temp*/      
     rst_low();
     delay(200);

     clk_high();
     rst_high();
     write_command(READ_TEMP);    /*command to 1620 for reading temp*/        
     raw_data=read_raw_data();       /*read raw temp data */      
     rst_low();

     clk_high();
     rst_high();
     write_command(READ_COUNTER);     
                   /*read value remaining in counter*/     
     count_remain=read_raw_data();
     rst_low();

     clk_high();
     rst_high();
     write_command(READ_SLOPE);    
                  /*load counter with value of slope accumulator */      
     rst_low();                    
     delay(200);

     clk_high();
     rst_high();
     write_command(READ_COUNTER);
     count_per_c=read_raw_data();  /*read value of slope
                                           accumulator*/      
     rst_low();                    /*from the counter*/


     T_C=(raw_data*0.5) - 0.25
          + ((count_per_c - count_remain)/(float)count_per_c);      
     T_F=convert_to_T_F(T_C);

     printf("The temperature is %f %f degrees C F.\n\n", T_C, T_F); 
     sleep(10);
   }

   clk_high();            /*stop temp conversion.*/
   rst_high();
   write_command(STOP_CONVERT);
   rst_low();
}

/*Note that the functions are the same as in Program T_1620_1.C */ 

 
Onlinecasiniosrooms offers an inclusive online gambling guide database. . http://www.rus-women.com - dating site, whete russian women looking for men from USA and Europe.