Saturday, November 16, 2013

TMP100 - Pinguino OTG

El TMP100 y TMP101 son dispositivos comúnmente conocidos como "two-wire", caracterizado por soportar transmisiones en dos direcciones simultáneamente, disponibles en encapsulados SOT23-6. Para su funcionamiento estos no requieren de circuiteria adicional, agregando también que la resolución de estos sensores es de 0.0625 °C. Ademas estos presentan compatibilidad SMBus e I2C, permitiendo hasta 8 dispositivos en el mismo bus.

TMP100 y TMP101 son ideales para la medición de temperatura en diferentes medios. El rango de operación oscila entre los -55 °C y 125 °C.

Conexionado

Sistema de Conexionado Pinguino OTG - TMP 100

La interfaz de conexion es simple y no necesita de muchos componentes para su optimo funcionamiento, mas solo 2 resistores de 10 Kohm en modo pull-up necesarios para el SCL (clock input) y SDA (data I/O) del TMP100 que son requeridas por las especificacion I2C de Phillips.

Sistema de Operacion

La configuración de llamado del TMP100 soporta hasta 8 dispositivos por bus I2C mediante 2 pin de direccionamiento. En esta aplicación, ambos pines ADD0 y ADD1 serán puestos a GND, por lo que la dirección del TMP100 sera 0b1001000. Todo acceso al TMP100 requiere la dirección apropiada que consiste en la dirección del dispositivo mas 1 bit de lectura/escritura (adress+WR) seguido por la dirección del registro deseado a manipular, mas la configuración de dicho registro.

Proceso de configuración TMP100
1.- Inicio el I2C
2.- Envió la dirección apropiada del dispositivo (0x90 = 0b1001000(Adress) + 0(R/W))
3.- Direccion del registro 0x01 (configuracion de resolucion)
4.- Envio configuracion de resolucion (0x00 (9 bits),0x20 (10 bits), 0x40 (11 bits),0x60 (12 bits))
5.- Finalizo I2C
Proceso de lectura TMP100
1.- Inicio el I2C
2.- Envió la dirección apropiada del dispositivo (0x90 = 0b1001000(Adress) + 0(R/W))
3.- Direccion del registro 0x00 (lectura de temperatura)
4.- Envio peticion de lectura del registro (0x91 = 0b1001000(Adress) + 1(R/W))
5.- Finalizo I2C
Tabla 1.- Correspondencia al proceso de escritura/lectura TMP100.

La información mas detallada del funcionamiento del TMP100 se encontrara al final de la pagina en sus respectivo datasheet.

Codigo

/*----------------------------------------------------- 
Author: Jefferson Gova O'Neil--<>
Date: Sun Dec 23 23:35:47 2012
Description: Pinguino OTG - TMP 100, usando comunicacion I2C
programado y compilado en Windows x64, usando el IDE x.3 desatendido para windows.
-----------------------------------------------------*/
int Buffer[2];
float PRECISION = 0.00001;

void initI2C() 
     { 
         I2C1CON |= (1 << 15); 
         // 1 = Slew rate control disabled for Standard Speed mode (100 kHz); also disabled for 1 MHz mode 
         I2C1CONbits.DISSLW = 1; 
         // I2C1BRG = ((Fcy/FSCL) - (Fcy/10,000,000)) - 1 
         // In our case, Fcy = Fosc/2 => 40,000,000/2 => 20,000,000 
         // The desired FSCL = 100 kHz 
         // I2C1BRG = ((20,000,000/100,000) - (20,000,000/10,000,000)) - 1 
         // I2C1BRG = ((200) - (2)) - 1 
         // I2C1BRG = (198) - 1 = 197    
         I2C1BRG = 196; 
         //IntSetVectorPriority(INT_I2C1_VECTOR,2,2); 
         IFS0bits.I2C1MIF = 0; 
         IFS0bits.I2C1SIF = 0; 
         IFS0bits.I2C1BIF = 0; 
         IEC0bits.I2C1MIE = 0; 
         IEC0bits.I2C1SIE = 0; 
         IEC0bits.I2C1BIE = 0; 
     }
 
 void i2c_start(void) 
     { 
 
           int x = 0; 
 
           I2C1CONbits.ACKDT = 0; //Reset any previous Ack 
           delayMicroseconds(10); 
           I2C1CONbits.SEN = 1; //Initiate Start condition 
           Nop(); 
 
           //the hardware will automatically clear Start Bit 
           //wait for automatic clear before proceding 
           while (I2C1CONbits.SEN) 
           { 
           delayMicroseconds(1);            
           x++; 
           if (x > 100) break; 
           } 
 
          delayMicroseconds(2); 
 
     } 
 //*************************************************** 
     //function iniates a restart condition on bus 
     void i2c_restart(void) 
     { 
 
           int x = 0; 
 
           I2C1CONbits.RSEN = 1; //Initiate restart condition 
           Nop(); 
 
           //the hardware will automatically clear restart bit 
           //wait for automatic clear before proceding 
           while (I2C1CONbits.RSEN) 
           { 
           delayMicroseconds(1); 
           x++; 
           if (x > 100) break; 
           } 
 
           delayMicroseconds(2); 
 
     } 
 //*************************************************** 
     //Resets the I2C bus to Idle 
     void reset_i2c_bus(void) 
     { 
 
           int x = 0; 
 
           //initiate stop bit 
           I2C1CONbits.PEN = 1; 
 
           //wait for hardware clear of stop bit 
           while (I2C1CONbits.PEN) 
           { 
           delayMicroseconds(1); 
           x ++; 
           if (x > 100) break; 
           } 
 
           I2C1CONbits.RCEN = 0; 
           IFS0bits.I2C1MIF = 0; // Clear Interrupt 
           I2C1STATbits.IWCOL = 0; 
           I2C1STATbits.BCL = 0; 
           delayMicroseconds(10); 
 
     } 
 //*************************************************** 
     //basic I2C byte send 
     char send_i2c_byte(int data) 
     { 
 
           short i; 
 
           while (I2C1STATbits.TBF) { } 
           IFS0bits.I2C1MIF = 0; // Clear Interrupt 
           I2C1TRN = data; // load the outgoing data byte 
 
           // wait for transmission 
           for (i=0; i<5000; i++) 
           { 
           if (!I2C1STATbits.TRSTAT) break; 
           delayMicroseconds(1); 
           } 
           if (i == 5000) 
           { 
           return(1); 
           } 
 
           // Check for NO_ACK from slave, abort if not found 
           if (I2C1STATbits.ACKSTAT == 1) 
           { 
           reset_i2c_bus(); 
           return(1); 
 
           } 
           delayMicroseconds(2); 
           return(0); 
 
     } 
 
 
 //*************************************************** 
     //function reads data, returns the read data, no ack 
     char i2c_read(void) 
     { 
 
           int i = 0; 
           char data = 0; 
 
           //set I2C module to receive 
           I2C1CONbits.RCEN = 1; 
 
           //if no response, break 
           while (!I2C1STATbits.RBF) 
           { 
           i ++; 
           if (i > 5000) break; 
           } 
 
           //get data from I2CRCV register 
           data = I2C1RCV; 
 
           //return data 
           return data; 
 
     } 
 //*************************************************** 
     //function reads data, returns the read data, with ack 
     char i2c_read_ack(void) //does not reset bus!!! 
     { 
 
           int i = 0; 
           char data = 0; 
 
           //set I2C module to receive 
           I2C1CONbits.RCEN = 1; 
 
           //if no response, break 
           while (!I2C1STATbits.RBF) 
           { 
           i++; 
           if (i > 5000) break; 
           } 
 
           //get data from I2CRCV register 
           data = I2C1RCV; 
 
           //set ACK to high 
           I2C1CONbits.ACKEN = 1; 
 
           //wait before exiting 
           delayMicroseconds(10); 
 
           //return data 
           return data; 
 
     }  
 
 
 //*************************************************** 
     void I2Cwrite(char addr, char subaddr, char value) 
     { 
 
           i2c_start(); 
           send_i2c_byte(addr); 
           send_i2c_byte(subaddr); 
           send_i2c_byte(value); 
           reset_i2c_bus(); 
 
     }     
 //*************************************** 
 void I2Cgets(int addr, int subaddr,int length, int *data){
           int i = 0,counter = 0;
           i2c_start(); 
           send_i2c_byte(addr); 
           send_i2c_byte(subaddr); 
           delayMicroseconds(10); 
 
           i2c_restart(); 
           send_i2c_byte(addr | 0x01); 
           //set I2C module to receive 
           I2C1CONbits.RCEN = 1; 
 
           //if no response, break 
           while (!I2C1STATbits.RBF) 
           { 
           i++; 
           if (i > 5000) break; 
           }
         data[0] = I2C1RCV;  // store received data 
         while (IFS0bits.I2C1MIF == 0); 
         IFS0bits.I2C1MIF = 0;     counter = 1; 
         while (length != counter) 
         { 
             I2C1CONbits.ACKDT = 0; //Ack received data 
             I2C1CONbits.ACKEN = 1; 
             while (I2C1CONbits.ACKEN == 1);         I2C1CONbits.RCEN = 1; 
             while (I2C1CONbits.RCEN == 1); 
             data[counter] = I2C1RCV; 
             while (IFS0bits.I2C1MIF == 0); 
             IFS0bits.I2C1MIF = 0; 
             counter++; 
         } 
         I2C1CONbits.ACKDT = 1; //NAck received data 
         I2C1CONbits.ACKEN = 1;
 reset_i2c_bus(); 
 }
 
 char I2Cread(char addr, char subaddr) 
     { 
 
           char temp; 
 
           i2c_start(); 
           send_i2c_byte(addr); 
           send_i2c_byte(subaddr); 
           delayMicroseconds(10); 
 
           i2c_restart(); 
           send_i2c_byte(addr | 0x01); 
           temp = i2c_read(); 
 
           reset_i2c_bus(); 
           return temp; 
 
     } 
 //************************************     
     unsigned char I2Cpoll(char addr) 
     { 
 
           unsigned char temp = 0; 
 
           i2c_start(); 
           temp = send_i2c_byte(addr); 
           reset_i2c_bus(); 
 
           return temp; 
 
     }

void ReadTemperature(){
float Temperature;
unsigned char BufferTemperature[20]={};
char* StringTemperature =&BufferTemperature;

Temperature =((((Buffer[0]*256)|Buffer[1])>>4)*.0625);
StringTemperature = dtoa(BufferTemperature,Temperature);
CDC.printf("Temperatura : %s C\r\n", StringTemperature);
} 



void setup() {
    //run once:
    initI2C(); 
    }

void loop() {
    //run repeatedly:
    char dato = 0;
    I2Cwrite(0x90, 0x01, 0x60);
    I2Cgets(0x90,0x00,2,Buffer); 
    delay(1000);
    ReadTemperature();
    }



If you like our work in Jeal's Blog just subscribe yourself. Get our posts in your RSS reader or by email.
Written by Jefferson GoVa

Ingeniero en electronica con aficiones a escribir y compartir todo aquello que le llama la atencion o que su curiosidad atrapa..

#Curioseando #Perdiendoeltiempo #sinnadamejorquehacer.

No comments:

Post a Comment