Interfacing with a Dallas DS2401 1-W Serial Number



/* DS2401_1.C
**
** Interfaces with a Dallas DS2401 Silicon Serial Number.
** Displays 64-bit serial number.
**
** Also writes ID to a data file.  Reads from data file and displays.
**
** Flashlite               DS2401
**
** P2.7 -------------------- DQ
**
** Note that 4.7K pullups to +5 VDC are required on the DQ lead.
**
** copyright, Peter H. Anderson, Baltimore, MD, Sept, '00
*/

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

#define SEG 0xf000
#define P2_OFFSET 0xff10
#define PM2_OFFSET 0xff11
#define PMC2_OFFSET 0xff12

typedef unsigned char byte;

void _1w_init(byte sensor);
byte _1w_in_byte(byte sensor);
void _1w_out_byte(byte sensor, byte d);
void _1w_pin_hi(byte sensor);
void _1w_pin_low(byte sensor);
void _1w_strong_pull_up(byte sensor);

byte far *p2, *pm2, *pmc2;    /* note global */
FILE *f;

void main(void)
{
   byte sensor, n, id[8], id_2[8];
   float T_C;

   p2 = MK_FP(SEG, P2_OFFSET);
   pm2 = MK_FP(SEG, PM2_OFFSET);
   pmc2 = MK_FP(SEG, PMC2_OFFSET);

   *pm2 = 0xff;     /* all of port 2 are inputs */


   while(1)
   {
      sensor = 7;
      _1w_init(sensor);
      _1w_out_byte(sensor, 0x33);  /* request ID */

      for (n=0; n<8; n++)  /* fetch the 8 bytes */
      {
         id[n]=_1w_in_byte(sensor);
      }

      printf("\nSaving to data file\n");

      f = fopen("id.dta", "wb");
      fwrite(id, 1, 8, f);
      fclose(f);

      /* display the result */

      for (n=0; n<8; n++)
      {
         printf("%2x ", id[n]);
      }
      printf("\n");

      printf("\nReading from file\n");

      f = fopen("id.dta", "rb"); /* open file for reading */
      fread(id_2, 1, 8, f);      /* read data into array id_2 */
      fclose(f);

      /* display the result */

      for (n=0; n<8; n++)
      {
         printf("%2x ", id_2[n]);
      }
      printf("\n");

      delay(500);
   }
}

void _1w_init(byte sensor)
{
   byte n;
   _1w_pin_hi(sensor);  /* be sure DQ is high */
   _1w_pin_low(sensor);

   for (n=166; n>0; n--)   /* 500 us delay */   ;

   _1w_pin_hi(sensor);
   for (n=166; n>0; n--)   /* 500 us delay */   ;
}

byte _1w_in_byte(byte sensor)
{
   byte m, n, i_byte, temp, mask_0, mask_1;
   mask_1 = 0x01<<sensor;
   mask_0 = ~mask_1;
   for (n=0; n<8; n++)
   {
      *p2 = 0x00;
      *pm2 = mask_0;
      *pm2 = 0xff;

      temp = *p2;

      if (temp & mask_1)
      {
        i_byte=(i_byte>>1) | 0x80;  /* least sig bit first  */
      }
      else
      {
        i_byte=i_byte >> 1;
      }
      for(m=19; m>0; m--)  /* 60 us */  ;
   }
   return(i_byte);
}

void _1w_out_byte(byte sensor, byte d)
{
   byte m, n, mask_0, mask_1;
   mask_1 = 0x01<<sensor;
   mask_0 = ~mask_1;
   for(n=0; n<8; n++)
   {
      if (d&0x01)
      {
         *p2 = 0x00;
         *pm2 = mask_0;
         *pm2 = 0xff;
         for(m=19; m>0; m--)  /* 60 us */  ;
      }

      else
      {
         *p2 = 0x00;
         *pm2 = mask_0;
         for(m=19; m>0; m--)  /* 60 us */  ;
         *pm2 = 0xff;
      }
      d=d>>1;
   }
}

void _1w_pin_hi(byte sensor)
{
   *pm2 = 0xff;
}

void _1w_pin_low(byte sensor)
{
   byte mask_0, mask_1;
   mask_1 = 0x01 << sensor;
   mask_0 = ~mask_1;
   *p2 = mask_0;
   *pm2 = mask_0;
}

void _1w_strong_pull_up(byte sensor)
{
   byte mask_0, mask_1;
   mask_1 = 0x01 << sensor;
   mask_0 = ~mask_1;
   *p2 = mask_1;     /* bring bit to a hard logic one */
   *pm2 = mask_0;    /* dirs configured as output */
   delay(500);
   *pm2 = 0xff;
}