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
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"
}
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.
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
Todos los archivos se pueden descargar en el siguiente enlace:
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
- Windows xp y windows 7
- Proteus V7.7 SP2
- CCS PIC C COMPILER v4.084
23 comentarios:
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!!!
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
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);
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
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í.
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!
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
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.
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
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.
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.
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.).
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
Hola. El acceso es libre. No es necesario ningún tipo de permiso.
Si basta con pinchar en el directamente Gracias La negación ocurre con la mania de querer abrirlo en una segunda pagina
Exelente aporte, una pregunta modificando un poco la programacion funciona igual para los pic 16f877a?
Si. Ambas programaciones serían muy similares entre 16f876a y 16f877a.
Como una duda, se puede hacer i2c entre 8 pics
Si. Pero cada uno con su propia dirección I2c.
Disculpe que pasa si no conecta la memoria EEprom
Buenas noches, los archivos de ejemplo estan privados? No puedo acceder a ellos. Saludos
Hola.
Los archivos de descarga son públicos. El enlace lo he verificado y funciona correctamente. Prueba a intentarlo de nuevo.
cuando lo meto a un pic16f887 no prende el teclado ya cambien el pic en la cabecera del codigo que puedo hacer para que funcione igual que con el pic que utilzaste
Publicar un comentario