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