Interfacing with a Dallas DS1820 1-W Thermometer
/* DS1820_1.C
**
** Illustrates interfacing of the Flashlite V25 with up to eight DS1820's
** on Port P2.
**
** This routine does not use the search ROM feature. Rather, the Skip
** ROM. Thus, only a single DS1820 may be configured on each bit of
** Port P2.
**
** This routine performs measurements on P2.0, P2.1, P2.2 and P2.3 and
** displays the nine bytes fetched from each of the DS1820s. The
** temperature is also displayed. Note that the extended resolution
** feature of the DS1820 is not used. Thus, the temperature resolution is
** 0.5 degrees C.
**
** Flashlite DS1820
**
** P2.X -------------------- DQ
**
** Note that 4.7K pullups to +5 VDC are required on each 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 */
#define MAX_SENSORS 4
void main(void)
{
byte sensor, n, buff[9];
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)
{
for (sensor = 0; sensor < MAX_SENSORS; sensor++)
{
_1w_init(sensor);
_1w_out_byte(sensor, 0xcc); /* skip ROM */
_1w_out_byte(sensor, 0x44); /* perform temperature conversion */
_1w_strong_pull_up(sensor);
_1w_init(sensor);
_1w_out_byte(sensor, 0xcc); /* skip ROM */
_1w_out_byte(sensor, 0xbe);
for (n=0; n<9; n++) /* fetch the 9 bytes */
{
buff[n]=_1w_in_byte(sensor);
}
/* display the result */
printf("%d\n", sensor);
for (n=0; n<4; n++)
{
printf("%2x ", buff[n]);
}
printf("\n");
for (n=4; n<9; n++)
{
printf("%2x ", buff[n]);
}
printf("\n");
if (buff[n] & 0x80) /* its negative */
{
buff[n] = ~buff[0] + 1;
T_C = - ((float) buff[0]) / 2.0;
}
else
{
T_C = ((float) buff[0]) / 2.0;
}
printf("T_C = %.1f\n", T_C);
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;
}