
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