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:
Para cambiar la dirección de cada sensor usamos:
Librería I2C, solo le hice un par de cambios, está con sus respectivos creditos.
[/B]887_i2c.h[/B]
Espero le sea de ayuda a alguien.
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: