aitouares jeremy
/
finalDS18S20
DS18S20
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�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 � 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); } //******************************************************************************