Usar sensores SRF02 HI TECH PIC16F877 por I2C

Saludos, hace poco estuve con problemas para usar los sensores SRF02, finalmente los pude utilizar, por lo que comparto aquí en el foro como lo logré para que los que tengan el mismo problema no tarden tanto y puedan aprovechar mas el tiempo en otras partes de sus proyectos, para empezar uno de los problemas que tenía era que no estaba mandando los datos de manera adecuada, y otra que la librería que finalmente utilicé tenía algunos problemas con las nuevas versiones de Hi Tech por lo que le hice un par de pequeñas modificaciones.

El código funciona perfectamente con el PIC16F877, lo probé igual en el PIC16F887 y también conseguí buenos resultados. Puede ser usado con el SRF08 o con otro SRF que trabaje por I2C

Para tomar una medida:

Código:
     i2c_start();
     i2c_write(0xe0);
     i2c_write(0x00);  // Dirección de comandos
     i2c_write(0x51);  // Le indicamos que queremos el resultado en cm
     i2c_stop();
     DelayMs(71); // Esperamos a que e sensor mande una ráfaga y la mida
     i2c_start();                
     i2c_write(0xe0);
     i2c_write(0x02);   //Nos posicionamos en el registro 2 del sensor para leer el resultado
     i2c_stop();
     i2c_start();                   //Restart
     i2c_write(0xe1);      //Le indicamos que queremos leer
     High = i2c_read(1);  //
     Low = i2c_read(0);    //
     i2c_stop();   // Muy importante cada stop para terminar la comunicacion


Para cambiar la dirección de cada sensor usamos:

Código:
     i2c_start();
     i2c_write(0XE0);  // Dirección de fabrica del sensor
     i2c_write(0x00);
     i2c_write(0xA0);  
     i2c_stop();


	 i2c_start();

     i2c_write(0XE0);
     i2c_write(0x00);
     i2c_write(0xAA);   //Nueva lectura, resultado en CM
     i2c_stop();


	 i2c_start();

     i2c_write(0XE0);
     i2c_write(0x00);
     i2c_write(0xA5);   
     i2c_stop();


	 i2c_start();

     i2c_write(0XE0);
     i2c_write(0x00);
     i2c_write(0xE4);     // La nueva dirección deseada
     i2c_stop();

Librería I2C, solo le hice un par de cambios, está con sus respectivos creditos.


[/B]887_i2c.h[/B]
Código:
/******************************************************************************************/
// Hardware I2C single master routines for PIC16F877
// for HI-TEC PIC C COMPILER.
//
// i2c_init  - initialize I2C functions
// i2c_start - issue Start condition
// i2c_repStart- issue Repeated Start condition
// i2c_stop  - issue Stop condition
// i2c_read(x) - receive unsigned char - x=0, don't acknowledge - x=1, acknowledge
// i2c_write - write unsigned char - returns ACK
//
// modified from CCS i2c_877 demo
//
// by
//
// Michael Alon - MICROCHIP FAE
// My E-mail michael@elina-micro.co.il
// www.elina-micro.co.il
// Tel: 972-3-6498543/4
// Fax: 972-3-6498745
// Elina Micro LTD .ISRAEL
//
/******************************************************************************************/

void i2c_init()
{
  TRISC3=1;           // set SCL and SDA pins as inputs
 TRISC4=1;

  SSPCON = 0x38;      // set I2C master mode
 SSPCON2 = 0x00;

 file://SSPADD = 0x6;     // 400kHz bus with 10MHz xtal - use 0x0C with 20MHz xtal
 SSPADD = 0x0C;            // 100k at 4Mhz clock

 CKE=1;     // use I2C levels      worked also with '0'
 SMP=1;     // disable slew rate control  worked also with '0'

 PSPIF=0;      // clear SSPIF interrupt flag
 BCLIF=0;      // clear bus collision flag
}

/******************************************************************************************/

void i2c_waitForIdle()
{
 while (( SSPCON2 & 0x1F ) | R_W ) {}; // wait for idle and not writing
}

/******************************************************************************************/

void i2c_start()
{
 i2c_waitForIdle();
 SEN=1;
}

/******************************************************************************************/

void i2c_repStart()
{
 i2c_waitForIdle();
 RSEN=1;
}

/******************************************************************************************/

void i2c_stop()
{
 i2c_waitForIdle();
 PEN=1;
}

/******************************************************************************************/

int i2c_read( unsigned char ack )
{
 unsigned char i2cReadData;

 i2c_waitForIdle();

 RCEN=1;

 i2c_waitForIdle();

 i2cReadData = SSPBUF;

 i2c_waitForIdle();

 if ( ack )
  {
  ACKDT=0;
  }
 else
  {
  ACKDT=1;
  }
  ACKEN=1;               // send acknowledge sequence

 return( i2cReadData );
}

/******************************************************************************************/

unsigned char i2c_write( unsigned char i2cWriteData )
{
 i2c_waitForIdle();
 SSPBUF = i2cWriteData;

 return ( ! ACKSTAT  ); // function returns '1' if transmission is acknowledged
}

/******************************************************************************************/

Espero le sea de ayuda a alguien.
 
Última edición:
Hola Jorger53... se ven muy bien sus codigos... necesito hacer un robot sumo y estoy usando este sensor por I2C pero ahi dice que la patilla de modo se deja al aire....pero luego lei en otro lado y decia q se dejaba en "1" logico...sera que ud me puede sacar de esta duda....
 
Atrás
Arriba