CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

SE98A/SE98ATP I2C temperature sensor, full driver by Eduardo

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
Eduardo__



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

SE98A/SE98ATP I2C temperature sensor, full driver by Eduardo
PostPosted: Fri May 18, 2012 10:23 am     Reply with quote

Code:
SE98A     (NXP/PHILIPS)
           DDR memory(or General) module temperature sensor, 1.7 V to 3.6 V
           
JEDEC (JC-42.4) TS3000B1 DIMM ± 0.5 °C (typ.) between 75 °C and 95 °C temperature sensor
* Optimized for voltage range: 1.7 V to 3.6 V
* Shutdown current: 0.1 µA (typ.) and 5.0 µA (max.)
* 2-wire interface: I2C-bus/SMBus compatible, 0 Hz to 400 kHz
* SMBus ALERT and TIMEOUT (programmable)
* 11-bit ADC Temperature-to-Digital converter with 0.125 °C resolution
* Operating current: 250 µA (typ.) and 400 µA (max.)
* Programmable hysteresis threshold: 0 °C, 1.5 °C, 3 °C, 6 °C
* Over/under/critical temperature EVENT output

PINOUT:
                      +-----U-----+
3bit I2C \     ->  A0 |1         8|VDD     <- Power Supply
address   >----->  A1 |2         7|EVENT   <- Open collector output for programmed events(Allarms, etc...)
Sellector/     ->  A2 |3         6|SCL     <- Connect to I2C bus here
Power Supply   ->  VSS|4         5|SDA     <- Connect to I2C bus here
                      +-----------+

_________________
Eduardo Guilherme Brandt
Eduardo__



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

SE98A_commandList.txt
PostPosted: Fri May 18, 2012 10:25 am     Reply with quote

SE98A_commandList.txt

Code:

/*************************SPI handshake and I/O commands***********************************/
//Functions
void SE98_setaddr(int8 devaddr, int8 SE98_reg);             //SET SE98A pointer register address
void SE98_write(int8 devaddr, int8 SE98_reg, int16 data);   //WRITE data to SE98A at specific address
int16 SE98_read(int8 devaddr, int8 SE98_reg);               //READ data from SE98A at specific address
int16 SE98_readlast(int8 devaddr);                          //READ data from SE98A actual(last) register(set with SE98_setaddr() function)
//
//
/*************************General Driver commands******************************************/
//Defined macros
//Functions
void SE98_initPorts();                       //Inicialize tris ports of uC for SE98A
void SE98_default_config(int8 da);           //Ititializes driver default configuration for SE98A chip
signed int16 SE_conv8to16(signed int8 val);  //Converts from signed int8(-50 to 125degree) to SE98A temperature format
signed int8 SE_conv16to8(signed int16 val);  //Converts from SE98A format to signed int8(-50 to 125degree) format
float SE_conv16tofloat(signed int16 val);    //Converts from SE98A temperature format to float(-55.0 to 255.9degree)
signed int SE98_get_temperature(int8 devaddr);//Get temperature from SE98A(returns signed 8bit value)
SE98_get_temperature_float(int8 devaddr);    //Get temperature from SE98A(returns float value)
void SE98_shutdown(int8 devaddr);            //Shutdown SE98A(low power mode)
void SE98_poweron(int8 devaddr);             //get out shutdown SE98A(normal power mode)
signed int8 SE98_wakeup_read_andshutdown(int8 devaddr, int1 op);  //Wakeup, waits for convertion, reads temperature, shutdown SE98A and returns converted temperature value
signed int8 SE98_wakeup_read_andshutdown(int8 devaddr);           //(overloaded function)Wakeup, waits for convertion, reads temperature, shutdown SE98A and returns converted temperature value
 

void SE98A_driver_use_example();             //Example of using this driver



_________________
Eduardo Guilherme Brandt
Eduardo__



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

SE98A.h header file
PostPosted: Fri May 18, 2012 10:27 am     Reply with quote

SE98A.h header file

Code:
/*
                              SE98A     (NXP/PHILIPS)
           DDR memory(or General) module temperature sensor, 1.7 V to 3.6 V

HEADER FILE                                                                                                                                     

ps: (R)=Read Only register
    (W)=Write Only register
    " "=Read and Write register
    (RW)=Read and Write register
    (?)=Initial Register State
    (xxxx)=Register Value/data
    *=Automated functions contemplated register(it has specific functions for it in driver, already done). Another registers/functions must be read/written by hand by the programmer. see example of implementation in driver.
    **=Frequently used tables
    data&=~PRIM_RX;   //Reset PRIM_RX bit(for example)
    data|=PRIM_RX;    //Set PRIM_RX bit(for example)
/////////////////////////////////////////////////////////////////////////////////////////*/
/***********************       REGISTERS ADDRESS LIST       *****************************/

enum SE98_regs {  //**Registers address list
   SE_CAPABILITY  = 0x00,     //(0037h) See "SE98_Capability" register (B grade = 0037h)(See SE98_capability)
   SE_CONFIG      = 0x01,     //(0000h) See "SE98_config" Configuration register(See SE98_config)
   SE_ALARM_UP    = 0x02,     //(0000h) Upper Boundary Alarm Trip register (16-bit read/write)
   SE_ALARM_LOW   = 0x03,     //(0000h) Lower Boundary Alarm Trip register (16-bit read/write)
   SE_ALARM_CRITICAL=0x04,    //(0000h) Critical Alarm Trip register (16-bit read/write)
   SE_TEMPERATURE = 0x05,     //(xxxxh) Temperature register (16-bit read-only)(See SE98_TempReg)
   SE_ID          = 0x06,     //(1131h) Manufacturer ID register (16-bit read-only)(ID=0x1131 for NXP Semiconductors)
   SE_REV         = 0x07,     //(A102h) Device ID/Revision register (16-bit read-only)(Ex.: ID=0xA1, Rev=0x02)
   SE_CONFIG_BUS  = 0x22      //(0000h) SMBus register(See SE98_CONFIG_BUS)
   };
   //08h to 21h 0000h reserved registers
   //23h to FFh 0000h reserved registers

#define SE_DEVICECODE   0b00110000     

/************
*   I2C address composition:   ddddxyzs
*
*   dddd  =  devicecode       //factory fixed devicecode
*   xyz   =  A2, A1, A0       //Hardware selectable address(0 to 7)
*   s     =  R/W              //1 write to, 0 read from
*/



/////////////////////////////////////////////////////////////////////////////////////////*/
/***************************       VALUE CODES       **********************************/

enum SE98_capability   {  //**Capability register (address 00h) bit allocation(READ ONLY)
   SE_RESERVED    = 0b1111111111000000,   //(R)15:6 RFU Reserved for future use. Must be zero.
   SE_VHV         = 0b0000000000100000,   //(R)5 VHV High voltage standoff for pin A0. This part can support a voltage up to 10 V on the A0 pin to support JC42.4 ballot 1435.00.
   SE_TRES        = 0b0000000000011000,   //(R)4:3 TRES Temperature resolution. 11 — 0.125 °C LSB (11-bit)
   SE_TRES0125    = 0b0000000000010000,   //(R)4:3 TRES Temperature resolution. 11 — 0.125 °C LSB (11-bit)
   SE_WRNG        = 0b0000000000000100,   //(R)2 WRNG Wider range. 1 — can read temperatures below 0 °C and set sign bit accordingly
   SE_HACC        = 0b0000000000000010,   //(R)1 HACC Higher accuracy (set during manufacture). B grade accuracy
   SE_BCAP        = 0b0000000000000001,   //(R)0 BCAP Basic capability. Has Alarm and Critical Trips interrupt capability.
   SE_CAPABILITIES= 0b0000000000111111    //For filtering all capabilities options
   };


enum SE98_config  {  //**Configuration register (address 01h) bit description
   SE_RESERVED1   = 0b1111100000000000,   //(R)15:11 reserved for future use; must be ‘0’.
   SE_HIST_DISABLE= 0b0000000000000000,   //(RW)Disable hysteresis(default)
   SE_HIST_1C     = 0b0000001000000000,   //(RW)Enable hysteresis at 1.5 °C. It´s sets histeresis of alarm conditions.
   SE_HIST_3C     = 0b0000010000000000,   //(RW)Enable hysteresis at 3 °C. It´s sets histeresis of alarm conditions.
   SE_HIST_6C     = 0b0000011000000000,   //(RW)Enable hysteresis at 6 °C. It´s sets histeresis of alarm conditions.
   SE_SHUTDOWN    = 0b0000000100000000,   //(RW)Shutdown SE98A. When shut down, the thermal sensor diode and Analog-to-Digital Converter(ADC) are disabled to save power, no events will be generated.
   SE_TRIPLOCK    = 0b0000000010000000,   //(RW)If Set, critical Alarm Trip register settings cannot be altered. This bit is initially cleared. When set, this bit will return a 1, and remains locked until cleared by internal Power-on reset. This bit can be written with a single write and do not require double writes.
   SE_ALARMLOCK   = 0b0000000001000000,   //(RW)If set, Upper and Lower Alarm Trip registers setting cannot be altered. This bit is initially cleared. When set, this bit will return a 1 and remains locked until cleared by internal power-on reset. This bit can be written with a single write and does not require double writes.
   SE_E_CLEAR     = 0b0000000000100000,   //(W)Clears active EVENT in Interrupt mode. When read, this register always returns zero.
   SE_E_STAT      = 0b0000000000010000,   //(R)Reads Event status(1 for set and 0 for reset, despite of output selected polarity, taht can be inverted).
   SE_E_OUTPUT    = 0b0000000000001000,   //(RW)Enable Event Output pin(open drain)
   SE_E_CRIT_OUT  = 0b0000000000000100,   //(RW)If set, output turns ON only in critical temperature event. If reset(default), output turns on in both alarm or critical temperature event.
   SE_E_POL_HIGH  = 0b0000000000000010,   //(RW)EVENT Polarity. Set this for active HIGH event pin. When either of the Critical Trip or Alarm Window lock bits is set, this bit cannot be altered until unlocked.
   SE_E_CRIT_ONLY = 0b0000000000000001,   //(RW)EVENT only if temperature is above the value in the critical temperature register. When the Critical Trip or Alarm Window lock bit is set, this bit cannot be altered until unlocked.
   SE_E_ALARM_EV  = 0b0000000000000000    //(RW)EVENT output on Alarm or Critical temperature event (default)
   };


enum SE98_bTempReg  {  //**Temperature register (16-bit read-only)
   SE_bCRYTICAL   =  15,      //(R)Bit 15: Above Critical Trip.
   SE_bALARM      =  14,      //(R)Bit 14: Above Alarm Window.
   SE_bNORMAL     =  13       /*(R)Bit 13: Below Alarm Window(Normal temperature)
   SE_bTEMPVAL    =  12       //(R)Bit 12 to 2: Temperature value(SE98A Format)
   SE_bDNA        =  1        //(R)Bit 1 to 0: Not used, always 0    */
   };
enum SE98_TempReg  {  //**Temperature register (16-bit read-only)
   SE_CRYTICAL    =  0b1000000000000000,  //(R)Bit 15: Above Critical Trip.
   SE_ALARM       =  0b0100000000000000,  //(R)Bit 14: Above Alarm Window.
   SE_NORMAL      =  0b0010000000000000,  //(R)Bit 13: Below Alarm Window(Normal temperature)
   SE_TEMPVAL     =  0b0001111111111100,   //(R)Bit 12 to 2: Temperature value(SE98A Format)
   SE_DNA         =  0b0000000000000011    //(R)Bit 1 to 0: Not used, always 0   
   };


enum SE98_CONFIG_BUS  {  //**SMBus register
   SE_SMBUS_Timeout=0b0000000010000000,   //(RW)disable SMBus time-out
   SE_SMBUS_Alert = 0b0000000000000001,   //disable SMBus ALERT
   };


_________________
Eduardo Guilherme Brandt
Eduardo__



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

PostPosted: Fri May 18, 2012 10:30 am     Reply with quote

SE98A.c driver main file(include this file)

Code:
/*
                              SE98A     (NXP/PHILIPS)
           DDR memory(or General) module temperature sensor, 1.7 V to 3.6 V
           
JEDEC (JC-42.4) TS3000B1 DIMM ± 0.5 °C (typ.) between 75 °C and 95 °C temperature sensor
* Optimized for voltage range: 1.7 V to 3.6 V
* Shutdown current: 0.1 µA (typ.) and 5.0 µA (max.)
* 2-wire interface: I2C-bus/SMBus compatible, 0 Hz to 400 kHz
* SMBus ALERT and TIMEOUT (programmable)
* 11-bit ADC Temperature-to-Digital converter with 0.125 °C resolution
* Operating current: 250 µA (typ.) and 400 µA (max.)
* Programmable hysteresis threshold: 0 °C, 1.5 °C, 3 °C, 6 °C
* Over/under/critical temperature EVENT output

PINOUT:
                      +-----U-----+
3bit I2C \     ->  A0 |1         8|VDD     <- Power Supply
address   >----->  A1 |2         7|EVENT   <- Open collector output for programmed events(Allarms, etc...)
Sellector/     ->  A2 |3         6|SCL     <- Connect to I2C bus here
Power Supply   ->  VSS|4         5|SDA     <- Connect to I2C bus here
                      +-----------+
                     
**********************************************************

Arquivo     :  SE98A.C
Programador :  Eduardo Guilherme Brandt                   
Criação     :  17/02/2012 ( V 1.0 )
Modificado  :  18/05/2012
Contato     :  Eduardogbrandt@yahoo.com.br - Indaial-SC, Brasil

Histórico   :  Versão 1.0 - 17/02/2012
                             

               
Functions   :
   ????See nSE98_commandList.c    //Do not include this file. It´s just for reference.
     

Further information:
   Ps:   *Define I2C pins(SE98_SCL, SE98_SDA)
         *Define I2C hardware controller stream SE98_I2C, too.
         *Define input pin(SE98_EVENT), if you need it
         *I2C can be configured till 400kHz for SE98A.

   REQUIRES:
            CCS PICC 4.124+,
            uC with I2C
            i2c_start(), i2c_write(), i2c_read() and i2c_stop() functions
           
   Command-set:       
            see SE98A.h header file
            ps: For more details, see SE98A datasheet.

   Config example: See in SE98_default_config() function




Eduardo Guilherme Brandt  17/11/2011   */
//////////////////////////////////////////////////////////////////////////////////////////
//
//

/*//Driver SE98.C
#define  SE98_SCL       NA       //Set in hardware I2C
#define  SE98_SDA       NA       //Set in hardware I2C
#define  SE98_EVENT     NA       //Not used
#define  SE98_I2C       STREAM_I2C//Redirects I2C port to SE98_I2C stream
#USE I2C(MASTER, FORCE_HW, I2C1, FAST=50000, STREAM=STREAM_I2C)    //Configura I2C1 via pinos padrao(hardware)
*/

#ifndef SE98_SCL       
   #ERROR SE98_SCL pin not defined!
#endif
#ifndef SE98_SDA       
   #ERROR SE98_SDA pin not defined!
#endif
#ifndef SE98_EVENT       
   #ERROR SE98_EVENT pin not defined!
#endif
#ifndef SE98_I2C
   #warning Initialize SE98_I2C stream for I2C communication with SE98A, as below:
   #warning #USE I2C(MASTER, FORCE_HW, I2C1, FAST=50000, STREAM=STREAM_I2C)    //Set I2C communication
   #warning #define SE98_I2C STREAM_I2C      //just to set I2C stream to SE98_I2C
   #warning I2C máx speed=400kHz for SE98A
#endif
//
//
//
#include <SE98A.h>     //HEADER FILE
//
//
//
/*****************************************************************************************
******************************************************************************************
*************************I2C handshake and I/O commands***********************************
*****************************************************************************************/
/*****************************************************************************************
******************************************************************************************
*************************I2C handshake and I/O commands***********************************
*****************************************************************************************/
/*****************************************************************************************
******************************************************************************************
*************************I2C handshake and I/O commands***********************************
*****************************************************************************************/
/*****************************************************************************************
******************************************************************************************
* DEFINED MACROS
* ex:   
*     RF24_select();    //Controls bit Chipselect
*/
#define SE98_i2c_start()   i2c_start(SE98_I2C)
#define SE98_i2c_read()    i2c_start(SE98_I2C)
#define SE98_i2c_write()   i2c_start(SE98_I2C)
#define SE98_i2c_stop()    i2c_start(SE98_I2C)
/*****************************************************************************************
******************************************************************************************
*
* SE98_setaddr : SET SE98A pointer register address
*
* Parameters:
*
* devaddr:     Address of device(0 to 7, selected in hardware A0, A1, A2 pins). You can use till 8 SE98A on the same I2C bus.
* SE98_reg:    SE98A pointer register address(See header file **Registers address list)
*
* ex:   
*     SE98_setaddr(0x00, SE_TEMPERATURE);    //Set SE98A pointer to temperature register.
*/
void SE98_setaddr(int8 devaddr, int8 SE98_reg) {      //SET SE98A pointer register address

   devaddr&=0b00000111;       //garantee to be a value from 0 to 7
   i2c_start();
   i2c_write((SE_DEVICECODE|(BYTE)(devaddr<<1))&0b11111110);   //garantee bit0 to be 0(it make a I2C WRITE command). Bits 6 to 7 must be the SE_DEVICECODE, factory fixed
   i2c_write(SE98_reg);       //Set SE98A pointer register address
   i2c_stop();
}//
/*****************************************************************************************
******************************************************************************************
*
* SE98_setaddr : WRITE data to SE98A at specific address
*
* Parameters:
*
* devaddr:     Address of device(0 to 7, selected in hardware A0, A1, A2 pins). You can use till 8 SE98A on the same I2C bus.
* SE98_reg:    SE98A pointer register address to write data(See header file **Registers address list)
* data:        16bit data to write
*
* ex:   
*     SE98_setaddr(0x00, SE_CONFIG, SE_SHUTDOWN);    //Set SE98A pointer to temperature register.
*/
void SE98_write(int8 devaddr, int8 SE98_reg, int16 data) {     //WRITE data to SE98A at specific address


   devaddr&=0b00000111;       //garantee to be a value from 0 to 7
   i2c_start();
   i2c_write((SE_DEVICECODE|(BYTE)(devaddr<<1))&0b11111110);   //garantee bit0 to be 0(it make a I2C WRITE command). Bits 6 to 7 must be the SE_DEVICECODE, factory fixed
   i2c_write(SE98_reg);       //Set SE98A pointer register address
   i2c_write(make8(data,1));  //write data MSB
   i2c_write(make8(data,0));  //write data LSB
   i2c_stop();
}//
/*****************************************************************************************
******************************************************************************************
*
* SE98_read : READ data from SE98A at specific address
*
* Parameters:
*
* devaddr:     Address of device(0 to 7, selected in hardware A0, A1, A2 pins). You can use till 8 SE98A on the same I2C bus.
* SE98_reg:    SE98A pointer register address to write data(See header file **Registers address list)
*
* returns:     Returns 16bit read data
*
* ex:   
*     long value;                               //temperature value in SE98A specific format(You must convert it)
*     signed int temperature;                   //temperature value in signed 8bit data format
*     value=SE98_setaddr(0x00, SE_TEMPERATURE); //Read from SE98A temperature register.
*     temperature=SE_conv16to8(value);          //Converts from SE98A format to signed int8(-50 to 125degree) format
*/
int16 SE98_read(int8 devaddr, int8 SE98_reg) {     //READ data from SE98A at specific address
int16 data=0;

   devaddr&=0b00000111;          //garantee to be a value from 0 to 7
   i2c_start();
   i2c_write((SE_DEVICECODE|(BYTE)(devaddr<<1))&0b11111110);   //garantee bit0 to be 0(it make a I2C WRITE command). Bits 6 to 7 must be the SE_DEVICECODE, factory fixed
   i2c_write(SE98_reg);          //Set SE98A pointer register address
   i2c_start();
   i2c_write((SE_DEVICECODE|(BYTE)(devaddr<<1))|0b00000001);   //garantee bit0 to be 1(it make a I2C READ command). Bits 6 to 7 must be the SE_DEVICECODE, factory fixed
   data=(int16)i2c_read()<<8;    //read data MSB
   data|=(int16)i2c_read(0);     //read data LSB(0 means without acknowledge bit)
   i2c_stop();
   return data;                  //Return read value
}//
/*****************************************************************************************
******************************************************************************************
*
* SE98_readlast : READ data from SE98A actual(last) register(set with SE98_setaddr() function)
*
* Parameters:
* devaddr:     Address of device(0 to 7, selected in hardware A0, A1, A2 pins). You can use till 8 SE98A on the same I2C bus.
*
* returns:     Returns 16bit read data
*
* ex:   
*     long value;   
*     value=SE98_setaddr(0x00);    //Read value from SE98A last register(set by SE98_setaddr()).
*/
int16 SE98_readlast(int8 devaddr) {    //READ data from SE98A actual(last) register(set with SE98_setaddr() function)
int16 data=0;

   devaddr&=0b00000111;          //garantee to be a value from 0 to 7
   i2c_start();
   i2c_write((SE_DEVICECODE|(BYTE)(devaddr<<1))|0b00000001);   //garantee bit0 to be 1(it make a I2C READ command). Bits 6 to 7 must be the SE_DEVICECODE, factory fixed
   data=(int16)i2c_read()<<8;    //read data MSB
   data|=(int16)i2c_read(0);     //read data LSB(0 means without acknowledge bit)
   i2c_stop();
   return data;                  //Return read value
}//
/*****************************************************************************************
******************************************************************************************
*************************General Driver commands******************************************
*****************************************************************************************/
/*****************************************************************************************
******************************************************************************************
*************************General Driver commands******************************************
*****************************************************************************************/
/*****************************************************************************************
******************************************************************************************
*************************General Driver commands******************************************
*****************************************************************************************/
/*****************************************************************************************
******************************************************************************************
* DEFINED FUNCTIONS
*
*
*/
/*****************************************************************************************
******************************************************************************************
* Inicialize tris ports of uC for SE98A
* ex:   SE98_initPorts();
*/
void SE98_initPorts() {    //Inicialize tris ports of uC for SE98A

   output_float(SE98_SCL);
   output_float(SE98_SDA);
}//
/*****************************************************************************************
******************************************************************************************
* Converts from signed int8(-50 to 125degree) to SE98A temperature format
*
* Parameters:
*
* val          signed 8bit value to be converted(-50 to 125degrees)
* returns      SE98A 16bit format value(of temperature, etc...)
*
*/
signed int16 SE_conv8to16(signed int8 val) {  //Converts from signed int8(-50 to 125degree) to SE98A temperature format
   int16 rv=0;   //return value
   
   rv=((int16)val<<4);
   if (bit_test(rv, 11)==true)   //if val was negative(7th val bit is now 11th rv bit)
      rv|=0b0001000000000000;    //Set 12th bit(it indicates that the value is negative for SE98A)
   return rv;
}//
/*****************************************************************************************
******************************************************************************************
* Converts from SE98A temperature format to signed int8(-55 to 127degree)
*
* Parameters:
*
* val          SE98A format value to be converted(16bit)
* returns      signed 8bit converted value(of temperature, etc...)
*
*/
//#define SE_conv16to8(xInt16)     make8(xInt16>>4,0);    //Converts from SE98A format to signed int8(-50 to 125degree) format, but not manage value higher than 127.
signed int8 SE_conv16to8(signed int16 val) {  //Converts from SE98A format to signed int8(-50 to 125degree) format
   signed int8 rv=0;   //return value

   if (bit_test(val, 11)==true) { //if val was larger than +127C
      rv=0b01111111;             //Consider vr as +127C, maximum readable temperature
   }                             //because signed 8bit int can fit only from -127 to +127 maximum.
   else {
      val=val>>4;                //discards values below comma(discarded the fractional value)
      rv=make8(val,0);           //gets low byte from val, already signed(1 degree precision)
   }
   return rv;
}//
/*****************************************************************************************
******************************************************************************************
* Converts from SE98A temperature format to float(-55.0 to 255.9degree)
*
* Parameters:
*
* val          SE98A format value to be converted(16bit)
* returns      float 32bit converted temperature value
*
*/
float SE_conv16tofloat(signed int16 val) {  //Converts from SE98A temperature format to float(-55.0 to 255.9degree)
   signed int16 val_h,val_l;
   float fval_h,fval_l;
   float rv=0;  //return value

   val_h=(val>>4)&0b0000000011111111;  //leave only integer value(left from comma)
   val_l=(val>>1)&0b0000000000000111;  //leave only right comma value(smaler than 1)
   if (bit_test(val, 12)==true) {//the value is negative
      val_h|=0b1111111100000000; //Turn the rest 1, to be val_h a negative int16
      val_h|=0b1111111111111000; //Turn the rest 1, to be val_h a negative int16
   }
   fval_h=val_h;
   fval_l=val_l;
   fval_l*=0.125;    //right comma multiply factor(see SE98A datasheet, topic "Temperature format")

   rv=fval_h+fval_l; //Sum integer with remainder
   return rv;
}//
/*****************************************************************************************
******************************************************************************************
* Configure SE98A with driver default values(Ititializes default configuration for chip)
* ex:   SE98_default_config(0x00);
*
*  da    Address of device(0 to 7, selected in hardware A0, A1, A2 pins). You can use till 8 SE98A on the same I2C bus.
*/
void SE98_default_config(int8 da) {  //Ititializes driver default configuration for SE98A chip

   SE98_write(da, SE_ALARM_UP, SE_conv8to16(80));  //Sets crytical allarm to 80degrees
   SE98_write(da, SE_CONFIG, SE_HIST_DISABLE|SE_E_CLEAR|SE_E_CRIT_ONLY);   //Set configuration
   //SE98_write(da, SE_CONFIG, SE_SHUTDOWN);
   delay_ms(130);    //Waits for the first temperature convertion
}
/*****************************************************************************************
******************************************************************************************
* Get SE98A temperature value(returns signed 8bit value, from -55 to +127degree)
*
* Parameters:
*
* devaddr      selected SE98A device address(from 0x00 to 0x07)
* returns      signed 8bit read temperature
*
*/
signed int8 SE98_get_temperature(int8 devaddr) {    //Get temperature from SE98A(returns signed 8bit value)
   int16 value;                                     //temperature value in SE98A specific format(You must convert it)

   value=SE98_read(devaddr, SE_TEMPERATURE);    //Read from SE98A temperature register.
   return SE_conv16to8(value);                       //returns temperature value in signed 8bit data format
}//
/*****************************************************************************************
******************************************************************************************
* Get SE98A temperature value(returns float value, from -55,0 to 255,9degrees)
*
* Parameters:
*
* devaddr      selected SE98A device address(from 0x00 to 0x07)
* returns      float 32bit read temperature
*
*/
float SE98_get_temperature_float(int8 devaddr) {    //Get temperature from SE98A(returns signed 8bit value)
   int16 value;                                     //temperature value in SE98A specific format(You must convert it)

   value=SE98_read(devaddr, SE_TEMPERATURE);    //Read from SE98A temperature register.
   return SE_conv16tofloat(value);                       //returns temperature value in signed 8bit data format
}//
//#define  SE98_get_temperature(xdevaddr)      SE_conv16to8(SE98_read(xdevaddr, SE_TEMPERATURE))
/*****************************************************************************************
******************************************************************************************
* Shutdown SE98A(low power mode)
*/
void SE98_shutdown(int8 devaddr) {     //Shutdown SE98A(low power mode)
int16 data;
   data=SE98_read(devaddr, SE_CONFIG);
   data|=SE_SHUTDOWN;   //sets shutdown bit
   SE98_write(devaddr, SE_CONFIG, data);
}//
/*****************************************************************************************
******************************************************************************************
* get out shutdown SE98A(normal power mode)
*/
void SE98_poweron(int8 devaddr) {      //get out shutdown SE98A(normal power mode)
int16 data;
   data=SE98_read(devaddr, SE_CONFIG);
   data&=~SE_SHUTDOWN;   //resets shutdown bit
   SE98_write(devaddr, SE_CONFIG, data);
}//
/*****************************************************************************************
******************************************************************************************
* Wakeup, waits for convertion, reads temperature, shutdown SE98A and returns converted temperature value
*
*  op:         Sleep if true(delay_ms(150) if false).
*              ps.:  you must configure wdt interrupt to occur(for 150ms or more).
*                    25ms is the SE98A adc temperature convertion time.
*
*  Returns:    signed int8 temperature value
*/
signed int8 SE98_wakeup_read_andshutdown(int8 devaddr, int1 op) {    //Wakeup, waits for convertion, reads temperature, shutdown SE98A and returns converted temperature value
   long val;                                 //temperature value in SE98A specific format(You must convert it)
   
   SE98_poweron(devaddr);
   if (op==true) sleep();                    //Sleep till interrupt occurs(you must configure sleep period for at least 150ms)
   else delay_ms(150);                       //Waits for the first temperature convertion
   val=SE98_read(devaddr, SE_TEMPERATURE);   //Read from SE98A temperature register.
   SE98_shutdown(devaddr);
   return SE_conv16to8(val);                 //returns temperature value in signed 8bit data format
}//
signed int8 SE98_wakeup_read_andshutdown(int8 devaddr) {    //(overloaded function)Wakeup, waits for convertion, reads temperature, shutdown SE98A and returns converted temperature value
   long val;                                 //temperature value in SE98A specific format(You must convert it)
   
   SE98_poweron(devaddr);
   delay_ms(150);                            //Waits for the first temperature convertion
   val=SE98_read(devaddr, SE_TEMPERATURE);   //Read from SE98A temperature register.
   SE98_shutdown(devaddr);
   return SE_conv16to8(val);                 //returns temperature value in signed 8bit data format
}//
/*****************************************************************************************
******************************************************************************************
******************************************************************************************
*****************************************************************************************/
/*****************************************************************************************
******************************************************************************************
******************************************************************************************
*****************************************************************************************/
/*****************************************************************************************
******************************************************************************************
******************************************************************************************
*****************************************************************************************/
/*****************************************************************************************
******************************************************************************************
******************************************************************************************
*****************************************************************************************/
/*****************************************************************************************
* Driver use example 1: Configure and Read temperature one time
*
* ps: At first, set SE98A I2C and control PINS
*     Then, include driver file.
*     Now, that´s all right
*     **YOU NOT NEED POWER_DOWN the device if you do not want to!
*
*/
void SE98A_driver_use_example() {    //Example of using this driver
signed int8 temperature;
float       float_temperature;
   SE98_initPorts();
   SE98_default_config(0x00);
   
   while(true) {
      SE98_poweron(0x00);  //get out shutdown SE98A(normal power mode)
      delay_ms(125);       //Wait for first conversion
      temperature=SE98_get_temperature(0x00);//Get temperature from SE98A(returns signed 8bit value)
      float_temperature=SE98_get_temperature_float(0x00);//Get temperature from SE98A(returns float value)
      SE98_shutdown(0x00); //Shutdown SE98A(low power mode)
      //do_something();    //If do_something() takes less than 125ms, you will get the same
      //                   //temperature value than last reading.
      delay_ms(10);        //put a break here to check whether the correct temperature was read
      delay_ms(10);
   }
}//
/*****************************************************************************************
******************************************************************************************
******************************************************************************************
*****************************************************************************************/


_________________
Eduardo Guilherme Brandt
Eduardo__



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

HOW TO USE DRIVER
PostPosted: Fri May 18, 2012 10:43 am     Reply with quote

Informe me if anyone find any bugs. Thanks.

----------------------------------------------------
HOW TO DO



Code:
Define uC, fuses, compiller,...


#USE I2C(MASTER, FORCE_HW, I2C1, FAST=50000, STREAM=STREAM_I2C)    //Configura I2C1 via pinos padrao(hardware)
...




//********** DEFINE PORT NAMES
//Driver SE98.C
#define  SE98_SCL       PIN_C3   //Set in hardware I2C
#define  SE98_SDA       PIN_C4   //Set in hardware I2C
#define  SE98_EVENT     NA       //Not used/OPTIONAL
#define  SE98_I2C       STREAM_I2C//Redirects I2C port to SE98_I2C stream






//INCLUDES_2   -  Drivers
#include <SE98A.C>               //Driver leitor de temperatura
...





void main() {
...
while(true) {
   ...
   
   SE98A_driver_use_example();
   
   }
}




It´s a pleasure to share it!
_________________
Eduardo Guilherme Brandt
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group