Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
DS18S20.h
- Committer:
- aitouares
- Date:
- 2012-04-26
- Revision:
- 0:5b6520e71eb6
File content as of revision 0:5b6520e71eb6:
/*** D'apres : *********************************************************
*
* FILENAME: ds1820.h
* DATE: 25.02.2005
* AUTHOR: Christian Stadler
*
* DESCRIPTION: Driver for DS1820 1-Wire Temperature sensor (Dallas)
*
******************************************************************************/
#include "mbed.h"
DigitalInOut DQ (p15); // broche DQ relie a la broche p15 du MBED
DigitalOut G__MOS_P (p16);
Serial pc(USBTX, USBRX); // tx, rx
/* -------------------------------------------------------------------------- */
/* DS1820 Timing Parameters */
/* -------------------------------------------------------------------------- */
#define DS1820_RST_PULSE 480 /* master reset pulse time in [us] */
#define DS1820_MSTR_BITSTART 2 /* delay time for bit start by master */
#define DS1820_PRESENCE_WAIT 40 /* delay after master reset pulse in [us] */
#define DS1820_PRESENCE_FIN 480 /* dealy after reading of presence pulse [us] */
#define DS1820_BITREAD_DLY 5 /* bit read delay */
#define DS1820_BITWRITE_DLY 100 /* bit write delay */
/* -------------------------------------------------------------------------- */
/* DS1820 Registers */
/* -------------------------------------------------------------------------- */
#define DS1820_REG_TEMPLSB 0
#define DS1820_REG_TEMPMSB 1
#define DS1820_REG_CNTREMAIN 6
#define DS1820_REG_CNTPERSEC 7
#define DS1820_SCRPADMEM_LEN 9 // length of scratchpad memory
#define DS1820_ADDR_LEN 8
/* -------------------------------------------------------------------------- */
/* DS1820 Commands */
/* -------------------------------------------------------------------------- */
#define DS1820_CMD_SEARCHROM 0xF0 // recherche des differents DS1820 et de leur numROMs
#define DS1820_CMD_READROM 0x33 // idem que SEARCHROM mais utilise pour 1 seul DS1820
#define DS1820_CMD_MATCHROM 0x55 // permet de communiquer avec un DS1820 en particulier grace a son numROM
#define DS1820_CMD_SKIPROM 0xCC // permet de communiquer avec tous les DS1820 en meme temps
#define DS1820_CMD_ALARMSEARCH 0xEC // permet de dialoguer seulement avec les DS1820 qui ont un flag
#define DS1820_CMD_CONVERTTEMP 0x44 // permet de lancer un convertion de la temperature, le resultat sera stocke dans le scratchpad
#define DS1820_CMD_WRITESCRPAD 0x4E // permet au MBED d'ecrire deux octets dans le scratchpad dont un dans le registre TH et un dans le registre TL
#define DS1820_CMD_READSCRPAD 0xBE // permet au MBED de lire le scratchpad
#define DS1820_CMD_COPYSCRPAD 0x48 // permet de copier le scratchpad et les registres TH, TL stocke dans EEPROM
#define DS1820_CMD_RECALLEE 0xB8 // rappel les valeur de declenchement de l'alarme
#define DS1820_FAMILY_CODE_DS18B20 0x28
#define DS1820_FAMILY_CODE_DS18S20 0x10
char dowcrc=0; // crc is accumulated in this variable
// crc lookup table
char const dscrc_table[] = {
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53
};
/* -------------------------------------------------------------------------- */
bool doneFlag; // declaration d'une variable booleenne "doneFlag"
char lastDiscrep,numROMs; // declaration des variables lastDiscrep et numROMs
char RomBytes[DS1820_ADDR_LEN]; // declaration de la variable RomBytes[DS1820_ADDR_LEN]
char FoundROM[9][8]; // Table of found ROM codes, 8 bytes for each
/* -------------------------------------------------------------------------- */
/* Low-Level Functions */
/* -------------------------------------------------------------------------- */
/*******************************************************************************
* FUNCTION: ow_reset
* PURPOSE: Initializes the DS1820 device.
*
* INPUT: -
* OUTPUT: -
* RETURN: FALSE if at least one device is on the 1-wire bus, TRUE otherwise
******************************************************************************/
bool ow_reset(void)
{
bool presence;
/* reset pulse */
DQ.output();
DQ=0;
wait_us(DS1820_RST_PULSE);
DQ=1;
/* wait until pullup pull 1-wire bus to high */
wait_us(DS1820_PRESENCE_WAIT);
/* get presence pulse */
DQ.input();
presence=DQ.read();
wait_us(424);
return presence;
}
/*******************************************************************************
* FUNCTION: read_bit
* PURPOSE: Reads a single bit from the DS1820 device.
*
* INPUT: -
* OUTPUT: -
* RETURN: bool value of the bit which as been read form the DS1820
******************************************************************************/
bool read_bit(void)
{
DQ.output();
DQ=0;
wait_us(DS1820_MSTR_BITSTART);
DQ.input();
DQ.read();
wait_us(DS1820_BITREAD_DLY);
return (DQ);
}
/*******************************************************************************
* FUNCTION: write_bit
* PURPOSE: Writes a single bit to the DS1820 device.
*
* INPUT: bBit value of bit to be written
* OUTPUT: -
* RETURN: -
******************************************************************************/
void write_bit(bool bBit)
{
DQ.output();
DQ=0;
wait_us(DS1820_MSTR_BITSTART);
if (bBit != false) DQ=1;
wait_us(DS1820_BITWRITE_DLY);
DQ=1;
}
/*******************************************************************************
* FUNCTION: read_byte
* PURPOSE: Reads a single byte from the DS1820 device.
*
* INPUT: -
* OUTPUT: -
* RETURN: uint8 byte which has been read from the DS1820
******************************************************************************/
char read_byte(void)
{
char i;
char value = 0;
for (i=0 ; i < 8; i++)
{
if ( read_bit() ) value |= (1 << i);
wait_us(120);
}
return(value);
}
/*******************************************************************************
* FUNCTION: write_byte
* PURPOSE: Writes a single byte to the DS1820 device.
*
* INPUT: val_u8 byte to be written
* OUTPUT: -
* RETURN: -
******************************************************************************/
void write_byte(char val_u8)
{
char i;
char temp;
for (i=0; i < 8; i++) /* writes byte, one bit at a time */
{
temp = val_u8 >> i; /* shifts val right 'i' spaces */
temp &= 0x01; /* copy that bit to temp */
write_bit(temp); /* write bit in temp into */
}
wait_us(105);
}
/* -------------------------------------------------------------------------- */
// One wire crc
char ow_crc(char x)
{
dowcrc = dscrc_table[dowcrc^x];
return dowcrc;
}
/* -------------------------------------------------------------------------- */
/* API Interface */
/* -------------------------------------------------------------------------- */
/*******************************************************************************
* FUNCTION: DS1820_AddrDevice
* PURPOSE: Addresses a single or all devices on the 1-wire bus.
*
* INPUT: nAddrMethod use DS1820_CMD_MATCHROM to select a single
* device or DS1820_CMD_SKIPROM to select all
* OUTPUT: -
* RETURN: -
******************************************************************************/
void DS1820_AddrDevice(char nAddrMethod)
{
char i;
if (nAddrMethod == DS1820_CMD_MATCHROM)
{
write_byte(DS1820_CMD_MATCHROM); /* address single devices on bus */
for (i = 0; i < DS1820_ADDR_LEN; i ++)
write_byte(RomBytes[i]);
}
else
write_byte(DS1820_CMD_SKIPROM); /* address all devices on bus */
}
/*******************************************************************************
* FUNCTION: Next
* PURPOSE: Finds next device connected to the 1-wire bus.
*
* INPUT: -
* OUTPUT: RomBytes[] ROM code of the next device
* RETURN: bool TRUE if there are more devices on the 1-wire
* bus, FALSE otherwise
******************************************************************************/
bool Next(void)
{
char x;
char n;
char k = 1;
char m = 1;
char discrepMarker = 0;
bool g;
bool flag;
bool nxt = false;
/* init ROM address */
for (n=0; n < 8; n ++)
RomBytes[n] = 0x00;
flag = ow_reset(); /* reset the 1-wire */
if (flag || doneFlag) /* no device found */
{
lastDiscrep = 0; /* reset the search */
return false;
}
/* send search rom command */
write_byte(DS1820_CMD_SEARCHROM);
n = 0;
do
{
x = 0;
/* read bit */
if ( read_bit() == 1 ) x = 2;
wait_us(120);
/* read bit complement */
if ( read_bit() == 1 ) x |= 1;
wait_us(120);
/* description for values of x: */
/* 00 There are devices connected to the bus which have conflicting */
/* bits in the current ROM code bit position. */
/* 01 All devices connected to the bus have a 0 in this bit position. */
/* 10 All devices connected to the bus have a 1 in this bit position. */
/* 11 There are no devices connected to the 1-wire bus. */
/* if there are no devices on the bus */
if (x == 3) break;
else
{
/* devices have the same logical value at this position */
if (x > 0) g = (bool)(x >> 1);// get bit value
/* devices have confilcting bits in the current ROM code */
else
{
/* if there was a conflict on the last iteration */
if (m < lastDiscrep)
/* take same bit as in last iteration */
g = ( (RomBytes[n] & k) > 0 );
else
g = (m == lastDiscrep);
if (g == 0)
discrepMarker = m;
}
/* store bit in ROM address */
if (g ==1)
RomBytes[n] |= k;
else
RomBytes[n] &= ~k;
write_bit(g);
/* increment bit position */
m ++;
/* calculate next mask value */
k = k << 1;
/* check if this byte has finished */
if (k == 0)
{
ow_crc(RomBytes[n]); // Accumulate the crc
n ++; /* advance to next byte of ROM mask */
k = 1; /* update mask */
}
}
} while (n < DS1820_ADDR_LEN);
/* if search was unsuccessful then */
if ((m < 65) ||dowcrc)
// if (m < 65 )
/* reset the last discrepancy to 0 */
lastDiscrep = 0;
else
{
/* search was successful */
lastDiscrep = discrepMarker;
doneFlag = (lastDiscrep == 0);
/* indicates search is not complete yet, more parts remain */
nxt = true;
}
return nxt;
}
/*******************************************************************************
* FUNCTION: First
* PURPOSE: Starts the device search on the 1-wire bus.
*
* INPUT: -
* OUTPUT: RomBytes[] ROM code of the first device
* RETURN: bool TRUE if there are more devices on the 1-wire
* bus, FALSE otherwise
******************************************************************************/
bool First(void)
{
lastDiscrep = 0;
doneFlag = false;
return ( Next() );
}
/* -------------------------------------------------------------------------- */
void FindDevices(void)
{
char m;
if(!ow_reset())
{
if(First()) // Begins when at least one part found
{
numROMs = 0;
do
{
numROMs++;
for (m=0;m<8;m++)
{
FoundROM[numROMs-1][m] = RomBytes[m];
}
} while (Next()&&(numROMs<10)); // Continues until no additional
}
}
}
//******************************************************************************
// Sends Match ROM command to bus then device address
char Send_MatchRom(char actNumROM)
{
char i;
if (ow_reset()) return false; // 0 if device present
write_byte(0x55); // Match ROM
for (i=0;i<8;i++)
{
write_byte(FoundROM[actNumROM][i]); // Send ROM code
}
return true;
}
//******************************************************************************
void Read_ROMCode(void)
{
char n;
char dat[9];
ow_reset();
write_byte(0x33);
for (n=0;n<8;n++){dat[n]=read_byte();}
pc.printf("\f%X%X%X%X\n%X%X%X%X",dat[0],dat[1],dat[2],dat[3],dat[4],dat[5],
dat[6],dat[7]);
wait_ms(5000);
}
/*******************************************************************************
* FUNCTION: DS1820_WriteEEPROM
* PURPOSE: Writes to the DS1820 EEPROM memory (2 bytes available).
*
* INPUT: nTHigh high byte of EEPROM
* nTLow low byte of EEPROM
* OUTPUT: -
* RETURN: -
******************************************************************************/
void DS1820_WriteEEPROM(char nTHigh, char nTLow)
{
/* --- write to scratchpad ----------------------------------------------- */
ow_reset(); // appel de la fonction ow_reset
DS1820_AddrDevice(DS1820_CMD_MATCHROM);
write_byte(DS1820_CMD_WRITESCRPAD); // debut conversion
write_byte(nTHigh);
write_byte(nTLow);
wait_us(10); // attendre 10ms
ow_reset(); // appel de la fonction ow_reset
DS1820_AddrDevice(DS1820_CMD_MATCHROM);
write_byte(DS1820_CMD_COPYSCRPAD); // start conversion
G__MOS_P=0; // "strong pullup"
wait_ms(10); // attendre 10 ms
G__MOS_P=1; // "strong pullup"
}
/*******************************************************************************
* FUNCTION: DS1820_GetTemp
* PURPOSE: Get temperature value from single DS1820 device.
*
* Scratchpad Memory Layout
* Byte Register
* 0 Temperature_LSB
* 1 Temperature_MSB
* 2 Temp Alarm High / User Byte 1
* 3 Temp Alarm Low / User Byte 2
* 4 Reserved
* 5 Reserved
* 6 Count_Remain
* 7 Count_per_C
* 8 CRC
*
* Temperature calculation for DS18S20 (Family Code 0x10):
* =======================================================
* (Count_per_C - Count_Remain)
* Temperature = temp_read - 0.25 + ----------------------------
* Count_per_C
*
* Where temp_read is the value from the temp_MSB and temp_LSB with
* the least significant bit removed (the 0.5C bit).
*
*
* Temperature calculation for DS18B20 (Family Code 0x28):
* =======================================================
* bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
* LSB 2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4
* bit15 bit14 bit13 bit12 bit3 bit2 bit1 bit0
* MSB S S S S S 2^6 2^5 2^4
*
* The temperature data is stored as a 16-bit sign-extended two�s
* complement number in the temperature register. The sign bits (S)
* indicate if the temperature is positive or negative: for
* positive numbers S = 0 and for negative numbers S = 1.
*
* RETURN: float
******************************************************************************/
float DS1820_GetTemp(void) //fonction capture de la temperature
{
char i; //declaration de la variable i
char scrpad[DS1820_SCRPADMEM_LEN]; //declaration de la variable scrpad[DS1820_SCRPADMEM_LEN]
signed char temp_read; //declaration de la variable signe temp_read
float temperature; //declaration de la variable flotante temperature
/* --- start temperature conversion -------------------------------------- */
ow_reset();
DS1820_AddrDevice(DS1820_CMD_MATCHROM); /* address the device */
DQ.output(); //DQ en sortie
DQ=1; //DQ � 1
write_byte(DS1820_CMD_CONVERTTEMP); /* start conversion */
G__MOS_P=0; //"strong pullup"
/* wait for temperature conversion */
wait_ms(750); // attendre 0.75s
G__MOS_P=1; //"strong pullup"
/* --- read sratchpad ---------------------------------------------------- */
ow_reset();
DS1820_AddrDevice(DS1820_CMD_MATCHROM); /* address the device */
write_byte(DS1820_CMD_READSCRPAD); /* read scratch pad */
/* read scratch pad data */
for (i=0; i < DS1820_SCRPADMEM_LEN; i++) // boucle for : i=0 puis on l'incremante jusqu'a i < DS1820_SCRPADMEM_LEN
scrpad[i] = read_byte();
/* --- calculate temperature --------------------------------------------- */
if (RomBytes[0] == DS1820_FAMILY_CODE_DS18S20)
{
/////////////////////// precision O,5 degC //////////////////////////////////////
/*// temp = (signed int) make16(scrpad[1],scrpad[0]);
temp = (signed int) ((int)scrpad[1]<<8 | (int)scrpad[0]);
temperature =(float)temp/2;*/
/////////////////////////////////////////////////////////////////////////////////
////////////////////// precision O,1 deg ////////////////////////////////////////
//...calcul....
temp_read=(signed char)(((int)scrpad[1]<<8 | (int)scrpad[0])>>1);
temperature=(float)(temp_read);
temperature = temperature + 0.75 - (float)(scrpad[6]/(float)scrpad[7]);
////////////////////////////////////////////////////////////////////////////////
}
else//ds18b20
temperature =((float) (signed int)((int)scrpad[1]<<8 | (int)scrpad[0]))/16;
return (temperature);
}
//******************************************************************************