aitouares jeremy
/
finalDS18S20
DS18S20
Revision 0:5b6520e71eb6, committed 2012-04-26
- Comitter:
- aitouares
- Date:
- Thu Apr 26 14:18:31 2012 +0000
- Commit message:
Changed in this revision
--- /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�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); +} +//******************************************************************************
--- /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