# Protocolo I2C entre 2 pic 16f876



## shougo (Ago 24, 2006)

Saludos amigos
Les comento un poco lo que quiero hacer: Un pic 16f876 en modo maestro quiero que le de información a un pic 16f876 modo esclavo. Hasta ahora lo que intenta hacer mi programa es prender un par de leds en la puerta B del esclavo cada vez que recibe un dato válido.
El programa cuando lo pruebo en protoboard no está funcionando, y no se como simular en mplab v7.4 la comunicación I2C.

Anexo les pongo el código de ambos programas

PIC Maestro
***********************************************************************

```
;Programa de Prueba Micro maestro
;se conecta mediante I2C con micro esclavo

	LIST		P=16F876
	INCLUDE		<P16F876.INC>
	__CONFIG	_CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

	CBLOCK 0x21 
	ENDC
	
	ORG	0
	goto Inicio
	ORG	4
	goto Interrupcion
	
Inicio
	clrf PORTC			;limpio puerto c
	clrf PORTB			;limpio puerto b
	bsf STATUS,RP0		;cambio al banco 1
	movlw b'11111100'	                ;inicializa PORTC como entradas
	movwf PORTC		;PORTC 0,1 leds de visualizacion	
	clrf PORTB			;inicializo como salidas para leds	
	movlw b'10000000'
	movwf SSPSTAT		;Velocidad Standard con niveles I2C
	movlw .9
	movwf SSPADD		;Velocidad del bus 100KHz
	bsf PIE1,SSPIE		;activo interrupcion del MSSP
	bcf STATUS,RP0		;cambio al banco 0
	movlw b'00101000'	                ;Modo maestro con 7 bits de direccion
	movwf SSPCON		;Módulo MSSP encendido
	bcf PIR1,SSPIF		;clear de la bandera del I2C
	movlw b'10000000'
	movwf INTCON		;activacion general de interrupciones

lazo
	bsf PORTB,0
	bcf PORTB,1
	call Retardo_1s
	bcf PORTB,0
	bsf PORTB,1
	call Retardo_1s
	call S_START
	movlw 0xA2			;Direccion esclavo b'1010001'
					;modo escritura, ultimo bit 0	
	call SEND_B			;Indico al micro que voy a escribir
	movlw 0x30			;en la posición 0x30
	call SEND_B
	movlw 0x00
	call SEND_B
	call S_STOP
	goto lazo			                ;del maestro via I2C

Interrupcion
	retfie

	INCLUDE <RETARDOS.INC>
	INCLUDE <I2C_Lib.INC>
	end
```
**************************************************************************
Los retardos de 1 segundo y la librería de I2C funcionan bien

Ahora el código del PIC esclavo
*************************************************************************

```
;Programa de Prueba Micro esclavo
;se conecta mediante I2C con micro maestro


	LIST		P=16F876
	INCLUDE		<P16F876.INC>
	__CONFIG	_CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

	CBLOCK  0x21
	ENDC
	
	ORG	0
	goto Inicio
	ORG	4
	goto Interrupcion
	
Inicio
	clrf PORTC			;limpio puerto c
	clrf PORTB			;limpio puerto b
	bsf STATUS,RP0		;cambio al banco 1
	movlw b'11111100'	                ;inicializa PORTC como entradas
	movwf PORTC		;PORTC 0,1 leds de visualizacion
	clrf PORTB			;inicializa PORTB como salida de leds		
	movlw b'10000000'
	movwf SSPSTAT		;Velocidad Standard con niveles I2C
	movlw 0xA2
	movwf SSPADD		;Direccion del esclavo
	bsf PIE1,SSPIE		;activo interrupcion del MSSP
	bcf STATUS,RP0		;cambio al banco 0
	movlw b'00111110'	                ;Modo esclavo con 7 bits de direccion
	movwf SSPCON		;Módulo MSSP encendido
	bcf PIR1,SSPIF		;clear de la bandera del I2C
	movlw b'10000000'
	movwf INTCON		;activacion general de interrupciones

lazo
	nop			;lazo infinito esperando datos
	goto lazo			;del maestro via I2C

Interrupcion
	btfss PIR1,SSPIF	;Pregunto si fue interrupcion del I2C
	goto fin		;no fue
	bcf PIR1,SSPIF	;limpio bandera
	bsf PORTB,0	;prendo leds
	bcf PORTB,1
	call Retardo_500ms	;espero tiempo para verlo
	bcf PORTB,0	;apago leds
	bsf PORTB,1
	call Retardo_200ms	;espero a ver leds
fin
	retfie

	INCLUDE <RETARDOS.INC>
	end
```
***********************************************************************

Como verán, el programa es bastante simple. Se me ocurre que puede ser un error de configuración de algún registro pero no consigo dar con el error.

Muchas gracias de antemano por cualquier ayuda que me puedan ofrecer


----------



## okcomputer (Sep 7, 2006)

Si averiguas como simular eso con el Mplab me avisas.. ya que lo busque como loco y no encontre como, al parecer el Mplab no simula Hardware.....
yo tengo una rutina para tx y rx usando I2C, no es tan simple como la tuya ya que maneja los eventos de transmisión, si te interesa te la mando ok

PD: conecte un PIC con una memoria serial y un IC timmer
saludos


----------



## shougo (Sep 8, 2006)

Si me interesa mucho, sobretodo si dices que te funciona bien! Nunca supe como simularlo en mplab y sigo teniendo los mismos errores en protoboard.
Cualquier cosa en la quete pudiese ayudar, con mucho gusto

Muchas gracias


----------



## barthsympson (Abr 16, 2007)

Estuve revisando el codigo y me parece que el error esta en el registro INTCON se supone que debe estar siempre activado el permiso global de interrupciones y el de perifericos, revisalo.

Avisame si funciona luego de esto, tambien estoy haciendo un codigo para I2C y la verdad que estoy recien haciendo mis primeros codigos, pero I2C, sin embargo ya hice varios para PIC, tambien te sugiero que revises el archivo AN735 de microchip, ahi tienen codigo de las rutinas de comunicacion con I2C, y estuve simulandolos en MPLAB, ah por cierto este simulador no tiene las herramientas para simular comunicacion serial.

Yo simulo activando los registros y flags directamente y el codigo de la nota AN735 si funciona en simulador, ahora justamente estoy trabajando en incorporar el codigo en mi proyecto.

aunque todavia me queda una duda, si es necesario desactivar el timer 0 y direccionarlo al WDT para que funcione el I2C, por lo que estoy viendo creo que no tiene nada que ver, si sabes algo dime por fa.


----------



## Gregory (Mar 25, 2009)

hola que tal necesito comunicar 3 pic donde uno de los tres(3) sea el servidor o matrix ;osea como especie de una red lan pero con micros ;ademas la comunicacion entre los pics se deben dar a traves de distintos protocolos tales como: RS-232 , i2c , rs 485 ,spi ....espero me ayuden ¿ por donde comienzo? cualquiero orientacion sera agradecida


----------



## KARITOU (Abr 9, 2009)

hola a todos:

quisiera solicitar su ayuda con un problemita que tengo, la idea es realizar una comunicacion i2c con tres pic 16f877a uno maestro y dos esclavos, tengo un codigo que funciona simulado en proteus y la verdad me parece muy simple pero cuando lo monto en protoboar no funciona, claro esta que este es simplemente maestro y esclavo el esclavo se inicializa mostrando un mensaje en la lcd pero la comunicacion no la realiza o almenos eso creo, el codigo esta en c es un ejemplo como para darme una idea ojala puedan colaborarme es el primer proyecto que realizo en comunicacion i2c y estoy tratando de entender.


----------



## KARITOU (Abr 9, 2009)

perdon aqui pongo los codigos

esclavo


```
#include <16f877.h>
#fuses XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#include <lcd.c>

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, ADDRESS=0X08, FAST , FORCE_HW)


void main(void)
{

      int dato;

      lcd_init();
      lcd_putc("Esperando");

      while(TRUE)
      {
         //i2c_poll solo se puede usar por hardware, detecta un byte en el buffer
         //seguidamente se llama a la funcion i2c_read que devolvera el byte recibido ó 5 ó 6

         if(i2c_poll())
            {
               dato=i2c_read();
               lcd_putc("\f");
               printf(lcd_putc,"El dato es el %i",dato);
            }

      };
}





maestro


#include <16f877.h>
#fuses XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#include <lcd.c>

#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3,ADDRESS=0X01,FAST,FORCE_HW)

void main(void)
{

      int buffer;

      delay_ms(1000);      //retardo, por si acaso no da tiempo al esclavo a "inicializarse" para
                           //poder esperar a la información que le puede enviar el master

      lcd_init();


      while(TRUE)
      {
         if((!input(PIN_A0)))
            {
               i2c_start();      //condicion de inicio
               i2c_write(0x08);  //direccion del esclavo con el que haremos la comunicacion

               i2c_write(5);  //enviamos un dato, p.e el entero 5
               i2c_stop();    //finalizacion de la comunicacion

               delay_ms(1000);   //introducimos retardo para que no este constantemte escribiendo

            }

         if((!input(PIN_A1)))
            {
               i2c_start();      //inicio
               i2c_write(0x08);  //direccion del esclavo

               i2c_write(6);     //enviamos un dato, p.e el entero 6
               i2c_stop();       //parada

               delay_ms(1000);

            }
            
            
      };
}
```


----------



## adrianjpc (May 23, 2009)

KARITOU tu programa ya esta probado yo necesito hacer la comunicacion entre dos pic pero no me decido que tipo de comunicacion realizar si i2c o serial  cual me recomiendas

espero tu respuesta


----------



## Gregory (May 23, 2009)

i2c es una comunicacion serial , spi es mas facil de implementar


----------



## adrianjpc (May 23, 2009)

me recomiendad I2C tiene algun ejemplo de como hacer la comunicacion en lengua C 
en especial en CCS C compiler


----------



## Gregory (May 23, 2009)

spi es muy facil de hacer con el ensamblador ,pero no lo he pasado a c quizas un dia de estos


----------



## albermillan69 (Feb 11, 2010)

YO necesito es hacer la cuestion al contrario!! osea necesito enviar un dato del esclavo al maestro!!! sera q me pueden ayudar!! uso CCS y 2 pic 18F4550?

Gracias...


----------



## __dero__ (May 9, 2010)

buenas alguien me puede ayudar necesito enviar informacion al esclavo para q me active unos pines... y el esclavo envie al maestro del estado de otros pines =S sera q alguien puede ayudar?


----------



## WODZAROD (Jul 23, 2010)

Hola, estoy realizando un proyecto con comunicación I2C entre dos PIC 18F4550, en CCS, la programación aparentemente está bien, funciona bien en simulación Proteus, pero al implementarlo en protoboard no funciona, no realiza la comunicación I2C. También he estado probrando entre PIC18F4550 y PIC16F877A, la simulación sale OK, al implementarlo no funciona. Por favor, alguien me puede pasar un ejemplo con I2C entre dos PICs 18F4550. Se lo agradecería mucho.

Zarbio Rómulo Ordóñez Dávila.


----------



## elegaba (Jul 23, 2010)

saludos, muestra el codigo y lo reviso, depronto sea algo del codigo, debes saber que proteus es algo casi ideal y no hay que hacer ciertas cosas para que un pic funcione, pero en fisico ya la vaina es diferente...


----------



## WODZAROD (Jul 23, 2010)

Hola, pongo el código en CCS de la comunicación I2C, no me sale. Revisé detalladamente todas las configuraciones de los PICs y no encuentro el error. Por algún foro de internet, mencionaban que era error del compilador CCS, pero no estoy seguro que sea verdad. El programa lo debo hacer en CCS.

Detalles:

- Usando 2 PICs PIC18F4550 (uno maestro y otro esclavo), aparentemente está bien el programa, la simulación en Proteus no funciona bien, al implementarlo no se realiza la comunicación I2C, sólo me muestra por el Puerto D del Maestro el número 35 (0011 0101) y después de casi 1seg el número 42(0100 0010), que no sé de dónde sale este último número (42).

- Al resetear el esclavo, me muestra FF en el Puerto D del Maestro.

Nota: 
- Probé este mismo programa entre PIC18F4550 (Maestro) y PIC18F877 (Esclavo) y me sale bien la simulación, pero al implementarlo no me sale.
- El código creado en cada archivo .h (configuraciones) de CCS lo he copiado al archivo .c, por facilidad.

Te adjunto el programa que estoy desarrollando entre 2 PICs PIC18F4550.

Saludos.


----------



## hexapodo (Oct 25, 2010)

Hola WODZAROD, lograste comunicar dos pics por I2C?
estoy tratando de establecer comunicacion I2C entre dos 16f877A pero no he podido, tienes algún otro código que me lo puedas prestar?
gracias


----------



## cricape06 (Abr 13, 2011)

Hola, colegas es que necesito comunicar dos pic por medio de i2c, cada pic tiene un teclado matricial y una lcd alfanumerica, y ps de un pic se puede enviar informacion para visualizar en la lcd del otro pic..... Espero puedan ayudarmen graciasss


----------



## Maverick911T (May 7, 2011)

Hola Karitou, antes que nada espero q no sea demaciado tarde la respuesta, probe tu codigo en hardware , solo cambie la configuracion del reloj por HS y por uno de 12 000 000 y funciono bien, la falla se deba a un problema de hardware, si aun es tiempo y puedo ayudarte con gusto lo hare. 

Saludos!


----------



## arsfigo07 (May 24, 2011)

Bueno es la primera vez que publico algo pero los programas que vienen al principio si sirven los probe con el pic 16f877a y si se comunican; solo hay que hacer unos pequeños cambios. Una vez que los tenga ya bien comentados los subo (aunque no se como pero ahi le veo). La verdad muy buen aporte....


----------



## arsfigo07 (May 24, 2011)

Bueno esto es lo que yo entrego la comunicacion entre los dos pics es por medio del puerto C, que es donde se tiene el I2C, las lineas SDA y SCL. En el archivo todo se compila en el mplab los archivos RETARDOS/I2C son guardados como .INC y el master/slave como .ASM.

Si alguien tiene mas dudas pues mas o menos ya le entendi a este tema.

Suerte y espero le sirva a alguien.

PD: Estan ya calados no tienen fallas (solo podria ser de HW).


----------



## csarpc (Jun 16, 2011)

alguien tiene la simulacio de I2C en mikroc para los pic 16F877A en maestro y esclavo?


----------



## GRUTTIS (Ago 24, 2011)

Hola gente, me gustaría comunicar dos microcontroladores por el bus I2c. Ya probé programando uno como master (PIC16F877), y como esclavos tengo una memoria 24C02, y un reloj DS1307, esta comunicación me salió perfecta, pero nunca pude programar un microcontrolador como esclavo, me gustaría usar un PIC16F873: Espero que alguien haya hecho la experiencia y pueda compartirla conmigo, aclaro que sigo programando en assembler, traté de descargar ese archivo, pero no pude saludos Darío.


----------



## antoniotablas (Nov 24, 2013)

shougo dijo:


> Saludos amigos
> Les comento un poco lo que quiero hacer: Un pic 16f876 en modo maestro quiero que le de información a un pic 16f876 modo esclavo. Hasta ahora lo que intenta hacer mi programa es prender un par de leds en la puerta B del esclavo cada vez que recibe un dato válido.
> El programa cuando lo pruebo en protoboard no está funcionando, y no se como simular en mplab v7.4 la comunicación I2C.
> 
> ...










necesito la libreria i2c para realizar la comunicacion,


----------



## D@rkbytes (Nov 24, 2013)

El último mensaje de *@shougo* fue en *12/09/2006*. Así que dudo mucho que te responda.

Mira el ejemplo del archivo comprimido que subió *@arsfigo07* en su *post #21*, usa la librería "*I2C.INC*"
Posiblemente te sirva su ejemplo o la librería.

Suerte.


----------



## dcsalg (Abr 25, 2016)

Hola GEnte, capaz puedan ayudar con esto quiero comunicar como veo en esta parte del foro 2 pic mediante I2C estoy utilizando  CCS, pero el problema que no logro la comunicacion quiero creer que es problema del simulador porque es algo basico un pic escanea una serie de teclas y al precionar quiero que envie ese dato a otro pic y que me lo muestre en el LCD, eso es lo que quiero hacer por ahora, igual mas adelante no va hacer eso pero quiero lo basico que es eso ahora pero no sale. Voy a adjuntar el archivo. a ver que se puede hacer. Seguro es algo que estoy pasando por alto y no lo veo.

por ejemplo si preciono una tecla que esta en fila 1 columna 1 envia el dato 11 y en el display del otro pic muestra el 11, si preciono columna 2 fila 1, el 12 y asi...
como tambien si preciono colimna 1 y fila 2 que muestre el 21. nose si me explico osea el primer numero es la fila y el sugundo la columna.

estaria bueno si fuera mediante una interrupcion, la deteccion del pic esclavo. 

Gracias


----------

