DS18S20

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS18S20.h Source File

DS18S20.h

00001  /*** D'apres :       *********************************************************
00002  *
00003  *    FILENAME:    ds1820.h
00004  *    DATE:        25.02.2005
00005  *    AUTHOR:      Christian Stadler
00006  *
00007  *    DESCRIPTION: Driver for DS1820 1-Wire Temperature sensor (Dallas)
00008  *
00009  ******************************************************************************/
00010 #include "mbed.h"
00011 DigitalInOut DQ       (p15);                    // broche DQ relie a la broche p15 du MBED 
00012 DigitalOut G__MOS_P   (p16);
00013 Serial pc(USBTX, USBRX);                        // tx, rx
00014 /* -------------------------------------------------------------------------- */
00015 /*                         DS1820 Timing Parameters                           */
00016 /* -------------------------------------------------------------------------- */
00017 #define DS1820_RST_PULSE       480               /* master reset pulse time in [us] */
00018 #define DS1820_MSTR_BITSTART   2                 /* delay time for bit start by master */
00019 #define DS1820_PRESENCE_WAIT   40                /* delay after master reset pulse in [us] */
00020 #define DS1820_PRESENCE_FIN    480               /* dealy after reading of presence pulse [us] */
00021 #define DS1820_BITREAD_DLY     5                 /* bit read delay */
00022 #define DS1820_BITWRITE_DLY    100               /* bit write delay */
00023 
00024 
00025 /* -------------------------------------------------------------------------- */
00026 /*                            DS1820 Registers                                */
00027 /* -------------------------------------------------------------------------- */
00028 
00029 #define DS1820_REG_TEMPLSB    0
00030 #define DS1820_REG_TEMPMSB    1
00031 #define DS1820_REG_CNTREMAIN  6
00032 #define DS1820_REG_CNTPERSEC  7                     
00033 #define DS1820_SCRPADMEM_LEN  9                     // length of scratchpad memory 
00034 
00035 #define DS1820_ADDR_LEN       8
00036 
00037 
00038 /* -------------------------------------------------------------------------- */
00039 /*                            DS1820 Commands                                 */
00040 /* -------------------------------------------------------------------------- */
00041 
00042 #define DS1820_CMD_SEARCHROM     0xF0               // recherche des differents DS1820 et de leur numROMs
00043 #define DS1820_CMD_READROM       0x33               // idem que SEARCHROM mais utilise pour 1 seul DS1820
00044 #define DS1820_CMD_MATCHROM      0x55               // permet de communiquer avec un DS1820 en particulier grace a son numROM
00045 #define DS1820_CMD_SKIPROM       0xCC               // permet de communiquer avec tous les DS1820 en meme temps
00046 #define DS1820_CMD_ALARMSEARCH   0xEC               // permet de dialoguer seulement avec les DS1820 qui ont un flag 
00047 #define DS1820_CMD_CONVERTTEMP   0x44               // permet de lancer un convertion de la temperature, le resultat sera stocke dans le scratchpad
00048 #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
00049 #define DS1820_CMD_READSCRPAD    0xBE               // permet au MBED de lire le scratchpad
00050 #define DS1820_CMD_COPYSCRPAD    0x48               // permet de copier le scratchpad et les registres TH, TL stocke dans EEPROM
00051 #define DS1820_CMD_RECALLEE      0xB8               // rappel les valeur de declenchement de l'alarme
00052 
00053 
00054 #define DS1820_FAMILY_CODE_DS18B20      0x28
00055 #define DS1820_FAMILY_CODE_DS18S20      0x10
00056 
00057 char dowcrc=0;            // crc is accumulated in this variable
00058 // crc lookup table
00059 char const dscrc_table[] = {
00060 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
00061 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
00062 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
00063 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
00064 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
00065 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
00066 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
00067 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
00068 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
00069 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
00070 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
00071 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
00072 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
00073 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
00074 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
00075 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53
00076 };
00077              
00078 /* -------------------------------------------------------------------------- */
00079 bool doneFlag;                              // declaration d'une variable booleenne "doneFlag"
00080 char lastDiscrep,numROMs;                   // declaration des variables lastDiscrep et numROMs
00081 char RomBytes[DS1820_ADDR_LEN];             // declaration de la variable RomBytes[DS1820_ADDR_LEN]
00082 char FoundROM[9][8];                        // Table of found ROM codes, 8 bytes for each
00083 
00084 
00085 /* -------------------------------------------------------------------------- */
00086 /*                           Low-Level Functions                              */
00087 /* -------------------------------------------------------------------------- */
00088 /*******************************************************************************
00089  * FUNCTION:   ow_reset
00090  * PURPOSE:    Initializes the DS1820 device.
00091  *
00092  * INPUT:      -
00093  * OUTPUT:     -
00094  * RETURN:     FALSE if at least one device is on the 1-wire bus, TRUE otherwise
00095  ******************************************************************************/
00096 bool ow_reset(void)
00097 {
00098    bool presence;
00099 
00100    /* reset pulse */
00101    DQ.output();
00102    DQ=0;
00103    wait_us(DS1820_RST_PULSE);
00104    DQ=1;
00105 
00106    /* wait until pullup pull 1-wire bus to high */
00107    wait_us(DS1820_PRESENCE_WAIT);
00108 
00109    /* get presence pulse */
00110    DQ.input();
00111    presence=DQ.read();
00112 
00113    wait_us(424);
00114 
00115    return presence;
00116 }
00117 
00118 /*******************************************************************************
00119  * FUNCTION:   read_bit
00120  * PURPOSE:    Reads a single bit from the DS1820 device.
00121  *
00122  * INPUT:      -
00123  * OUTPUT:     -
00124  * RETURN:     bool        value of the bit which as been read form the DS1820
00125  ******************************************************************************/
00126 bool read_bit(void)
00127 {
00128    DQ.output();
00129    DQ=0;
00130    wait_us(DS1820_MSTR_BITSTART);
00131    DQ.input();
00132    DQ.read();
00133    wait_us(DS1820_BITREAD_DLY);
00134 
00135    return (DQ);
00136 }
00137 
00138 /*******************************************************************************
00139  * FUNCTION:   write_bit
00140  * PURPOSE:    Writes a single bit to the DS1820 device.
00141  *
00142  * INPUT:      bBit        value of bit to be written
00143  * OUTPUT:     -
00144  * RETURN:     -
00145  ******************************************************************************/
00146 void write_bit(bool bBit)
00147 {
00148    DQ.output();
00149    DQ=0;
00150    wait_us(DS1820_MSTR_BITSTART);
00151 
00152    if (bBit != false) DQ=1;
00153 
00154    wait_us(DS1820_BITWRITE_DLY);
00155    DQ=1;
00156 
00157 }
00158 
00159 /*******************************************************************************
00160  * FUNCTION:   read_byte
00161  * PURPOSE:    Reads a single byte from the DS1820 device.
00162  *
00163  * INPUT:      -
00164  * OUTPUT:     -
00165  * RETURN:     uint8          byte which has been read from the DS1820
00166  ******************************************************************************/
00167 char read_byte(void)
00168 {
00169    char i;
00170    char value = 0;
00171 
00172    for (i=0 ; i < 8; i++)
00173    {
00174       if ( read_bit() ) value |= (1 << i);
00175       wait_us(120);
00176    }
00177    return(value);
00178 }
00179 
00180 /*******************************************************************************
00181  * FUNCTION:   write_byte
00182  * PURPOSE:    Writes a single byte to the DS1820 device.
00183  *
00184  * INPUT:      val_u8         byte to be written
00185  * OUTPUT:     -
00186  * RETURN:     -
00187  ******************************************************************************/
00188 void write_byte(char val_u8)
00189 {
00190    char i;
00191    char temp;
00192 
00193    for (i=0; i < 8; i++)      /* writes byte, one bit at a time */
00194    {
00195       temp = val_u8 >> i;     /* shifts val right 'i' spaces */
00196       temp &= 0x01;           /* copy that bit to temp */
00197       write_bit(temp);  /* write bit in temp into */
00198    }
00199 
00200    wait_us(105);
00201 }
00202 /* -------------------------------------------------------------------------- */
00203 // One wire crc
00204 char ow_crc(char x)
00205 {
00206    dowcrc = dscrc_table[dowcrc^x];
00207    return dowcrc;
00208 }
00209 /* -------------------------------------------------------------------------- */
00210 /*                             API Interface                                  */
00211 /* -------------------------------------------------------------------------- */
00212 
00213 /*******************************************************************************
00214  * FUNCTION:   DS1820_AddrDevice
00215  * PURPOSE:    Addresses a single or all devices on the 1-wire bus.
00216  *
00217  * INPUT:      nAddrMethod       use DS1820_CMD_MATCHROM to select a single
00218  *                               device or DS1820_CMD_SKIPROM to select all
00219  * OUTPUT:     -
00220  * RETURN:     -
00221  ******************************************************************************/
00222 void DS1820_AddrDevice(char nAddrMethod)
00223 {
00224    char i;
00225 
00226    if (nAddrMethod == DS1820_CMD_MATCHROM)
00227    {
00228       write_byte(DS1820_CMD_MATCHROM); /* address single devices on bus */
00229       for (i = 0; i < DS1820_ADDR_LEN; i ++)
00230          write_byte(RomBytes[i]);
00231    }
00232    else
00233       write_byte(DS1820_CMD_SKIPROM);  /* address all devices on bus */
00234 }
00235 
00236 /*******************************************************************************
00237  * FUNCTION:   Next
00238  * PURPOSE:    Finds next device connected to the 1-wire bus.
00239  *
00240  * INPUT:      -
00241  * OUTPUT:     RomBytes[]       ROM code of the next device
00242  * RETURN:     bool                 TRUE if there are more devices on the 1-wire
00243  *                                  bus, FALSE otherwise
00244  ******************************************************************************/
00245 bool Next(void)
00246 {
00247     char x;
00248     char n;
00249     char k = 1;
00250     char m = 1;
00251     char discrepMarker = 0;
00252     bool g;
00253     bool flag;
00254     bool nxt = false;
00255 
00256     /* init ROM address */
00257     for (n=0; n < 8; n ++)
00258         RomBytes[n] = 0x00;
00259 
00260     flag = ow_reset();        /* reset the 1-wire */
00261 
00262     if (flag || doneFlag)        /* no device found */
00263     {
00264         lastDiscrep = 0;     /* reset the search */
00265         return false;
00266     }
00267 
00268     /* send search rom command */
00269     write_byte(DS1820_CMD_SEARCHROM);
00270 
00271     n = 0;
00272     do
00273     {
00274         x = 0;
00275 
00276         /* read bit */
00277         if ( read_bit() == 1 )  x = 2;
00278         wait_us(120);
00279 
00280         /* read bit complement */
00281         if ( read_bit() == 1 )  x |= 1;
00282         wait_us(120);
00283 
00284         /* description for values of x: */
00285         /* 00    There are devices connected to the bus which have conflicting */
00286         /*       bits in the current ROM code bit position. */
00287         /* 01    All devices connected to the bus have a 0 in this bit position. */
00288         /* 10    All devices connected to the bus have a 1 in this bit position. */
00289         /* 11    There are no devices connected to the 1-wire bus. */
00290 
00291         /* if there are no devices on the bus */
00292         if (x == 3) break;
00293         else
00294         {
00295             /* devices have the same logical value at this position */
00296             if (x > 0)  g = (bool)(x >> 1);// get bit value
00297             /* devices have confilcting bits in the current ROM code */
00298             else
00299             {
00300                 /* if there was a conflict on the last iteration */
00301                 if (m < lastDiscrep)
00302                     /* take same bit as in last iteration */
00303                     g = ( (RomBytes[n] & k) > 0 );
00304                 else
00305                     g = (m == lastDiscrep);
00306 
00307                 if (g == 0)
00308                     discrepMarker = m;
00309             }
00310 
00311             /* store bit in ROM address */
00312            if (g ==1)
00313                RomBytes[n] |= k;
00314            else
00315                RomBytes[n] &= ~k;
00316 
00317            write_bit(g);
00318 
00319            /* increment bit position */
00320            m ++;
00321 
00322            /* calculate next mask value */
00323            k = k << 1;
00324 
00325            /* check if this byte has finished */
00326            if (k == 0)
00327            {
00328                ow_crc(RomBytes[n]);      // Accumulate the crc
00329                n ++;  /* advance to next byte of ROM mask */
00330                k = 1;    /* update mask */
00331            }
00332         }
00333     } while (n < DS1820_ADDR_LEN);
00334 
00335 
00336     /* if search was unsuccessful then */
00337     if ((m < 65) ||dowcrc)
00338 //    if (m < 65 )
00339         /* reset the last discrepancy to 0 */
00340         lastDiscrep = 0;
00341     else
00342     {
00343         /* search was successful */
00344         lastDiscrep = discrepMarker;
00345         doneFlag = (lastDiscrep == 0);
00346 
00347         /* indicates search is not complete yet, more parts remain */
00348         nxt = true;
00349     }
00350     return nxt;
00351 }
00352 
00353 /*******************************************************************************
00354  * FUNCTION:   First
00355  * PURPOSE:    Starts the device search on the 1-wire bus.
00356  *
00357  * INPUT:      -
00358  * OUTPUT:     RomBytes[]       ROM code of the first device
00359  * RETURN:     bool                 TRUE if there are more devices on the 1-wire
00360  *                                  bus, FALSE otherwise
00361  ******************************************************************************/
00362 bool First(void)
00363 {
00364     lastDiscrep = 0;
00365     doneFlag = false;
00366 
00367     return ( Next() );
00368 }
00369 /* -------------------------------------------------------------------------- */
00370 void FindDevices(void)
00371 {
00372    char m;
00373    if(!ow_reset())
00374    {
00375       if(First())    // Begins when at least one part found
00376       {
00377          numROMs = 0;
00378          do
00379          {
00380             numROMs++;
00381             for (m=0;m<8;m++)
00382             {
00383                FoundROM[numROMs-1][m] = RomBytes[m];
00384             }
00385          } while (Next()&&(numROMs<10));   // Continues until no additional
00386       }
00387    }
00388 
00389 }
00390 //******************************************************************************
00391 // Sends Match ROM command to bus then device address
00392 char Send_MatchRom(char actNumROM)
00393 {
00394    char i;
00395    if (ow_reset()) return false;          // 0 if device present
00396    write_byte(0x55);                      // Match ROM
00397 
00398    for (i=0;i<8;i++)
00399    {
00400       write_byte(FoundROM[actNumROM][i]);   // Send ROM code
00401    }
00402 
00403    return true;
00404 }
00405 //******************************************************************************
00406 void Read_ROMCode(void)
00407 {
00408 char n;
00409 char dat[9];
00410 
00411 ow_reset();
00412 write_byte(0x33);
00413 for (n=0;n<8;n++){dat[n]=read_byte();}
00414 
00415 pc.printf("\f%X%X%X%X\n%X%X%X%X",dat[0],dat[1],dat[2],dat[3],dat[4],dat[5],
00416                                                                  dat[6],dat[7]);
00417 
00418 wait_ms(5000);
00419 }
00420 /*******************************************************************************
00421  * FUNCTION:   DS1820_WriteEEPROM
00422  * PURPOSE:    Writes to the DS1820 EEPROM memory (2 bytes available).
00423  *
00424  * INPUT:      nTHigh         high byte of EEPROM
00425  *             nTLow          low byte of EEPROM
00426  * OUTPUT:     -
00427  * RETURN:     -
00428  ******************************************************************************/
00429 void DS1820_WriteEEPROM(char nTHigh, char nTLow)
00430 {
00431     /* --- write to scratchpad ----------------------------------------------- */
00432     ow_reset();                                          // appel de la fonction ow_reset
00433     DS1820_AddrDevice(DS1820_CMD_MATCHROM);
00434     write_byte(DS1820_CMD_WRITESCRPAD);                  // debut conversion
00435     write_byte(nTHigh);
00436     write_byte(nTLow);
00437     wait_us(10);                                         // attendre 10ms
00438     ow_reset();                                          // appel de la fonction ow_reset
00439     DS1820_AddrDevice(DS1820_CMD_MATCHROM);
00440     write_byte(DS1820_CMD_COPYSCRPAD);                   // start conversion
00441     G__MOS_P=0;                                          // "strong pullup"
00442     wait_ms(10);                                         // attendre 10 ms
00443     G__MOS_P=1;                                          // "strong pullup"
00444 }
00445 
00446 /*******************************************************************************
00447  * FUNCTION:   DS1820_GetTemp
00448  * PURPOSE:    Get temperature value from single DS1820 device.
00449  *
00450  *             Scratchpad Memory Layout
00451  *             Byte  Register
00452  *             0     Temperature_LSB
00453  *             1     Temperature_MSB
00454  *             2     Temp Alarm High / User Byte 1
00455  *             3     Temp Alarm Low / User Byte 2
00456  *             4     Reserved
00457  *             5     Reserved
00458  *             6     Count_Remain
00459  *             7     Count_per_C
00460  *             8     CRC
00461  *
00462  *             Temperature calculation for DS18S20 (Family Code 0x10):
00463  *             =======================================================
00464  *                                             (Count_per_C - Count_Remain)
00465  *             Temperature = temp_read - 0.25 + ----------------------------
00466  *                                                     Count_per_C
00467  *
00468  *             Where temp_read is the value from the temp_MSB and temp_LSB with
00469  *             the least significant bit removed (the 0.5C bit).
00470  *
00471  *
00472  *             Temperature calculation for DS18B20 (Family Code 0x28):
00473  *             =======================================================
00474  *                      bit7   bit6   bit5   bit4   bit3   bit2   bit1   bit0
00475  *             LSB      2^3    2^2    2^1    2^0    2^-1   2^-2   2^-3   2^-4
00476  *                      bit15  bit14  bit13  bit12  bit3   bit2   bit1   bit0
00477  *             MSB      S      S      S      S      S      2^6    2^5    2^4
00478  *
00479  *             The temperature data is stored as a 16-bit sign-extended two&#65533;s
00480  *             complement number in the temperature register. The sign bits (S)
00481  *             indicate if the temperature is positive or negative: for
00482  *             positive numbers S = 0 and for negative numbers S = 1.
00483  *
00484  * RETURN:     float
00485  ******************************************************************************/
00486 float DS1820_GetTemp(void)                          //fonction capture de la temperature
00487 {
00488     char i;                                         //declaration de la variable i
00489     char scrpad[DS1820_SCRPADMEM_LEN];              //declaration de la variable scrpad[DS1820_SCRPADMEM_LEN]
00490     signed char temp_read;                          //declaration de la variable signe temp_read
00491     float temperature;                              //declaration de la variable flotante temperature
00492 
00493     /* --- start temperature conversion -------------------------------------- */
00494     ow_reset();
00495     DS1820_AddrDevice(DS1820_CMD_MATCHROM);          /* address the device */
00496     DQ.output();                                     //DQ en sortie
00497     DQ=1;                                            //DQ &#65533; 1
00498     write_byte(DS1820_CMD_CONVERTTEMP);              /* start conversion */
00499     G__MOS_P=0;                                      //"strong pullup"
00500     /* wait for temperature conversion */
00501     wait_ms(750);                                    // attendre 0.75s
00502     G__MOS_P=1;                                      //"strong pullup"
00503 
00504     /* --- read sratchpad ---------------------------------------------------- */
00505     ow_reset();
00506     DS1820_AddrDevice(DS1820_CMD_MATCHROM);           /* address the device */
00507     write_byte(DS1820_CMD_READSCRPAD);                /* read scratch pad */
00508 
00509     /* read scratch pad data */
00510     for (i=0; i < DS1820_SCRPADMEM_LEN; i++)          // boucle for : i=0 puis on l'incremante jusqu'a i < DS1820_SCRPADMEM_LEN
00511         scrpad[i] = read_byte();
00512 
00513     /* --- calculate temperature --------------------------------------------- */
00514 
00515     if (RomBytes[0] == DS1820_FAMILY_CODE_DS18S20)
00516     {
00517 /////////////////////// precision O,5 degC //////////////////////////////////////
00518 /*//   temp = (signed int) make16(scrpad[1],scrpad[0]);
00519    temp = (signed int) ((int)scrpad[1]<<8 | (int)scrpad[0]); 
00520    temperature =(float)temp/2;*/
00521 /////////////////////////////////////////////////////////////////////////////////
00522 
00523 ////////////////////// precision O,1 deg ////////////////////////////////////////
00524 //...calcul....
00525     temp_read=(signed char)(((int)scrpad[1]<<8 | (int)scrpad[0])>>1);
00526     temperature=(float)(temp_read);
00527     temperature = temperature + 0.75 - (float)(scrpad[6]/(float)scrpad[7]);
00528 ////////////////////////////////////////////////////////////////////////////////
00529    }
00530     else//ds18b20
00531         temperature =((float) (signed int)((int)scrpad[1]<<8 | (int)scrpad[0]))/16;
00532 
00533     return (temperature);
00534 }
00535 //******************************************************************************