
DS18S20
Embed:
(wiki syntax)
Show/hide line numbers
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�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 � 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 //******************************************************************************
Generated on Thu Jul 14 2022 11:27:35 by
