DS18S20

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
aitouares
Date:
Thu Apr 26 14:18:31 2012 +0000
Commit message:

Changed in this revision

DS18S20.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /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);
+}
+//******************************************************************************
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Apr 26 14:18:31 2012 +0000
@@ -0,0 +1,57 @@
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//                                                                                                                  //
+//                                      Fonctionnement du programme du DS1820                                       //
+//                                                                                                                  //
+//                                                                                                                  //
+//  1)    Pour commencer le MBED initial le bus 1-Wire c'est-à-dire :                                               //
+//          -    MBED envoi une impulsion à 0 pendant 480µs minimum                                                 //
+//          -    Puis le DS1820 répond avec une impulsion à 0 de 60à 240µs.                                         //
+//  2)    On utilise la fonction «Search ROM [F0]» qui va permettre au MBED de récupérer tous les numéros           //
+//      de ROM des DS1820 et par la même occasion de savoir combien de DS1820 il y a sur le bus 1-Wire.             //
+//  3)    On fait un reset du bus 1-Wire on envoi le numéro de ROM « 0x10,0x65,0xF2,0x45,0x2,0x8,0x0,0xAE »         //
+//      pour communiquer avec le DS1820 désiré puis on utilise la fonction « Convert Temperature [44] »,            //
+//      la valeur de la température est stocké dans le deuxième octet du scratchpad.                                //
+//  4)    Puis on va lire dans le scratchpad la valeur de la température stockée dans la variable « temperature »   //
+//      prise par le DS1820.                                                                                        //
+//  5)    Affichage de la variable « temperature » sur un HyperTerminal grâce à une liaison série.                  //
+//                                                                                                                  //
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+#include "mbed.h"
+#include "DS18S20.h"
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//                                                                                                               //
+//                                        Affichage de la temperature                                            //
+//                                                                                                               //  
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+int main()                                                         /* debut du programme principal */ 
+{
+                                         
+    float temperature;                                             /* declaration de la variabble
+                                                                      flotante temperature */
+    G__MOS_P =1 ;                                                   /* initialisation du P-MOS */
+    FindDevices();                                                  /* fonction cherchant le nombre de ds1820 
+                                                                       et leur numero de serie */
+   
+        
+    while (true)                                                    /* boucle while infini */ 
+    {
+
+        if ( First() )                                              /* fonction if */
+        {
+         temperature =  DS1820_GetTemp();                           /* affectation du resultat de la temperature
+                                                                       a la variable temperature */
+         pc.printf("\t temp = % +.3g""\xb0""C   \r",temperature);   /* affichage de la temperature */                                                                    
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Apr 26 14:18:31 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/737756e0b479