DS18S20

Dependencies:   mbed

Revision:
0:5b6520e71eb6
diff -r 000000000000 -r 5b6520e71eb6 DS18S20.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DS18S20.h	Thu Apr 26 14:18:31 2012 +0000
@@ -0,0 +1,535 @@
+ /*** 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);
+}
+//******************************************************************************