Autor Tema: Comunicacion I2C que FUNCIONA  (Leído 3126 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado juanelete

  • PIC12
  • **
  • Mensajes: 74
Comunicacion I2C que FUNCIONA
« en: 07 de Marzo de 2005, 16:31:00 »
Hola a tod@s:

LLevo varia semanas intentando comunicar dos PIC mediante I2C, y por fin lo he conseguido.

He descubierto que hay un par de "trucos" para que funcione correctamente.

Os pongo unos ejemplos simplificados al maximo:

El master:

///////////////////////////////////////////////////////////////////////////////////////////////////////
//                            INT_SSP_MASTER                                                                    //
//                                                                                                                            //
// Comunicacion I2C entre dos PIC 16F876                                                           //
//                                                                                                                           //
// Este es el que va a actuar como master. Enviara secuencialmente una serie   //
// de numeros que iran incrementandose de uno en uno.                                    //
//                                                                                                                           //
//////////////////////////////////////////////////////////////////////////////////////////////////////


#INCLUDE <16F876.H>

#fuses HS,NOWDT,NOPROTECT,NOLVP

#ORG 0x1F00,0x1FFF {}   //Necesario para bootloader

#use delay(clock=20000000)

#use I2C(master,sda=PIN_C4,scl=PIN_C3)

//Leds que se iluminaran
#DEFINE LED1 PIN_A1  //PIN 3

#DEFINE PIC2 0x02    //Direccion dispositivo PIC 2 (esclavo)


void main()
{
   int8 dato=0;
 
   delay_ms(1000);  //Hay que dejar tiempo que se inicialize el esclavo

   while(1)
   {
      output_high(PIN_A1);
     
      delay_ms(1000);

      i2c_start();    // Condicion Inicio

      i2c_write(PIC2);// Direccion dispositivo

      delay_ms(3);    // *** Necesario ***

      i2c_write(dato);// dato

      delay_ms(3);    // *** Necesario ***

      i2c_write(++dato);// dato

      i2c_stop();     // Stop
     
      output_low(PIN_A1);
      delay_ms(1000);
    }
}


Y el Esclavo:

///////////////////////////////////////////////////////////////////////////////////////////////////////
//                            INT_SSP_SLAVE                                                                       //
//                                                                                                                            //
// Comunicacion I2C entre dos PIC 16F876                                                            //
//                                                                                                                            //
// Este es el que va a actuar como ESCLAVO. Recibira secuencialmente una serie//
// de numeros que iran incrementandose de uno en uno y los mostrara en         //
// pantalla                                                                                                             //
//////////////////////////////////////////////////////////////////////////////////////////////////////

#INCLUDE <16F876.H>

#fuses HS,NOWDT,NOPROTECT,NOLVP

#ORG 0x1F00,0x1FFF {}   // Necesario para bootloader

#use delay(clock=20000000)

#DEFINE PIC2 0x02

#use I2C(slave,sda=PIN_C4,scl=PIN_C3,address=PIC2)

#define use_portb_lcd TRUE //Necesario si usamos el portB para el LCD, y que sea compatible con LCD.C
#include <LCD.C>


//VARIABLES GLOBALES
int8 buffer[2];
int1 recibido=0;


#int_ssp               //Rutina Interrupción I2C
void int_sspi2c()
{
   disable_interrupts(int_ssp);  // *** Necesario ***

   buffer[0]=i2c_read();
   
   buffer[1]=i2c_read();
   
   recibido=1;
}



void main()
{

   delay_ms(50);

   lcd_init();
   lcd_putc("fPreparado...
");

   delay_ms(300);

   enable_interrupts(int_ssp);
   enable_interrupts(global);

   while(1)
   {
      if(recibido==1)
      {
         printf(lcd_putc,"fb[0]=%U b[2]=%u",buffer[0],buffer[1]);
         
         recibido=0;
         
         enable_interrupts(int_ssp);  // *** Necesario ***
      }
     
   }
}



Los "trucos" a los que me referia antes son los siguientes:

Es fundamental poner un pequeño retardo despues de enviar la direccion del dispositivo:

i2c_write(PIC2); // Direccion dispositivo
delay_ms(3);    // *** Necesario ***

Y luego tambien poner un retardo despues de enviar cada dato:

i2c_write(dato);// dato
delay_ms(3);    // *** Necesario ***

El otro "truco" es que, en el esclavo, justo cuando se entra en la interrupcion SSP hay que desactivarla antes de hacer nada:

disable_interrupts(int_ssp);  // *** Necesario ***

y luego cuando ya se ha terminado de procesar todos los datos volver a activarla:

enable_interrupts(int_ssp);  // *** Necesario ***

Os puedo asegurar que estos ejemplos, asi, funcionan perfectamente, si se quitan los retardos o no se desactiva la int, no funcionan. Palabrita de "Niño Jesus".

Saludos

Desconectado manex_1987

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1127
RE: Comunicacion I2C que FUNCIONA
« Respuesta #1 en: 08 de Marzo de 2005, 13:17:00 »
Jeje no es la mala... aver si tengo tiempo para testearlo en proteus.

Aun asi, lo que me mosquea son esos delays... 6ms por dato? Eso reduce el bitrate a 160 bps... y eso en ciertas aplicaciones pueSsSsSs...Avergonzado  No se puede reducir ese delay?

salu2!

Desconectado oshow

  • PIC18
  • ****
  • Mensajes: 321
RE: Comunicacion I2C que FUNCIONA
« Respuesta #2 en: 08 de Marzo de 2005, 19:48:00 »
En teoría deberia funcionar sin los delays, aunque no pongo en duda lo que dice juanelete. Yo hice hace tiempo un ejemplo muy sencillo con simulación en proteus, pero sin usar la interrupción. Lo tengo en esa cosa que llamo web, que es tan cutre y nunca acabo, pero por si sirve de ayuda os lo pego aquí.

http://www.telecable.es/personales/trelles2

Es muy sencillo, pero si necesitais otro con más detalle, recuerdo que en el foro había varios ejemplos, incluso uno comunicando 3 pics, pero no recuerdo donde está posteado.

Un saludo.

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Comunicacion I2C que FUNCIONA
« Respuesta #3 en: 08 de Marzo de 2005, 21:20:00 »
En la carpeta de ejemplos C hay un par de ejemplos

http://personal.auna.com/asencio5/Ejemplos%20C/I2C/

Desconectado ppalou

  • PIC10
  • *
  • Mensajes: 36
RE: Comunicacion I2C que FUNCIONA
« Respuesta #4 en: 10 de Marzo de 2005, 01:38:00 »
Habeis hecho alguna comunicación I2C entre una PIC y una memoria? la que tengo es la 24LC512 .

Es que lo estoy intentando y no hay manera.


 

anything