Autor Tema: Leyendo BMP085(sensor presion) en xc8  (Leído 7269 veces)

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

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Leyendo BMP085(sensor presion) en xc8
« en: 03 de Junio de 2013, 14:44:20 »
Hola Amigos ....hace ya un tiempo que vengo tratando de armar una subrutina para leer el sensor de bosch BMP085 por i2c ....y primero me encontre con problemas de i2c ...aparentemente estan solucionados ....estoy usando un pic16f819 ....programo en mplabx ...la libreria  i2c compila ...no se si funciona todavia pero compila , ahora tengo una libreria del BMP085 ....y seguramente por mi falta de experiencia me encuentro con errores del tipo illegal conversion between types  non-scalar types can't be converted to other types

los errores estan en estas lineas

 msb=i2c_read(0); // Leer la direccion

 lsb=i2c_read(0); // Read address


les paso el codigo a ver si me pueden dar una mano ...muchas gracias


i2c.c

Código: [Seleccionar]
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include "delay.h"
#include <delays.h>
#include "i2c.h"


#define SDA_PIN PORTBbits.RB1 //
#define SCL_PIN PORTBbits.RB4 //

#define SDA_DIR TRISBbits.TRISB1
#define SCL_DIR TRISBbits.TRISB4



// Common I2C Routines

void i2c_restart(void)
{
i2c_low_scl(); /* ensure clock is low */
i2c_high_scl(); /* ensure data is high */
SCL_DIR = 1;                        /* clock pulse high */
i2c_low_sda(); /* the high->low transition */
return;
}


void i2c_read(unsigned short r_byte)
{
   int  n;
   i2c_high_sda();
   for (n=0; n<8; n++)
   {
      i2c_high_scl();

      if (SDA_PIN)
      {
         r_byte = (r_byte << 1) | 0x01; // msbit first
      }
      else
      {
         r_byte = r_byte << 1;
      }
      i2c_low_scl();
   }
   return;
}

void i2c_write(signed char w_byte)

{
    int m ;
   for(m=0; m<8; m++)
   {
      if(w_byte&0x80)
      {
         i2c_high_sda();
      }
      else
      {
         i2c_low_sda();
      }
      i2c_high_scl();
      i2c_low_scl();
      w_byte = w_byte << 1;
   }
   i2c_high_sda();
}

void i2c_nack(void)
{
   i2c_high_sda(); // data at one
   i2c_high_scl(); // clock pulse
   i2c_low_scl();
}

void i2c_ack(void)
{
   i2c_low_sda(); // bring data low and clock
   i2c_high_scl();
   i2c_low_scl();
   i2c_high_sda();
}


void i2c_start(void)
{
   i2c_low_scl();
   i2c_high_sda();
   i2c_high_scl(); // bring SDA low while SCL is high
   i2c_low_sda();
   i2c_low_scl();
}

void i2c_stop(void)
{
   i2c_low_scl();
   i2c_low_sda();
   i2c_high_scl();
   i2c_high_sda();  // bring SDA high while SCL is high
   // idle is SDA high and SCL high
}

void i2c_high_sda(void)
{
   // bring SDA to high impedance
   SDA_DIR = 1;
   DelayUs(5);
}

void i2c_low_sda(void)
{
   SDA_PIN = 0;
   SDA_DIR = 0;  // output a hard logic zero
   DelayUs(5);
}

void i2c_high_scl(void)
{
   SCL_DIR = 1;   // high impedance
   DelayUs(5);
}

void i2c_low_scl(void)
{
   SCL_PIN = 0;
   SCL_DIR = 0;
   DelayUs(5);
}




BMP085.c

Código: [Seleccionar]
/************************************************************************
* Defines ***** Definiciones *
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "delay.h"
#include <delays.h>
#include <xc.h>
#include "BMP085.h"
#define BMP085_R 0xEF // Write address
#define BMP085_W 0xEE // Read address
#define OSS 0 // Oversampling Setting

/************************************************************************
* Globar Vars and Constants ***** Variables y Constates globales *
************************************************************************/
const unsigned char OSS_conversion_time[] = {5, 8, 14, 26};

signed short ac1;
signed short ac2;
signed short ac3;
signed short b1;
signed short b2;
signed short mb;
signed short mc;
signed short md;
unsigned short ac4;
unsigned short ac5;
unsigned short ac6;
signed char but,bup;
unsigned char shift;


/************************************************************************
* Function Prototypes *
************************************************************************/

void BMP085_Calibration(void);
long bmp085Read2Bytes(unsigned char address);
unsigned long bmp085Read3Bytes(unsigned char address);
long bmp085ReadTemp(void);
long bmp085ReadPressure(void);
void bmp085Convert(long *temperature, long *pressure,unsigned char readings);




/************************************************************************
* *
* Purpose: Will read two (or 3) sequential 8-bit registers, *
* and Return a 16-bit value. *
* Proposito: Leer 2 registros de 8 bits secuenciales y regresar *
* un valor de 16bits. *
* Passed: Address - Unsigned char *
* Argumento: Direccion *
* Returned: Reading - Long *
* Retorno: Lectura *
* Note: Return value must be typecast to an signed short *
* if reading a signed value! *
* *
************************************************************************/

long bmp085Read2Bytes(unsigned char address)
{
   unsigned short msb, lsb;
   long data=0;

   delay_ms(10);

   i2c_start();
   i2c_write(BMP085_W); // Escribir la direccion del sensor
   i2c_write(address); // Direccion de memoria
   i2c_start(); // Reinicio
   i2c_write(BMP085_R); // Direccion para leer del sensor
   msb = i2c_read(0); // Leer la direccion
   delay_ms(10);
   i2c_stop(); // Parar

   delay_ms(10);

   i2c_start();
   i2c_write(BMP085_W); // Write required to clock in address
   i2c_write(address+1); // Mem address
   i2c_start(); // Restart
   i2c_write(BMP085_R); // Device address for reading
   lsb=i2c_read(0); // Read address
   delay_ms(10);
   i2c_stop(); // Stop

   data = msb << 8;
   data = data | lsb;

   return data;
}

unsigned long bmp085Read3Bytes(unsigned char address)
{
   unsigned short msb,lsb,xlsb;
   unsigned long data=0;

   delay_ms(10);

   i2c_start();
   i2c_write(BMP085_W); // Escribir la direccion del sensor
   i2c_write(address); // Direccion de memoria
   i2c_start(); // Reinicio
   i2c_write(BMP085_R); // Direccion para leer del sensor
   msb=i2c_read(0); // Leer la direccion
   delay_ms(10);
   i2c_stop(); // Parar



   delay_ms(10);

   i2c_start();
   i2c_write(BMP085_W); // Write required to clock in address
   i2c_write(address+1); // Mem address
   i2c_start(); // Restart
   i2c_write(BMP085_R); // Device address for reading
   lsb=i2c_read(0); // Read address
   delay_ms(10);
   i2c_stop(); // Stop

   delay_ms(10);

   i2c_start();
   i2c_write(BMP085_W); // Write required to clock in address
   i2c_write(address+2); // Mem address
   i2c_start(); // Restart
   i2c_write(BMP085_R); // Device address for reading
   xlsb=i2c_read(0); // Read address
   delay_ms(10);
   i2c_stop(); // Stop





   data = (msb << 8);
   data = (data | lsb);
   data = (data << 8);
   data = (data | xlsb);
   data = (data >> (8-OSS));


   return data;
}
/************************************************************************
*
* Purpose: Calibrates the BMP085 pressure sensor.
* Passed: Void
* Returned: Void
* Note:
*
************************************************************************/
void BMP085_Calibration(void)
{
  /* ac1 = 6690;
ac2 = -1227;
ac3 = -14421;
ac4 = 33898;
ac5 = 24422;
ac6 = 22886;
b1 = 5498;
b2 = 66;
mb = -32768;
mc = -11075;
md = 2432;
*/
   ac1 = bmp085Read2Bytes(0xAA);
   ac2 = bmp085Read2Bytes(0xAC);
   ac3 = bmp085Read2Bytes(0xAE);
   ac4 = bmp085Read2Bytes(0xB0);
   ac5 = bmp085Read2Bytes(0xB2);
   ac6 = bmp085Read2Bytes(0xB4);
   b1 = bmp085Read2Bytes(0xB6);
   b2 = bmp085Read2Bytes(0xB8);
   mb = bmp085Read2Bytes(0xBA);
   mc = bmp085Read2Bytes(0xBC);
   md = bmp085Read2Bytes(0xBE);
/*
printf("%Ld \n",ac1);
printf("%Ld \n",ac2);
printf("%Ld \n",ac3);
printf("%Lu \n",ac4);
printf("%Lu \n",ac5);
printf("%Lu \n",ac6);
printf("%Ld \n",b1);
printf("%Ld \n",b2);
printf("%Ld \n",mb);
printf("%Ld \n",mc);
printf("%Ld \n",md);
*/
}


/************************************************************************
*
* Purpose: Will read the 16-bit temperature value of BMP085 sensor.
* Passed: Void
* Returned: Long
* Note:
*
************************************************************************/
long bmp085ReadTemp(void)
{
   i2c_start();

   i2c_write(BMP085_W); // Write 0xEE
   i2c_write(0xF4); // Write register address
   i2c_write(0x2E); // Write register data for temp

   i2c_stop();

   delay_ms(10); // Max time is 4.5ms

   return bmp085Read2Bytes(0xF6);
}

/************************************************************************
*
* Purpose: Will read the 16-bit pressure value from BMP085 sensor.
* Passed: Void
* Returned: Long
* Note:
*
************************************************************************/
unsigned long bmp085ReadPressure(void)
{
   i2c_start();

   i2c_write(BMP085_W); // Write 0xEE
   i2c_write(0xF4); // Write register address
   i2c_write(0x34 | (OSS << 6)); // Write register data for temp

   i2c_stop();

   delay_ms(OSS_conversion_time[OSS]); // Max time is 4.5ms

   return bmp085Read3Bytes(0xF6);

}

/************************************************************************
*
* Purpose: Will find callibrated pressure + temperature
* Passed: Long *temperature, long *pressure, unsigned char readings
* Returned: Void
* Note:
*
************************************************************************/

// The bit-shift for possibly negative numbers.
// Note that divide has a higher precedence than
// bit shift, so this is not precisely the same.

void bmp085Convert(float *temperature, float *pressure)
{
   unsigned long ut,up;
   //float32 b5, b6, x3, b3, p, b4, b7;
   signed long aux1,aux2,aux3,aux4;

   signed long c3,c4,c5,c6,bb1,mmc,mmd,x,x0,x1,x2,y,y0,y1,y2,p0,p1,p2,z,s,alpha,temp,pres;

   ut = bmp085ReadTemp();
   ut = bmp085ReadTemp();
   up = bmp085ReadPressure();
   up = bmp085ReadPressure();

   //ut = 0x7B50;
   //up = 0x883F;
   //printf("%LX \n",ut);
   //printf("%LX \n",up);

   //but = ut; //Debug var

/*NEW CALCS*/

   c3 = 160*pow(2,-15)*ac3;
   c4 = pow(10,-3)*pow(2,-15)*ac4;
   bb1 = 25600*pow(2,-30)*b1;

   //printf("%e \n",c3);
   //printf("%e \n",c4);
   //printf("%e \n",bb1);

   c5 = ac5*pow(2,-15)/160;
   c6 = ac6;
   mmc = (0.08)*mc;
   mmd = md/160;

   //printf("%e \n",c5);
   //printf("%e \n",c6);
   //printf("mmc\n");
   //printf("%e \n",mmc);
   //printf("%e \n",mmd);

   x0 = ac1;
   x1 = 160*pow(2,-13)*ac2;
   x2 = 25600*pow(2,-25)*b2;

   //printf("%e \n",x0);
   //printf("%e \n",x1);
   //printf("%e \n",x2);

   y0 = c4*32768;
   y1 = c4*c3;
   y2 = c4*bb1;

   //printf("%e \n",y0);
   //printf("%e \n",y1);
   //printf("%e \n",y2);

   p0 = 3783/1600;
   p1 = 1-7357*pow(2,-20);
   p2 = 3038*100*pow(2,-36);

   //printf("%e \n",p0);
   //printf("%e \n",p1);
   //printf("%e \n",p2);

   /*Calculamos temperatura*/
   alpha = c5*(ut-c6);
   temp = alpha + (mmc/(alpha+mmd));


   /*Calculamos presion*/
   s = temp - 25;
   x = x2*s*s+x1*s+x0;
   y = y2*s*s+y1*s+y0;
   z = (up-x)/y;
   pres = p2*z*z+p1*z+p0;



   *temperature = temp;
   *pressure = pres;


/**/


/****************BEGIN*****CALC*****TEMP*********************/

/*
aux1 = ut-ac6;
aux2 = aux1*ac5;
x1 = aux2/32768;
//x1 = ((ut - ac6) * ac5 / pow(2,15));
aux3 = x1+md;
aux4 = mc/aux3;
x2 = aux4*2048;
//x2 = (mc * (pow(2,11))) / (x1 + md);
b5 = x1 + x2;
*temperature = ((b5 + 8) / 16);

/****************END*****CALC*****TEMP***********************/


/****************BEGIN*****CALC*****PRES*********************/
/*

up = up >> (8-OSS);
//bup = up; //Debug var
b6 = b5 - 4000;
aux1 = b6*b6;
aux2 = aux1/4096;
aux3 = aux2*b2;
x1 = aux3/2048;
//x1 = (b2 * (b6 * b6 / pow(2,12))) / pow(2,11);
aux1 = ac2*b6;
x2 = aux1/2048;
//x2 = ac2 * b6 / pow(2,11);
x3 = x1 + x2;

aux1 = ac1*4;
aux2 = aux1+x3;
shift = aux2;
aux3 = shift << OSS;
aux4 = aux3+2;
b3 = aux4/4;
//b3 = ((((ac1 * 4) + x3) << OSS) + 2) / 4;
aux1 = ac3*b6;
x1 = aux1/8192;
//x1 = ac3 * b6 / pow(2,13);
aux1 = b6*b6;
aux2 = aux1/4096;
aux3 = aux2*b1;
x2 = aux3/65536;
//x2 = (b1 * (b6 * b6 / pow(2,12))) / pow(2,16);
aux1 = x1+x2+2;
x3 = aux1/4;
//x3 = ((x1 + x2) + 2) / pow(2,2);
aux1 = x3+32768;
aux2 = ac4*aux1;
b4 = aux2/32768;
//b4 = (ac4 * (unsigned long) (x3 + 32768)) / pow(2,15);
aux1 = up-b3;
aux2 = 50000>>OSS;
b7 = aux1*aux2;
//b7 = ((unsigned long) up - b3) * (50000 >> OSS);
if (b7 < 0x80000000)
{
aux1 = b7*2;
p = aux1/b4;
}
else
{
aux1 = b7/b4;
p = aux1*2;
}

aux1 = p/256;
x1 = aux1*aux1;
//x1 = p / pow(2,8);
//x1 *= x1;
aux2 = x1*3038;
x1 = aux2/65536;
//x1 = (x1 * 3038) / pow(2,16);
aux1 = -7357*p;
x2 = aux1/65536;
//x2 = (-7357 * p) / pow(2,16);
aux1 = x1+x2+3791;
aux2 = aux1/16;
p = p+aux2;
*pressure = p;
/****************END*****CALC*****PRES***********************/
}
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Leyendo BMP085(sensor presion) en xc8
« Respuesta #1 en: 03 de Junio de 2013, 15:15:50 »
Si te fijas bien, i2c_read está definida como una función que no devuelve valor

Código: C
  1. void funcion(xxxx)

Justamente delante del nombre de la función se indica el tipo de valor que devuelve..

Sin embargo es una función a la cual se le pasa un parámetro -ya que está indicado dentro del paréntesis- y, es casi seguro, que usa esa misma variable para devolver el valor.

Por lo tanto deberías probar de escribir tu código así...

Código: C
  1. i2c_read(msb);
  2. i2c_read(lsb);

supongo que entre ambas lecturas deberás intercalar i2c_ack() para indicarle al dispositivo que el micro recibió el dato y está listo para recibir el siguiente. Quedando algo así

Código: C
  1. i2c_read(msb);
  2. i2c_ack();
  3. i2c_read(lsb);
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Leyendo BMP085(sensor presion) en xc8
« Respuesta #2 en: 03 de Junio de 2013, 16:58:01 »
Gracias AngelGris ...logre que compile ...solo me da warnings --warning: local variable "_msb" is used but never given a value

si mal no recuerdo esto sucede porque la variable lsb y msb estan declaradas pero no tienen valor ?? no recuedo como se soluciona ....era haciendolas cero al principio ???

Muchas gracias
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Leyendo BMP085(sensor presion) en xc8
« Respuesta #3 en: 03 de Junio de 2013, 21:56:06 »
  Rseliman, estoy releyendo tus post y me encuentro con una duda... ¿las rutinas de I2C las has hecho tu?

  Me parece que hay un error. De hecho, creo que i2c_read() nunca funcionaría. Sinceramente me has hecho dudar  :oops: pero creo que la única forma que tiene una función para devolver un valor es definiendola para que devuelva

por ejemplo
Código: C
  1. unsigned char i2c_read();

o manejar una variable global y modificarla dentro de la función.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Leyendo BMP085(sensor presion) en xc8
« Respuesta #4 en: 03 de Junio de 2013, 22:20:26 »
  Rseliman, estoy releyendo tus post y me encuentro con una duda... ¿las rutinas de I2C las has hecho tu?

  Me parece que hay un error. De hecho, creo que i2c_read() nunca funcionaría. Sinceramente me has hecho dudar  :oops: pero creo que la única forma que tiene una función para devolver un valor es definiendola para que devuelva

por ejemplo
Código: C
  1. unsigned char i2c_read();

o manejar una variable global y modificarla dentro de la función.

Como estas AngelGris ...la rutina i2c las he estado buscando por todos lados y la verdad es que para xc8 hay muy poco de todo ...asi que esta rutina es una mezcla de lo que encontre .......no se si funcionara todavia ...no la he probado ...pero al menos queria hacer algo para desp sobre la marcha ir modificando lo que no funcione ...voy a tener en cuenta lo que me decis ...y ovbiamente te voy a seguir consultando sobre la marcha ...a ver que sale de todo esto ...por lo menos para que alguien que busque i2c para xc8 encuentre !!!

Gracias
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Leyendo BMP085(sensor presion) en xc8
« Respuesta #5 en: 04 de Junio de 2013, 13:58:51 »
Bueno paso en limpio como va esto ....


bmp085.c

Código: [Seleccionar]
/************************************************************************
* *
* Module: BMP085.c *
* Description: BMP085-specific code. *
* *
* *
* Date: Authors: Comments: *
* 18 Feb 2012 Jose Morales Created *
* *
* *
************************************************************************/


/************************************************************************
* Defines ***** Definiciones *
************************************************************************/

#include "math.h"
#include "i2c.h"
#define BMP085_R 0xEF // Write address
#define BMP085_W 0xEE // Read address
#define OSS 0 // Oversampling Setting

/************************************************************************
* Globar Vars and Constants ***** Variables y Constates globales *
************************************************************************/
const unsigned char OSS_conversion_time[] = {5, 8, 14, 26};

signed short ac1;
signed short ac2;
signed short ac3;
signed short b1;
signed short b2;
signed short mb;
signed short mc;
signed short md;
unsigned short ac4;
unsigned short ac5;
unsigned short ac6;
signed char but,bup;
unsigned char shift;


/************************************************************************
* Function Prototypes *
************************************************************************/

//void BMP085_Calibration(void);
//long bmp085Read2Bytes(unsigned char address);
//unsigned long bmp085Read3Bytes(unsigned char address);
//long bmp085ReadTemp(void);
//unsigned long bmp085ReadPressure(void);
//void bmp085Convert(signed long *temperature, signed long *pressure);




/************************************************************************
* *
* Purpose: Will read two (or 3) sequential 8-bit registers, *
* and Return a 16-bit value. *
* Proposito: Leer 2 registros de 8 bits secuenciales y regresar *
* un valor de 16bits. *
* Passed: Address - Unsigned char *
* Argumento: Direccion *
* Returned: Reading - Long *
* Retorno: Lectura *
* Note: Return value must be typecast to an signed short *
* if reading a signed value! *
* *
************************************************************************/

long bmp085Read2Bytes(unsigned char address)
{
   unsigned short msb, lsb;
   msb,lsb = 0;
   long data=0;

   delay_ms(10);

   i2c_start();
   i2c_write(BMP085_W); // Escribir la direccion del sensor
   i2c_write(address); // Direccion de memoria
   i2c_start(); // Reinicio
   i2c_write(BMP085_R); // Direccion para leer del sensor
   i2c_read(msb); // Leer la direccion
   delay_ms(10);
   i2c_stop(); // Parar

   delay_ms(10);

   i2c_start();
   i2c_write(BMP085_W); // Write required to clock in address
   i2c_write(address+1); // Mem address
   i2c_start(); // Restart
   i2c_write(BMP085_R); // Device address for reading
   i2c_read(lsb); // Read address
   delay_ms(10);
   i2c_stop(); // Stop

   data = msb << 8;
   data = data | lsb;

   return data;
}

unsigned long bmp085Read3Bytes(unsigned char address)
{
   unsigned short msb,lsb,xlsb;
   unsigned long data=0;

   delay_ms(10);

   i2c_start();
   i2c_write(BMP085_W); // Escribir la direccion del sensor
   i2c_write(address); // Direccion de memoria
   i2c_start(); // Reinicio
   i2c_write(BMP085_R); // Direccion para leer del sensor
   i2c_read(msb); // Leer la direccion
   delay_ms(10);
   i2c_stop(); // Parar



   delay_ms(10);

   i2c_start();
   i2c_write(BMP085_W); // Write required to clock in address
   i2c_write(address+1); // Mem address
   i2c_start(); // Restart
   i2c_write(BMP085_R); // Device address for reading
   i2c_read(lsb); // Read address
   delay_ms(10);
   i2c_stop(); // Stop

   delay_ms(10);

   i2c_start();
   i2c_write(BMP085_W); // Write required to clock in address
   i2c_write(address+2); // Mem address
   i2c_start(); // Restart
   i2c_write(BMP085_R); // Device address for reading
   i2c_read(xlsb); // Read address
   delay_ms(10);
   i2c_stop(); // Stop





   data = (msb << 8);
   data = (data | lsb);
   data = (data << 8);
   data = (data | xlsb);
   data = (data >> (8-OSS));


   return data;
}
/************************************************************************
*
* Purpose: Calibrates the BMP085 pressure sensor.
* Passed: Void
* Returned: Void
* Note:
*
************************************************************************/
void BMP085_Calibration(void)
{
  /* ac1 = 6690;
ac2 = -1227;
ac3 = -14421;
ac4 = 33898;
ac5 = 24422;
ac6 = 22886;
b1 = 5498;
b2 = 66;
mb = -32768;
mc = -11075;
md = 2432;
*/
   ac1 = bmp085Read2Bytes(0xAA);
   ac2 = bmp085Read2Bytes(0xAC);
   ac3 = bmp085Read2Bytes(0xAE);
   ac4 = bmp085Read2Bytes(0xB0);
   ac5 = bmp085Read2Bytes(0xB2);
   ac6 = bmp085Read2Bytes(0xB4);
   b1 = bmp085Read2Bytes(0xB6);
   b2 = bmp085Read2Bytes(0xB8);
   mb = bmp085Read2Bytes(0xBA);
   mc = bmp085Read2Bytes(0xBC);
   md = bmp085Read2Bytes(0xBE);
/*
printf("%Ld \n",ac1);
printf("%Ld \n",ac2);
printf("%Ld \n",ac3);
printf("%Lu \n",ac4);
printf("%Lu \n",ac5);
printf("%Lu \n",ac6);
printf("%Ld \n",b1);
printf("%Ld \n",b2);
printf("%Ld \n",mb);
printf("%Ld \n",mc);
printf("%Ld \n",md);
*/
}


/************************************************************************
*
* Purpose: Will read the 16-bit temperature value of BMP085 sensor.
* Passed: Void
* Returned: Long
* Note:
*
************************************************************************/
long bmp085ReadTemp(void)
{
   i2c_start();

   i2c_write(BMP085_W); // Write 0xEE
   i2c_write(0xF4); // Write register address
   i2c_write(0x2E); // Write register data for temp

   i2c_stop();

   delay_ms(10); // Max time is 4.5ms

   return bmp085Read2Bytes(0xF6);
}

/************************************************************************
*
* Purpose: Will read the 16-bit pressure value from BMP085 sensor.
* Passed: Void
* Returned: Long
* Note:
*
************************************************************************/
unsigned long bmp085ReadPressure(void)
{
   i2c_start();

   i2c_write(BMP085_W); // Write 0xEE
   i2c_write(0xF4); // Write register address
   i2c_write(0x34 | (OSS << 6)); // Write register data for temp

   i2c_stop();

   delay_ms(OSS_conversion_time[OSS]); // Max time is 4.5ms

   return bmp085Read3Bytes(0xF6);

}

/************************************************************************
*
* Purpose: Will find callibrated pressure + temperature
* Passed: Long *temperature, long *pressure, unsigned char readings
* Returned: Void
* Note:
*
************************************************************************/

// The bit-shift for possibly negative numbers.
// Note that divide has a higher precedence than
// bit shift, so this is not precisely the same.

void bmp085Convert(float long *temperature, float long *pressure)
{
   unsigned long ut,up;
   //float32 b5, b6, x3, b3, p, b4, b7;
   signed long aux1,aux2,aux3,aux4;

      float long c3,c4,c5,c6,bb1,mmc,mmd,x,x0,x1,x2,y,y0,y1,y2,p0,p1,p2,z,s,alpha,temp,pres;

   ut = bmp085ReadTemp();
   ut = bmp085ReadTemp();
   up = bmp085ReadPressure();
   up = bmp085ReadPressure();

   //ut = 0x7B50;
   //up = 0x883F;
   //printf("%LX \n",ut);
   //printf("%LX \n",up);

   //but = ut; //Debug var

/*NEW CALCS*/

   c3 = 160*pow(2,-15)*ac3;
   c4 = pow(10,-3)*pow(2,-15)*ac4;
   bb1 = 25600*pow(2,-30)*b1;

   //printf("%e \n",c3);
   //printf("%e \n",c4);
   //printf("%e \n",bb1);

   c5 = ac5*pow(2,-15)/160;
   c6 = ac6;
   mmc = (0.08)*mc;
   mmd = md/160;

   //printf("%e \n",c5);
   //printf("%e \n",c6);
   //printf("mmc\n");
   //printf("%e \n",mmc);
   //printf("%e \n",mmd);

   x0 = ac1;
   x1 = 160*pow(2,-13)*ac2;
   x2 = 25600*pow(2,-25)*b2;

   //printf("%e \n",x0);
   //printf("%e \n",x1);
   //printf("%e \n",x2);

   y0 = c4*32768;
   y1 = c4*c3;
   y2 = c4*bb1;

   //printf("%e \n",y0);
   //printf("%e \n",y1);
   //printf("%e \n",y2);

   p0 = 3783/1600;
   p1 = 1-7357*pow(2,-20);
   p2 = 3038*100*pow(2,-36);

   //printf("%e \n",p0);
   //printf("%e \n",p1);
   //printf("%e \n",p2);

   /*Calculamos temperatura*/
   alpha = c5*(ut-c6);
   temp = alpha + (mmc/(alpha+mmd));


   /*Calculamos presion*/
   s = temp - 25;
   x = x2*s*s+x1*s+x0;
   y = y2*s*s+y1*s+y0;
   z = (up-x)/y;
   pres = p2*z*z+p1*z+p0;



   *temperature = temp;
   *pressure = pres;


/**/


/****************BEGIN*****CALC*****TEMP*********************/

/*
aux1 = ut-ac6;
aux2 = aux1*ac5;
x1 = aux2/32768;
//x1 = ((ut - ac6) * ac5 / pow(2,15));
aux3 = x1+md;
aux4 = mc/aux3;
x2 = aux4*2048;
//x2 = (mc * (pow(2,11))) / (x1 + md);
b5 = x1 + x2;
*temperature = ((b5 + 8) / 16);

/****************END*****CALC*****TEMP***********************/


/****************BEGIN*****CALC*****PRES*********************/
/*

up = up >> (8-OSS);
//bup = up; //Debug var
b6 = b5 - 4000;
aux1 = b6*b6;
aux2 = aux1/4096;
aux3 = aux2*b2;
x1 = aux3/2048;
//x1 = (b2 * (b6 * b6 / pow(2,12))) / pow(2,11);
aux1 = ac2*b6;
x2 = aux1/2048;
//x2 = ac2 * b6 / pow(2,11);
x3 = x1 + x2;

aux1 = ac1*4;
aux2 = aux1+x3;
shift = aux2;
aux3 = shift << OSS;
aux4 = aux3+2;
b3 = aux4/4;
//b3 = ((((ac1 * 4) + x3) << OSS) + 2) / 4;
aux1 = ac3*b6;
x1 = aux1/8192;
//x1 = ac3 * b6 / pow(2,13);
aux1 = b6*b6;
aux2 = aux1/4096;
aux3 = aux2*b1;
x2 = aux3/65536;
//x2 = (b1 * (b6 * b6 / pow(2,12))) / pow(2,16);
aux1 = x1+x2+2;
x3 = aux1/4;
//x3 = ((x1 + x2) + 2) / pow(2,2);
aux1 = x3+32768;
aux2 = ac4*aux1;
b4 = aux2/32768;
//b4 = (ac4 * (unsigned long) (x3 + 32768)) / pow(2,15);
aux1 = up-b3;
aux2 = 50000>>OSS;
b7 = aux1*aux2;
//b7 = ((unsigned long) up - b3) * (50000 >> OSS);
if (b7 < 0x80000000)
{
aux1 = b7*2;
p = aux1/b4;
}
else
{
aux1 = b7/b4;
p = aux1*2;
}

aux1 = p/256;
x1 = aux1*aux1;
//x1 = p / pow(2,8);
//x1 *= x1;
aux2 = x1*3038;
x1 = aux2/65536;
//x1 = (x1 * 3038) / pow(2,16);
aux1 = -7357*p;
x2 = aux1/65536;
//x2 = (-7357 * p) / pow(2,16);
aux1 = x1+x2+3791;
aux2 = aux1/16;
p = p+aux2;
*pressure = p;
/****************END*****CALC*****PRES***********************/
}




i2c.c



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

// Common I2C Routines


#define SDA_PIN PORTBbits.RB1 //
#define SCL_PIN PORTBbits.RB4 //

#define SDA_DIR TRISBbits.TRISB1
#define SCL_DIR TRISBbits.TRISB4


void i2c_high_sda(void)
{
   // bring SDA to high impedance
   SDA_DIR = 1;
   DelayUs(5);
}

void i2c_low_sda(void)
{
   SDA_PIN = 0;
   SDA_DIR = 0;  // output a hard logic zero
   DelayUs(5);
}

void i2c_high_scl(void)
{
   SCL_DIR = 1;   // high impedance
   DelayUs(5);
}

void i2c_low_scl(void)
{
   SCL_PIN = 0;
   SCL_DIR = 0;
   DelayUs(5);
}

void i2c_read(unsigned short r_byte)
{
   int  n;
   i2c_high_sda();
   for (n=0; n<8; n++)
   {
      i2c_high_scl();

      if (SDA_PIN)
      {
         r_byte = (r_byte << 1) | 0x01; // msbit first
      }
      else
      {
         r_byte = r_byte << 1;
      }
      i2c_low_scl();
   }
   return;
}



void i2c_write(signed char w_byte)

{
    int m ;
   for(m=0; m<8; m++)
   {
      if(w_byte&0x80)
      {
         i2c_high_sda();
      }
      else
      {
         i2c_low_sda();
      }
      i2c_high_scl();
      i2c_low_scl();
      w_byte = w_byte << 1;
   }
   i2c_high_sda();
}

void i2c_nack(void)
{
   i2c_high_sda(); // data at one
   i2c_high_scl(); // clock pulse
   i2c_low_scl();
}

void i2c_ack(void)
{
   i2c_low_sda(); // bring data low and clock
   i2c_high_scl();
   i2c_low_scl();
   i2c_high_sda();
}


void i2c_start(void)
{
   i2c_low_scl();
   i2c_high_sda();
   i2c_high_scl(); // bring SDA low while SCL is high
   i2c_low_sda();
   i2c_low_scl();
}

void i2c_stop(void)
{
   i2c_low_scl();
   i2c_low_sda();
   i2c_high_scl();
   i2c_high_sda();  // bring SDA high while SCL is high
   // idle is SDA high and SCL high
}



void i2c_restart(void)
{
i2c_low_scl(); /* ensure clock is low */
i2c_high_scl(); /* ensure data is high */
SCL_DIR = 1;                         /* clock pulse high */
i2c_low_sda(); /* the high->low transition */
return;
}

Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Leyendo BMP085(sensor presion) en xc8
« Respuesta #6 en: 04 de Junio de 2013, 14:19:23 »
 ¿Y funciona, o no?

  Insisto en que está mal definida la función i2c_read();
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Leyendo BMP085(sensor presion) en xc8
« Respuesta #7 en: 04 de Junio de 2013, 14:36:34 »
¿Y funciona, o no?

  Insisto en que está mal definida la función i2c_read();


A ver ...no te entendi bien ...

void i2c_read(unsigned short r_byte)

esto es i2c_read ...devuelve un r_byte  unsigned short ...o estoy equivocado ???

Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Leyendo BMP085(sensor presion) en xc8
« Respuesta #8 en: 04 de Junio de 2013, 14:47:09 »
Una Pregunta AngelGris ....como puedo probar en proteus solamente la subrutina i2c para estar seguro que ande antes de conectar el sensor ??


Saludos y gracias
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Leyendo BMP085(sensor presion) en xc8
« Respuesta #9 en: 04 de Junio de 2013, 14:50:34 »
No. Para que te devuelva un valor debes especificar el tipo de valor a devolver antes del nombre de la función. Así...

Código: C
  1. unsigned short i2c_read();

y la implementación podría ser algo así

Código: C
  1. unsigned short i2c_read()
  2. {
  3.   unsigned short variable_temporal;
  4.   unsigned short contador;
  5.  
  6.  
  7.   i2c_high_sda();
  8.   for (contador = 0; contador < 8; contador++)
  9.   {
  10.     i2c_high_scl();
  11.     variable_temporal = variable_temporal << 1;
  12.     if (SDA_PIN == 1) variable_temporal = variable_temporal | 1;
  13.     i2c_low_slc();
  14.   }
  15.   return variable_temporal;
  16. }

  Proteus tiene una herramienta para I2C que se llama i2c debugger. Si mal no recuerdo se la puede configurar como slave y darle un address y datos a devolver.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Leyendo BMP085(sensor presion) en xc8
« Respuesta #10 en: 04 de Junio de 2013, 15:10:56 »
a ver ahora ...

Código: [Seleccionar]
unsigned short i2c_read()
{
    unsigned short r_byte;
    int  n;
   i2c_high_sda();
   for (n=0; n<8; n++)
   {
      i2c_high_scl();

      if (SDA_PIN)
      {
         r_byte = (r_byte << 1) | 0x01; // msbit first
      }
      else
      {
         r_byte = r_byte << 1;
      }
      i2c_low_scl();
   }
   return r_byte;
}


Ahora con la i2c_write ...esta bien ???
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Leyendo BMP085(sensor presion) en xc8
« Respuesta #11 en: 04 de Junio de 2013, 15:17:57 »
  Sí, i2c_write parecería estar bien. Dicha función recibe un parámetro, por ello está indicado dentro de los paréntesis.

  Yo cambiaría el tamaño de las variables que utilizas como contadores para el ciclo for tanto de i2c_read como de i2c_write. El tipo "int" es de 16 bits y el tipo "char" es de 8 bits, así que sería suficiente utilizar variables de éste último tipo.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: Leyendo BMP085(sensor presion) en xc8
« Respuesta #12 en: 05 de Junio de 2013, 21:04:21 »
Por que no usas las de hitech? xc y hitech son lo mismo.

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Leyendo BMP085(sensor presion) en xc8
« Respuesta #13 en: 07 de Junio de 2013, 14:37:22 »
Buenas !!! recien termino mi programa ...compila , pero no logro que funcione , estoy tratando de leer el sensor , pero no estoy seguro de que el i2c este funcionando bien ....y esa es la pregunta ...como me aseguro de que lo que hice funciona ?? les paso el proyecto a ver cual es su opinion ...esta compilando en mplabx con compiler xc8 ...pic16f819

Gracias

Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!

Desconectado Rseliman

  • PIC16
  • ***
  • Mensajes: 239
Re: Leyendo BMP085(sensor presion) en xc8
« Respuesta #14 en: 07 de Junio de 2013, 14:53:38 »
Y aca va el proyecto en proteus 8
Las Grandes Obras las sueñan los grandes locos , mientras los inutiles las critican !!


 

anything