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 2 PIC.



Se trata de comunicar mediante bus I2C dos pic. Uno será el maestro, que enviará la información al pic esclavo para que la gestione. En concreto, en este ejemplo, el pic maestro toma el valor introducido por un teclado numérico. El valor de la tecla pulsada se enviará vía I2c al pic esclavo que la presentará en una pantalla lcd. Pulsando la tecla del asterisco (*), la información mostrada en la pantalla se borrará.

Para este tipo de comunicación se emplea la directiva...

#use I2C

...en la que se establecen las condiciones de la trasmisión como velocidad, pines del bus en el PIC, dirección del PIC esclavo, etc.

Por ejemplo, en este caso:

#use I2C(SLAVE, SDA=PIN_C4 , SCL=PIN_C3, SLOW, ADDRESS=0xa0)

Se está indicando que se establece al PIC como esclavo (SLAVE) , el pin C4 es la linea SDA del bus , el pin C3 es la linea SCL, se utiliza la velocidad de transmisión baja (SLOW) y  la dirección como esclavo será A0h.

En el caso del PIC maestro, en la directiva se indica MASTER en lugar de SLAVE, y se ignora la opción ADDRESS:

#use I2C(MASTER, SDA=PIN_C4 , SCL=PIN_C3, SLOW)

Para enviar la información con el PIC maestro empleamos este grupo de instrucciones:

i2c_start();        //Comienzo de la comunicación I2C ...
i2c_write(0xa0);    //...con la dirección del PIC esclavo...
i2c_write(tecla);   // Envía dato
i2c_stop();         //Finalización de la transmisión

Para saber cuando el PIC esclavo recibe información utilizamos la función i2c_poll(). Esta función devuelve un "TRUE" (valor 1) cuando se ha recibido el dato en el buffer. Comprobando su estado ciclicamente sabremos cuando hay que procesar la información recibida. El dato recepcionado lo podremos recuperar con la función i2c_read(). 

if(i2c_poll()) {                   // Si se ha recibido información...
   dato=i2c_read();                //...la guarda en la variable "dato"
}

La línea de datos SDA y la línea de señal de reloj SCL del bus, son líneas a colector abierto. Esto implica que se deben utilizar resistencias externas o pull-up que aseguren el estado alto cuando no haya dispositivos conectados al bus. Si no fueran usadas, las líneas podrían encontrarse en un momento dado en un estado indeterminado. Si uno de los componentes del bus intenta poner la línea en estado bajo a la vez que otro en estado alto, esto llevaría a conflicto al bus y podría dañar a los componentes.

Los valores típicos de estas resistencias pueden ser, a modo de orientación, de 4k7 para velocidades del bus inferiores o en torno a 100kbps, de 2k2 para velocidades alrededor de 100kbps y de 1k para velocidades en torno a 400kbs o superiores. 

Esquema comunicación I2C entre dos PIC
Haz clic en la imagen para ampliarla           


Los programas de los PIC van a ser dos, uno para el maestro...

[+/-] Ver / Ocultar programa MASTER en C


...y  otro para el PIC esclavo.

[+/-] Ver / Ocultar programa SLAVE en C


Se puede comprobar el funcionamiento bajo una simulación en proteus en esta animación:


Todos los archivos se pueden descargar en el siguiente enlace:

Existen más opciones de comunicación I2C. En el artículo referente a la Comunicación I2C entre 3 PIC, se utiliza la interrupción #INT_SSP como otra alternativa.


El proyecto contenido en el artículo ha sido diseñado y probado utilizando las siguientes versiones de software:
- Windows xp y windows 7
- Proteus V7.7 SP2
- CCS PIC C COMPILER v4.084


22 comentarios:

Raúl dijo...

Hola!!

Te agradezco mucho que pongas información así accesible para todo el mundo, gracias a tu ejemplo he podido iniciarme en la comunicación I2C con un 18F458.

Muchísimas gracias!!!

titiguanta dijo...

te agradezco y me ayudes si se puede configurar dos pic por i2c y el master en ves del teclado tenga una entrada de voltaje de 5v con un potenciometro y poder variarlo y muestre esa lectura en la 1ra linea de la lcd y q la entrada del voltaje sea por el puerto RA0 O RA1

Robotypic dijo...

Fíjate en el artículo “Lectura luminosidad con conversor A/D”. El proceso de lectura de la señal analógica sería como ahí se indica sustituyendo las LDR por el potenciómetro y configurando la conversión a 8 bits en lugar de 10. #device adc=8
El dato a enviar por I2C sería el contenido de la variable “valor_digital”.

Recibido este dato en el esclavo, debes pasarlo a su valor equivalente analógico:
valor_analogico=5.0*valor_digital/512.0;
Y mostrarlo en el LCD:
printf(lcd_putc, "\fVoltaje = %01.2fV", valor_analogico);

Arturo dijo...

Hola que tal me parece muy bueno tu código, solo diría que tiene un pequeño detalle la función de lectura solo se puede usar una vez por esclavo,pasa que se deja el bus en ocupado y al hacer el segundo llamado a la función lectura en la posición que sea el esclavo siempre responderá FF es un error o, simplemente así es tu programa quisiera que me ayudaras necesito hacer esa función pero sin que el bus se quede habilitado. es todo help

Robotypic dijo...

Hola Arturo.
Creo que haces referencia al ejemplo en el que se utilizan dos esclavos. Lo he estado revisando y tienes razón. Para evitarlo hay que cambiar en cada esclavo la sentencia if(i2c_poll() == FALSE) por esta otra if(fstate == 0x80). En el artículo ya está corregido, lo puedes ver ahí.

Arturo dijo...

Muchas muchas gracias.....

me ha salvado la vida! apenas esto iniciándome en el protocolo y sinceramente al principio me era totalmente inmanejable.

Es usted un máster! :D
yo no le hallaba el error.

gracias!

Asdrubal dijo...

Hola que mas, muy bueno el proyecto. Jamás he trabajado con el I2C y estoy tratando de implementar este mismo proyecto pero los PICS no se me comunican... en la conexión física del circuito que debo tener en cuenta?.... También observé que si en la simulación quito el depurador I2C, la comunicación de ellos es nula.. a que se debe?. GRACIAS

Robotypic dijo...

Hola Asdrubal.
Realmente en la simulación que esté o no el depurador no debería influir. Tan solo es un visualizador del bus. ¿Puede ser algún defecto de proteus? En algún otro aspecto los tiene.
Con respecto al montaje físico, en el código del PIC esclavo debes poner #fuses XT si empleas un cristal de 4 MHz. Estaba omitido.

Unknown dijo...

Hola, Oye, voy a hacer un proyecto con 1 arduino maestro y 2 pic esclavos pero me gustaría tener la resolución del dato que envíe a más de 1 byte, no tienes apuntes de cómo hacer eso? saludos y gracias

Robotypic dijo...

Pako. En el artículo "Comunicación I2C entre 3 PIC" puedes ver como enviar y recibir varios byte. En ese caso se emplean como dirección, posición, dato, ect. Pero tu los puedes interpretar como datos.

CCNA dijo...

Hola.
Estoy armando un circuito donde uso I2C y tome este circuito como modelo.
En tu ejemplo veo que el PIN RC2 está en gris. Eso es por que no esta programado ni como entrada ni como salida ?
En mi circuito me pasa lo mismo pero con RC1 que lo tengo programado como salida. Ademas RC0 tambien esta como salida y aunque no esta en gris no me funciona, siempre queda en azul (0 volt) siendo que en determinados momentos deberia ponerse en rojo (5 volt)
Cuando arranco la simulación en Proteus V7.7 SP2 esas dos salidas funcionan correctamente hasta que hago la primera transmision por I2C. A partir de ese momento ninguno de las dos salidas responden.
Arme el circuito y me pasa lo mismo, o sea que no es un bug de Proteus.
Revisando descubri que el problema es con I2C porque si no transmito datos esas dos salidas me funcionan correctamente.
Que podra ser ?
Sera un bug de la libreria I2C ?
Gracias.

Robotypic dijo...

Hola CCNA
Ten en cuenta que según que configuración de #fuses emplees, algunos de los pines del puerto C se deshabilitan como entradas y salidas. Consulta esta sección para que sepas en que medida: http://robotypic.blogspot.com.es/2011/05/generacion-de-numeros-aleatorios-con.html#fuses
Por otro lado, pasa lo mismo cuando empleas alguna de las funciones hardware del puerto C (I2C, módulo CCP, etc.).

Unknown dijo...

Este soy yo cuando intento mirar vuestro codigo
Tu cuenta actual (berto3soydd@hotmail.com) no tiene acceso para ver esta página.
Podríais darme acceso por favor, en referencia a
-Ver / Ocultar programa MASTER en C & slave

Robotypic dijo...

Hola. El acceso es libre. No es necesario ningún tipo de permiso.

Unknown dijo...

Si basta con pinchar en el directamente Gracias La negación ocurre con la mania de querer abrirlo en una segunda pagina

Unknown dijo...

Exelente aporte, una pregunta modificando un poco la programacion funciona igual para los pic 16f877a?

Robotypic dijo...

Si. Ambas programaciones serían muy similares entre 16f876a y 16f877a.

Unknown dijo...

Como una duda, se puede hacer i2c entre 8 pics

Robotypic dijo...

Si. Pero cada uno con su propia dirección I2c.

Unknown dijo...

Disculpe que pasa si no conecta la memoria EEprom

Unknown dijo...

Buenas noches, los archivos de ejemplo estan privados? No puedo acceder a ellos. Saludos

Robotypic dijo...

Hola.
Los archivos de descarga son públicos. El enlace lo he verificado y funciona correctamente. Prueba a intentarlo de nuevo.

Related Posts Plugin for WordPress, Blogger...

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