RobotyPic son proyectos básicos de electrónica con microcontroladores PIC, de aplicación en el mundo de la robótica didáctica, con archivos fuente creados mediante el compilador CCS PIC C COMPILER en lenguajeC.

Comunicación I2C entre 3 PIC















El ejemplo didáctico consiste en lo siguiente. El PIC maestro carga en los PIC esclavos datos aleatorios en 10 posiciones de memoria. Primero con el PIC esclavo 1, dirección I2C en el bus 0xA0. Posteriormente con el PIC esclavo 2, con dirección I2C 0xB0. Cuando ha cargado los datos en ambos PIC, hace una lectura del dato que ha guardado en la posición 5 de ambos PIC y la muestra por el LCD.

Pulsa en la imagen para ampliarla

PIC Maestro

Lo primero de todo será configurar la comunicación I2C en la cabecera del programa. En dicha configuración vamos a establecer que se trata del PIC maestro (master), que vamos a usar velocidad rápida (fast), y que los pines del PIC van a ser C4 para la línea sda del bus y C3 para scl, propios del módulo SSP que este PIC posee.

#use i2c(Master, fast, sda=PIN_C4,scl=PIN_C3)

Si el PIC no posee módulo SSP o queremos emplear otros pines diferentes, se puede realizar la comunicación mediante software forzando esta característica e indicando los pines que van a ser utilizados.

#use i2c(Master, fast, sda=PIN_B2,scl=PIN_B3, force_sw)


A partir de este momento, para enviar algo por el bus I2C ejecutamos la función Envio_I2C(), en la que deberemos especificar previamente la dirección en el bus I2C del esclavo con el que se quiere comunicar, la posición del buffer de memoria donde se va a guardar en el esclavo el dato enviado y la información del propio dato.


 direccion=0xA0;        //Dirección del esclavo en el bus I2C
 posicion=0x05;         //Posición donde se guardará el dato 
 dato=0xfb;             //Dato a transmitir


 Envio_I2C(direccion, posicion, dato);  //Función para envio I2C

Dentro ya de la función, el envío de cada byte de datos se realizará con las siguientes sentencias:

 i2c_start();           //Comienzo comunicación 
 i2c_write(direccion);  //Dirección del esclavo en el bus I2C
 i2c_write(posicion);   //Posición donde se guardará el dato 
 i2c_write(dato);       //Dato a transmitir 
 i2c_stop();            //Fin comunicación

Para la lectura de los esclavos el proceso es similar, pero esta vez ejecutando la función Lectura_I2C(). También previamente deberemos especificar la dirección del esclavo en el bus I2C, la posición en el buffer de memoria del PIC esclavo de donde queremos obtener el byte que contiene y la variable donde lo vamos a guardar (&dato).

 direccion=0xA0;        //Dirección del esclavo en el bus I2C
 posicion=0x05;         //Posición donde se guardará el dato 


 Lectura_I2C(direccion, posicion, &dato); //Función para envío I2C

Dentro ya de la función ejecutaremos las sentencias para el envío de cada byte de datos:

 i2c_start();            //Comienzo de la comunicación 
 i2c_write(direccion);   //Dirección del esclavo en el bus I2C 
 i2c_write(posicion);    //Posición de donde se leerá el dato
                           en el esclavo 
 i2c_start();            //Reinicio 
 i2c_write(direccion+1); //Dirección del esclavo en modo lectura 
 dato=i2c_read(0); //Lectura del dato 
 i2c_stop();             //Fin comunicación



PIC esclavo

Igual que en el PIC master, en cada PIC esclavo se debe configurar la comunicación I2C. En este caso vamos a establecer que se trata de un PIC esclavo (slave), que vamos a usar velocidad rápida (fast), que los pines del PIC van a ser C4 para la línea sda y C3 para scl, y cual va a ser su dirección en el bus (address).

#use i2c(slave, fast, sda=PIN_C4, scl=PIN_C3, address=0xA0)

A diferencia del PIC maestro que es quien decide en que momento iniciar la comunicación, en los esclavos, la comunicación se establece cuando, mediante la interrupción #INT_SSP se detecta actividad en el bus I2C.

En el caso del PIC esclavo, si que vamos a necesitar del módulo SSP, por tanto no se puede forzar una comunicación por software como en el PIC maestro y los pines han de ser necesariamente los propios del bus I2C del PIC.

#INT_SSP
void ssp_interupt (){
      int incoming;           //Variable donde se recibe el byte que manda el maestro
      fstate = i2c_isr_state();  //Lectura del estado del bus I2c la interrupción
  /* Solicitud de lectura del esclavo por el master */
   if(fstate == 0x80) {        
       //Manda al maestro la información contenida en la posición de memoria que le ha solicitado
      i2c_write (buffer[posicion]);
      SolicitudMaster=1;          //Fin de solicitud del master
   }
   /* Sino está solicitando lectura es que está enviando algo */
   else {                         //Sino es que hay dato en el bus I2C...
      incoming = i2c_read();      //... lo lee
      if (fState == 1) {          //Información recibida corresponde a la posicion
         posicion = incoming;     //Se guarda posición
      }
      else if (fState == 2) {  //Información recibida corresponde al dato
         buffer[posicion] = incoming;  //Se guarda dato
         EnvioMaster=1;                //Fin del envío del master
      }
  }

}


[+/-] Ver / Ocultar programa en C PIC Maestro

[+/-] Ver / Ocultar programa en C PIC Esclavo 1

[+/-] Ver / Ocultar programa en C PIC Esclavo 2



En esta animación se ve la demostración de funcionamiento bajo proteus.




Descarga de los archivos del proyecto.

Descargar archivos I2C tres PICs


El proyecto contenido en el artículo ha sido diseñado y probado con éxito utilizando las siguientes versiones de software:
- Windows xp y windows 7 (32 y 64 bits)
- Proteus V7.7 SP2
- CCS PIC C COMPILER v4.104

Última revisión del artículo junio de 2015





21 comentarios:

Pako Riezu dijo...

Hola, tengo una super duda, me sirvió mucho tu programa para 2 pic, lo pude utilizar super bien, pero ahora quiero cambiar el Pic maestro por un arduino y no me jala, no sé si lo has hecho esto mismo con arduino de master,no sé cual sea mi error, pero si lo has solucionado en arduino me ayudarías muchisimo.

por cierto muchas gracias por subir tu trabajo está muy bien hecho y ayuda montón!!

Robotypic dijo...

Pues no lo he hecho en Arduino. No tengo información que ofrecerte.

Ítalo Rodrigues dijo...

Ola, quero agradecer a sua contribuição na demostração da comunicação i2c, você realmente está de parabéns, foi único código que realmente consegui entender e trabalhar em cima de tudo que pesquisei, você tem um excelente trabalho em seu blog!! graças a você consegui entender muito e avançar bastante na implementação do protocolo! Agora estou tentando trabalhar com sensor HMC6352, mais enfrento umas certas dificuldades, você teria algum projeto com tal sensor?

Robotypic dijo...

Hola Italo.

Lo siento pero ahora mismo no tengo nada sobre el sensor que propones.

Carlos dijo...

Que tal, primeramente quiero agradecer la ayuda que brindas con todos tus proyectos .
Tengo un problema he implementado el programa para poder enviar los datos obtenidos por dos Canales analogicos del pic, pero en un cierto momento proteus me tira error en el pic esclavo, de antemano muchas gracias!

Robotypic dijo...

Carlos.
Lo que ves en esta entrada funciona tal como lo ves en el video demostrativo. Lo que hay aqui funciona. Si tienes algun tipo de problema deberías revisar lo que hayas añadido.

Carlos dijo...

He logrado hacerlo funcionar, era solo un problema con una variable en el pic esclavo. Te agradezco mucho que compartas los proyectos que haces, me han servido de mucha ayuda! gracias

Sebastian Araya dijo...

Cual es la contrasrña del archico rar?

Robotypic dijo...

El archivo de descarga no requiere contraseña.

Alejo Veloz dijo...

Hola una pregunta modificaste alguna librería porque funcina bien con tu archivo .hex pero compilo y genero el nuevo .hex y ya no funciona que puede ser?? gracias

JOHN dijo...

Gracias por el programa, veras lo he descargado y como no tengo la misma versión de proteus lo que hice fue montar el circuito en este y usar tus. Hex para mi montaje pero no funciona igual que el vídeo, al iniciar la tradición los 2 pic reciben la misma info, es decir no diferencia un esclavo del otro y los dos reciben lo mismo, espero me puedas ayudar a solucionar esto

Robotypic dijo...

Alejo, emplea las mismas versiones que las mostradas en el ejemplo.

Robotypic dijo...

John, está probado fisicamente. Debe funcionarte con los archivos del ejemplo.

Alejo Veloz dijo...

Muchas gracias :)

Unknown dijo...

Amigo

Muy bueno tu ejemplo yo lo probé y funciona perfecto,, yo intente que los esclavos le mandaran la información al Maestro y no pude ...estoy tratando de que dos esclavos leen cada uno un teclado de 4x3 y esas teclas sean enviadas al maestro... como se puede hacer eso ?...lo he intentado pero por ahora nada he podido sacar

Saludos
desde Chile

Robotypic dijo...

La iniciativa la lleva siempre el maestro. Éste debe ser el que solicite la información a los esclavos. Puedes hacer que los esclavos guarden la información hasta que el maestro se la solicite.

dark dijo...

hola tengo una duda como hago para mandar un dato float en el mismo ejemplo que muestras..

Robotypic dijo...

Dark.
Envíalo como caracteres ascii. Mira este otro ejemplo: http://robotypic.blogspot.com.es/2012/08/transmision-variable-tipo-float-por.html

Andreu Ática Agua dijo...

antes de nada darte las gracias por las extraordinarias presentaciones que haces de cada ejercicio... de lo mejor que he encontado por internet ... quería comentarte que estoy diseñando un sistema que va a leer de unos sensores analógicos unas señales....estas señales las quiero sacar por pantalla en continuo y posteriormente tb sacare algún tipo de salida de regulación tipo bus de pulsos o 4-20 aun esta por decidir ...mi pregunta es la siguiente... como quiero utilizar un sistema basado en dos o tres pics he pensado en que uno haga de coordinador de eventos, como atender al teclado y visualizar datos por el lcd y los otros dos que atiendan el proceso en continuo... cual crees que será el mejor protocolo de comunicación para un caso asi el i2c o rs 232??... muchísimas gracias de antemano

Robotypic dijo...

Andreu.
En el momento en el que tu empleas más de 2 PIC el RS232 como tal no te va a servir. Otra opción es el SPi, pero necesitarías emplear un linea de Chip Select por cada PIC. Yo pienso que el mejor sería el I2C puesto que con 2 únicas lineas puedes comunicar multitud de PICs.

Jose Arias dijo...

HOla! Saludos de Ecuador
Que tendria que modificar para utilizar el programa con un pic 16f877a o un 18f4550?
Gracias

Related Posts Plugin for WordPress, Blogger...

CONTACTA - (Haz referencia del artículo sobre el que trata la consulta o comentario)