Autor Tema: Comunicacion I2C y sensor de temperatura Tmp102  (Leído 4392 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado juankcba

  • PIC10
  • *
  • Mensajes: 7
Comunicacion I2C y sensor de temperatura Tmp102
« en: 30 de Marzo de 2012, 12:26:09 »

Buenos dias a todos los del foro... quisiera saber si algun Guru de los pic podria hecharme una mano con este problema.
Resulta que quiero comunicar un pic 18f67j10 con el sensor de temperatura tmp102, los tiempos de comunicación

 

 como pueden ver la comunicacion si buscan la hoja de datos de este sensor es i2c. y donde lo compre adjuntan el siguiente código http://wiring.org.co/learning/libraries/tmp102sparkfun.html

Código: [Seleccionar]
#include <Wire.h>

// From the datasheet the BMP module address LSB distinguishes
// between read (1) and write (0) operations, corresponding to
// address 0x91 (read) and 0x90 (write).
// shift the address 1 bit right (0x91 or 0x90), the Wire library only needs the 7
// most significant bits for the address 0x91 >> 1 = 0x48
// 0x90 >> 1 = 0x48 (72)

int sensorAddress = 0x91 >> 1;  // From datasheet sensor address is 0x91
                                // shift the address 1 bit right, the Wire library only needs the 7
                                // most significant bits for the address
byte msb;
byte lsb;
int temperature;

void setup()
{
  Serial.begin(9600);  // start serial communication at 9600bps
  Wire.begin();        // join i2c bus (address optional for master)
}

void loop()
{
  // step 1: request reading from sensor
  Wire.requestFrom(sensorAddress,2);
  if (2 <= Wire.available())  // if two bytes were received
  {
    msb = Wire.read();  // receive high byte (full degrees)
    lsb = Wire.read();  // receive low byte (fraction degrees)
    temperature = ((msb) << 4);  // MSB
    temperature |= (lsb >> 4);   // LSB
    Serial.print("Temperature: ");
    Serial.println(temperature*0.0625);
  }
  delay(500);  // wait for half a second
}


intentando traducirlo al mplab que es el que utilizo realice la siguiente función
Código: [Seleccionar]
void temperatura(void)
{
int sensorAddress = 0x91 >> 1;
char msb;
char lsb;
int temperature=0;
TRISDbits.TRISD6=1;
TRISDbits.TRISD5=1;
OpenI2C1(  MASTER, SLEW_OFF);

StartI2C2();
     WriteI2C1(sensorAddress);
WriteI2C1(2);
StopI2C1();


  if ( DataRdyI2C1() ) 
  {
     // receive high byte (full degrees)
    msb = ReadI2C2();  // receive high byte (full degrees)
    lsb = ReadI2C2();  // receive low byte (fraction degrees)
    temperature = ((msb) << 4);  // MSB
    temperature |= (lsb >> 4);   // LSB
    temperature =  temperature*0.0625
    //vGLCDTexto(45,42,"T:",ARIAL,1,1);
    deco(43, temperature);
  }
 
}
,

no estoy seguro de como inicializar el i2c a 9600baudios, tampoco estoy seguro que es lo que tengo que mandarle al sensor para que me de como respuesta la temperatura, la hoja de datos se encuentra en http://www.ti.com/lit/ds/symlink/tmp102.pdf gracias por cualquier ayuda que me puedan enviar.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Comunicacion I2C y sensor de temperatura Tmp102
« Respuesta #1 en: 30 de Marzo de 2012, 12:31:29 »
Dale una revisada al siguiente post: http://www.todopic.com.ar/foros/index.php?topic=33666.msg281825#msg281825

Luego, en C18 hay que utilizar IDLE_I2C, por ejemplo:

Código: C
  1. void vHW_i2c_Start(void){
  2.         IdleI2C();
  3.         StartI2C();
  4.         IdleI2C();
  5. }
  6. UINT8 ui8HW_i2c_Write(UINT8 Data){
  7.         UINT8 Ack;
  8.        
  9.         Ack=WriteI2C(Data);
  10.        
  11.         if(Ack==0){return(0);}
  12.         else{return(1);}
  13. }
  14. void vHW_i2c_ReStart(void){
  15.         RestartI2C();
  16.         IdleI2C();
  17. }
  18. UINT8 ui8HW_i2c_Read(UINT8 Ack){
  19.         UINT8 Data;
  20.                
  21.         Data=ReadI2C();
  22.         if(Ack==0){
  23.                 AckI2C();
  24.         }else{
  25.                 NotAckI2C();
  26.         }
  27.         IdleI2C();
  28.        
  29.         return(Data);
  30. }
  31.  
  32. void vHW_i2c_Stop(void){
  33.         StopI2C();
  34.         IdleI2C();
  35. }

Y para establecer la velocidad hay que trabajar con el registro SSPxADD:  Fosc/(4*(SSPxADD+1))


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado juankcba

  • PIC10
  • *
  • Mensajes: 7
Re: Comunicacion I2C y sensor de temperatura Tmp102
« Respuesta #2 en: 30 de Marzo de 2012, 13:13:24 »
Gracias suky voy a investigar y cuando lo termine posteo la funcion como para que la agreges a la biblioteca de funciones...

Desconectado juankcba

  • PIC10
  • *
  • Mensajes: 7
Re: Comunicacion I2C y sensor de temperatura Tmp102
« Respuesta #3 en: 31 de Marzo de 2012, 19:04:50 »
Bueno a la fuerza esto es lo que codifique, tomando de ejemplo un codigo para otro micro y lo que lei en el foro suki...

Código: [Seleccionar]
void temperatura(void)
{
char temperature;
TRISDbits.TRISD6=1;
TRISDbits.TRISD5=1;
OpenI2C2(MASTER,SLEW_OFF);
//SSP1ADD =11;
temperature=tmp102read();
Delay10KTCYx(100); //delay de 500ms
}
char tmp102read(void)
{
char msb, lsb;
char temp;

StartI2C2() ;
    IdleI2C2() ;

WriteI2C2(TMP_WR); //We want to write a value to the TMP
IdleI2C2();

WriteI2C2(TEMP_REG); //Set pointer regster to temperature register (it's already there by default, but you never know)
IdleI2C2();

StartI2C2() ;

WriteI2C2(TMP_RD); // Read from this I2C address, R/*W Set
IdleI2C2();

    transpc('1');

AckI2C2();
    IdleI2C2();
msb =  ReadI2C2(); //Read the MSB data
IdleI2C2();
    transpc('2');

NotAckI2C2() ;
IdleI2C2();
lsb = ReadI2C2(); //Read the LSB data
IdleI2C2();

StopI2C2();
deco(12,msb);vGLCDUpdate();
deco(23,lsb);vGLCDUpdate();
//printf("0x%02X ", msb);
//printf("0x%02X ", lsb);

//Test
msb = 0b11100111;
lsb = 0b00000000; //From the datasheet, -25C
deco(12,msb);vGLCDUpdate();
deco(23,lsb);vGLCDUpdate();

temp = (msb<<8) | lsb;
temp >>= 4; //The TMP102 temperature registers are left justified, correctly right justify them

//The tmp102 does twos compliment but has the negative bit in the wrong spot, so test for it and correct if needed
if(temp & (1<<11))
temp |= 0xF800; //Set bits 11 to 15 to 1s to get this reading into real twos compliment

//printf("%02d\n", temp);

//But if we want, we can convert this directly to a celsius temp reading
//temp *= 0.0625; //This is the same as a divide by 16
//temp >>= 4; //Which is really just a shift of 4 so it's much faster and doesn't require floating point
//Shifts may not work with signed ints (negative temperatures). Let's do a divide instead
temp /= 16;

return(temp);
}

pero bueno tengo problemas con el registro de la velocidad... cuando lo pongo slew on se tilda si lo pongo en low llega hasta transpc(1) y despues se tilda... seguro pinta ser problema de velocidad o que no recibe los datos lo que intente traducir es lo siguiente

Código: [Seleccionar]
int16_t tmp102Read(void)
{

uint8_t msb, lsb;
int16_t temp;

i2cSendStart();
    i2cWaitForComplete();

i2cSendByte(TMP_WR); //We want to write a value to the TMP
i2cWaitForComplete();

i2cSendByte(TEMP_REG); //Set pointer regster to temperature register (it's already there by default, but you never know)
i2cWaitForComplete();

i2cSendStart();

i2cSendByte(TMP_RD); // Read from this I2C address, R/*W Set
i2cWaitForComplete();

i2cReceiveByte(TRUE);
i2cWaitForComplete();
msb = i2cGetReceivedByte(); //Read the MSB data
i2cWaitForComplete();

i2cReceiveByte(FALSE);
i2cWaitForComplete();
lsb = i2cGetReceivedByte(); //Read the LSB data
i2cWaitForComplete();

i2cSendStop();

//printf("0x%02X ", msb);
//printf("0x%02X ", lsb);

//Test
//msb = 0b11100111;
//lsb = 0b00000000; //From the datasheet, -25C

temp = (msb<<8) | lsb;
temp >>= 4; //The TMP102 temperature registers are left justified, correctly right justify them

//The tmp102 does twos compliment but has the negative bit in the wrong spot, so test for it and correct if needed
if(temp & (1<<11))
temp |= 0xF800; //Set bits 11 to 15 to 1s to get this reading into real twos compliment

//printf("%02d\n", temp);

//But if we want, we can convert this directly to a celsius temp reading
//temp *= 0.0625; //This is the same as a divide by 16
//temp >>= 4; //Which is really just a shift of 4 so it's much faster and doesn't require floating point
//Shifts may not work with signed ints (negative temperatures). Let's do a divide instead
temp /= 16;

return(temp);
}

void ioinit(void)
{
//1 = output, 0 = input
    DDRB = 0b11111111;
    DDRC = 0b11111111;
    DDRD = 0b11111111;

PORTC = 0b00110000; //pullups on the I2C bus

    //Init Timer0 for delay_us
TCCR0B = (1<<CS01); //Set Prescaler to clk/8 : 1click = 0.5us(assume we are running at external 16MHz). CS01=1

    //Setup USART baud rate
    UBRR0H = SERIAL_MYUBRR >> 8;
    UBRR0L = SERIAL_MYUBRR;
    UCSR0B = (1<<RXEN0)|(1<<TXEN0); //No receive interrupt
UCSR0A &= ~(1<<U2X0); //This clears the double speed UART transmission that may be set by the Arduino bootloader

    stdout = &mystdout; //Required for printf init
}

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Comunicacion I2C y sensor de temperatura Tmp102
« Respuesta #4 en: 01 de Abril de 2012, 08:55:14 »
Pero escribiendo sobre SSP1ADD, que velocidad elegiste? 100kHz?
No contesto mensajes privados, las consultas en el foro

Desconectado juankcba

  • PIC10
  • *
  • Mensajes: 7
Re: Comunicacion I2C y sensor de temperatura Tmp102
« Respuesta #5 en: 01 de Abril de 2012, 14:20:04 »
habia elegido 400k pero me da 11,5 probando con 100k el valor es 49, sucede lo mismo llega hasta el ack y se tilda ahi
« Última modificación: 01 de Abril de 2012, 14:24:52 por juankcba »

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Comunicacion I2C y sensor de temperatura Tmp102
« Respuesta #6 en: 01 de Abril de 2012, 14:28:23 »
Tiene las resistencias pull-up?
No contesto mensajes privados, las consultas en el foro

Desconectado juankcba

  • PIC10
  • *
  • Mensajes: 7
Re: Comunicacion I2C y sensor de temperatura Tmp102
« Respuesta #7 en: 01 de Abril de 2012, 14:45:49 »
Si eso ya viene todo en el la placa... las resistencias y tiene un pequeño capacitor también


 

anything