Complete DS1621 library (all functions implemented)
ds1621.cpp
- Committer:
- bborredon
- Date:
- 2012-07-14
- Revision:
- 0:096dbb58d60e
File content as of revision 0:096dbb58d60e:
/*********************************************************** Author: Bernard Borredon Date: 27 december 2011 Version: 1.0 ************************************************************/ #include "ds1621.h" #define BIT_SET(x,n) (x=x | (0x01<<n)) #define BIT_TEST(x,n) (x & (0x01<<n)) #define BIT_CLEAR(x,n) (x=x & ~(0x01<<n)) // Constructor DS1621::DS1621(PinName sda, PinName scl, uint8_t address) : _i2c(sda, scl) { _errnum = DS1621_NoError; _config = DS1621_PolHigh; // Check address range (0 to 7) _address = address; if(address > 7) { _errnum = DS1621_BadAddress; } _address = _address << 1; // Set I2C frequency _i2c.frequency(100000); } // Get temperature with 0.5 degrees resolution float DS1621::getTemp(void) { char cmd; int8_t temp8[2]; float temp; int ack; // Check error if(_errnum) return(0.0); // No error _errnum = DS1621_NoError; // Start convert startConvert(true); if(getError() != 0) return(0.0); cmd = 0xAA; // Read Temperature [AAh] ack = _i2c.write(DS1621_address | _address,&cmd,sizeof(cmd)); if(ack != 0) { _errnum = DS1621_I2cError; return(0.0); } // Read value ack = _i2c.read(DS1621_address | _address,(char *)temp8,sizeof(temp8)); if(ack != 0) { _errnum = DS1621_I2cError; return(0.0); } // Format temperature temp8[1] = temp8[1] >> 7; if(temp8[0] < 0) { // - temp = -~temp8[0] + 0.5 * temp8[1]; } else { // + temp = temp8[0] - 0.5 * temp8[1]; } return(temp); } // Get temperature with 0.01 degrees resolution float DS1621::getHrTemp(void) { char cmd; int8_t temp8[2]; int ack; uint8_t count_remain, count_per_c; uint8_t config,config_mem; int16_t ifract; int16_t itemp; float temp; // Check error if(_errnum) return(0.0); // No error _errnum = DS1621_NoError; // Get config register config = getConfig(); if(getError() != 0) return(0.0); // Force 1Shot if needed config_mem = 0; if(!BIT_TEST(config,DS1621_CFG_1SHOT)) { config_mem = config; BIT_SET(config,DS1621_CFG_1SHOT); setConfig(config); if(getError() != 0) return(0.0); startConvert(false); if(getError() != 0) return(0.0); } // Start conversion startConvert(true); if(getError() != 0) return(0.0); // Wait end of conversion waitEndConvert(); if(getError() != 0) return(0.0); cmd = 0xAA; // Read Temperature [AAh] ack = _i2c.write(DS1621_address | _address,&cmd,sizeof(cmd)); if(ack != 0) { _errnum = DS1621_I2cError; return(0.0); } // Read value ack = _i2c.read(DS1621_address | _address,(char *)temp8,sizeof(temp8)); if(ack != 0) { _errnum = DS1621_I2cError; return(0.0); } cmd = 0xA8; // Read Counter [A8H] ack = _i2c.write(DS1621_address | _address,&cmd,sizeof(cmd)); if(ack != 0) { _errnum = DS1621_I2cError; return(0.0); } // Read value ack = _i2c.read(DS1621_address | _address,(char *)&count_remain,sizeof(count_remain)); if(ack != 0) { _errnum = DS1621_I2cError; return(0.0); } cmd = 0xA9; // Read Slope [A9H] ack = _i2c.write(DS1621_address | _address,&cmd,sizeof(cmd)); if(ack != 0) { _errnum = DS1621_I2cError; return(0.0); } // Read value ack = _i2c.read(DS1621_address | _address,(char *)&count_per_c,sizeof(count_per_c)); if(ack != 0) { _errnum = DS1621_I2cError; return(0.0); } // Format temperature ifract = ((int16_t)(count_per_c - count_remain) * 100) / 25; if(temp8[0] < 0) { // - itemp = -~temp8[0] * 100 + ifract; } else { // + itemp = temp8[0] * 100 + ifract; } temp = (float)itemp / 100.0; // Restore config if needed if(config_mem) { setConfig(config_mem); if(getError() != 0) return(0.0); startConvert(true); if(getError() != 0) return(0.0); } return(temp); } // Read config register uint8_t DS1621::getConfig(void) { char cmd; uint8_t config; int ack; // Check error if(_errnum) return(0); // No error _errnum = DS1621_NoError; cmd = 0xAC; // Access Config [ACh] ack = _i2c.write(DS1621_address | _address,&cmd,sizeof(cmd)); if(ack != 0) { _errnum = DS1621_I2cError; return(0); } // Read value ack = _i2c.read(DS1621_address | _address,(char *)&config,sizeof(config)); if(ack != 0) { _errnum = DS1621_I2cError; return(0); } return(config); } // Write config register void DS1621::setConfig(uint8_t config) { char cmd[2]; int ack; // Check error if(_errnum) return; // No error _errnum = DS1621_NoError; _config = config; cmd[0] = 0xAC; // Access Config [ACh] cmd[1] = config; ack = _i2c.write(DS1621_address | _address,cmd,sizeof(cmd)); if(ack != 0) { _errnum = DS1621_I2cError; } } // Start or stop convert void DS1621::startConvert(bool flag) { char cmd; int ack; // Check error if(_errnum) return; // No error _errnum = DS1621_NoError; if(flag) cmd = 0xEE; // Start Convert [EEh] else cmd = 0x22; // Stop Convert [22h] ack = _i2c.write(DS1621_address | _address,&cmd,sizeof(cmd)); if(ack != 0) { _errnum = DS1621_I2cError; } } // Wait end of conversion void DS1621::waitEndConvert(void) { uint8_t cfg; // Check error if(_errnum) return; // No error _errnum = DS1621_NoError; // Wait end of conversion do { // Get Config register and test bit DONE cfg = getConfig(); if(getError() != 0) return; } while(cfg < DS1621_DONE); } // Read Temperature High Flag bool DS1621::getTHF(void) { uint8_t cfg; bool thf; // Check error if(_errnum) return(0); // No error _errnum = DS1621_NoError; // get Config register cfg = getConfig(); if(getError() != 0) return(0); // Test THF bit if(BIT_TEST(cfg,DS1621_CFG_THF)) thf = true; else thf = false; return(thf); } // Read Temperature Low Flag bool DS1621::getTLF() { uint8_t cfg; bool tlf; // Check error if(_errnum) return(0); // No error _errnum = DS1621_NoError; // get Config register cfg = getConfig(); if(getError() != 0) return(0); // Test TLF bit if(BIT_TEST(cfg,DS1621_CFG_TLF)) tlf = true; else tlf = false; return(tlf); } // Read Temperature Low and High Flag void DS1621::getTF(bool& tlf,bool& thf) { uint8_t cfg; // Check error if(_errnum) return; // No error _errnum = DS1621_NoError; // get Config register cfg = getConfig(); if(getError() != 0) return; // Test TLF bit tlf = false; if(BIT_TEST(cfg,DS1621_CFG_TLF)) tlf = true; // Test THF bit thf = false; if(BIT_TEST(cfg,DS1621_CFG_THF)) thf = true; } // Read 1Shot bit bool DS1621::get1Shot(void) { // Test 1Shot bit if(BIT_TEST(_config,DS1621_CFG_1SHOT)) return(true); else return(false); } // Write Temperature (High or Low) void DS1621::setTemperature(float temp,uint8_t trig) { uint8_t temp8[3]; int ack; float r; // Chack param if(trig > 1) { _errnum = DS1621_ParamError; return; } // Check error if(_errnum) return; // No error _errnum = DS1621_NoError; // Format temperature if(temp >= 0.0) { temp8[1] = (uint8_t)temp; r = temp - (int)temp; if(r >= 0.5) temp8[2] = 0x80; else temp8[2] = 0; } else { temp8[1] = ~(-(int8_t)temp); r = -temp + (int)temp; if(r >= 0.5) temp8[2] = 0x80; else temp8[2] = 0; } wait_ms(100); temp8[0] = 0xA1 + trig; // Access TH or TL [A1h or A2h] ack = _i2c.write(DS1621_address | _address,(char *)temp8,sizeof(temp8)); if(ack != 0) { _errnum = DS1621_I2cError; } } // Read Temperature (High or Low) float DS1621::getTemperature(uint8_t trig) { char cmd; float temp; int8_t temp8[2]; int ack; // Check param if(trig > 1) { _errnum = DS1621_ParamError; return(0.0); } // Check error if(_errnum) return(0.0); // No error _errnum = DS1621_NoError; wait_ms(100); cmd = 0xA1 + trig; // Access TH or TL [A1h or A2h] ack = _i2c.write(DS1621_address| _address,&cmd,sizeof(cmd)); if(ack != 0) { _errnum = DS1621_I2cError; return(0.0); } ack = _i2c.read(DS1621_address | _address,(char *)temp8,sizeof(temp8)); if(ack != 0) { _errnum = DS1621_I2cError; return(0.0); } // Format temperature temp8[1] = temp8[1] >> 7; if(temp8[0] < 0) { // - temp = -~temp8[0] + 0.5 * temp8[1]; } else { // + temp = temp8[0] - 0.5 * temp8[1]; } return(temp); } // Get current error number uint8_t DS1621::getError(void) { return(_errnum); }