DS18S20

Dependencies:   mbed

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&#65533;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 &#65533; 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);
}
//******************************************************************************