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
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 |
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(); }
Download Zone
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