Comunicacion I2C entre pic´s

Bueno pues, como dice el tema, solo quiero enviar datos de un pic a otro, en una sola direccion, supongo que es mas sencillo, ahorita estoy probando con el PIC16F877A, aunque supongo podria adaptarme a cualquier otro pic. No es un puerto de alta velocidad o de una gran carga de datos, a lo mucho enviaria 6 bytes , con sus respectivos tiempos entre cada uno. Soy relativamente nuevo en pic's, conozco algo de como programarlos en C y ya he hecho algunos proyectos sencillos; pero ahorita nomas no puedo hacer que se comuniquen 2 pics, he hecho pruebas simulando en proteus y no funciona, he buscado en internet y usualmente la informacion o esta truncada, es decir nunca llegan a una conclusion, o siempre difiere, el manual de ccs me indica las funciones
Código:
i2c_start()
i2c_poll()
i2c_stop()
i2c_write()
i2c_read()
Pero aunque he cambiado los codigos varias veces, no funciona. Esperaba que me pudieran ayudar a encontrar mi problema, que me falta o que me sobra, o simplemente la fomra en que se envian y adquieren los datos.

Pongo los ultimos codigos que hice:

Maestro:

Código:
#INCLUDE <16F877.h> 
#USE DELAY(clock=4000000)
#USE I2C (MASTER, SDA=PIN_C4, SCL=PIN_C3,ADDRESS=0XA0,SLOW,FORCE_HW)
#BYTE porta= 0x05
#BYTE portb= 0x06
#BYTE portc= 0x07
#BYTE porta_tris= 0x85
#BYTE portb_tris= 0x86
#BYTE portc_tris= 0x87


main()
{

   porta_tris= 0x00;
   portb_tris= 0b11111111;
   portc_tris= 0x00;

i2c_start();
i2c_write(0b00111111);
i2c_stop();

delay_ms(1000);

i2c_start();
i2c_write(0XA1);
i2c_write(0b11111111);
i2c_stop();

delay_ms(1000);

i2c_start();
i2c_write(0XA0);
i2c_write(0b11111111);
i2c_stop();
  
delay_ms(1000);  
  
}

Esclavo:

Código:
#INCLUDE <16F877.h> 
#USE DELAY(clock=4000000)
#USE I2C (SLAVE, SDA=PIN_C4, SCL=PIN_C3,ADDRESS=0XA1,SLOW,FORCE_HW)
#BYTE porta= 0x05
#BYTE portb= 0x06
#BYTE porta_tris= 0x85
#BYTE portb_tris= 0x86

main()
{
INT R1;
   porta_tris= 0x00;
   portb_tris= 0x00;
   portc_tris= 0b11111111;
R1=0;
      if(i2c_poll())
      {
         R1=i2c_read();
         output_toggle(PIN_B0);
      }

      if(i2c_poll())
      {
         R1=i2c_read();
         output_toggle(PIN_B1);
      }
      
      
      if(i2c_poll())
      {
         R1=i2c_read();
         output_toggle(PIN_B2);
      }


  
}

Aqui el maestro se supone envia 3 datos al esclavo, con 1 segundo de diferencia entre si, y el esclavo muestra que ha recibido un dato con un led oscilante en algun pin del puerto B.

Espero su ayuda, Gracias de antemano.
 
Hola Helios, Mi nombre es cristian, estoy tratando de comprender como programar I2c y he visto que tienes dudas como yo, mas o menos, de inicialización al I2C. Podriamos tener contacto para comentarlo los dos?? Estoy con el proyecto final de carrera y estoy intentando comprender el I2C para empezar con las simulaciones, pero me cuesta encontrar información útil.

Gracias!

Un saludo
 
Última edición por un moderador:
Hola de nuevo! la comunicación de I2c ya la controlo mas o menos, ahora me ha surgido un problema para comunicar. Debo tratar una variable (puerta) que guarda el valor de 8 bits que nos interesan (8 sensores) en forma de array y que lo realizo asi:

for(i=0;i<8;i++)
{
porta=select;
delay_ms(10);
puerta[select]=input_state(PIN_B0);
select++;
}
select=0;
i=0;

enviar_datos();


Una vez tenga el dato de "puerta" quiero enviar ese array de bits al esclavo (mediante enviar_datos():

void enviar_datos(void)

{
i2c_start(); //Comienzo de la comunicación I2C ...
i2c_write(0xA0); //...con la dirección del PIC esclavo...
i2c_write(puerta);
delay_ms(20);
i2c_stop(); //Finalización de la transmisión
}


En el esclavo quiero sacar el valor de ese array por el puerto B. Que tipo de variable deberia definir en el esclavo para que los datos que le llegan del maestro los interprete que son un array y se los meta a tal variable para poder sacarlos por el PortB. No se si me he explicado muy bien en esta parte final, si no lo entendeis lo vuelvo a repetir.

Saludos.
 
si esta usano el puerto usar me imagino que solo por uno... pero para esas osas si que biene muy bien entrar a recover el byte mediante una interruccion, yo creo...

un saludo
 
Lo quiero sacar por el puerto B (8 pines). Los Bytes que provienen del maestro (16F874A), los quiero ir guardando en un array de Bytes, en el esclavo. Cada posición se referirá a una puerta. Ej: El primer envio se guardara en la primera posicion del array y asi con 6 mas (total 7 puertas). Lo que me gustaria saber es como identificar luego para el programa del esclavo cada Byte que corresponda a una puerta determinada.

Saludos
 
Envía los 7 bytes seguidos, y los guardas en un array en el esclavo en el mismo orden que los envías.
¿O es que quieres enviar un byte de cada vez y en orden aleatorio?
 
Buenas!, siento el retraso, no he tenido a disposición el ordenador mucho la verdad. Al final lo que hice es enviar byte a byte desde el puerto B del maestro al esclavo y ir sacando los valores por el PB del esclavo (vamos lo basico que hace el I2C).

Dicho esto, me ha surgido un nuevo problema a la hora de enviar datos. Mirad ahora estoy con los sensores de las luces (constaran de 15 sensores). estas entradas estan gestionadas por dos multiplexores de 8 e/1salida (es decir 8 en uno y 7 en el otro). Estas dos salidas me proporcionaran bits de información que los voy a guardar en un array de 8 posiciones, formando asi dos arrays de 8 bits. Creo que me esta dando problemas a la hora de enviar estos arrays a un nuevo esclavo (le proporciono la address 0xB0, el anterior era A0) para que cada array de 8 bits me lo saque por un puerto distinto y asi comprobar que los 8 bits de cada array activados corresponden con la salida de uno de los puertos, y el otro array con otro de los puertos.

Muchas gracias por la atencion.

Saludos
 
Atrás
Arriba