Autor Tema: CONFIGURACION DEL I2C  (Leído 4747 veces)

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

Desconectado microcarsil

  • PIC10
  • *
  • Mensajes: 44
CONFIGURACION DEL I2C
« en: 06 de Enero de 2007, 21:21:59 »
Hola amigos estuve probando la comunicacion I2C con los dspic y funciona bien siempre y cuando ponga osciladores externos sin PLL, por ejemplo con 8 mhz y 20 mhz funciona bien, pero resulta que si pongo un cristal de 7.3728 mhz y activo el PLL a 16 para obtener MIPS = (7.3728 Mhz * 16/4)= 29.49 no funciona, para ilustrar un poco lo que hice voy a poner el codigo que funciona bien con un cristal de 20 mhz.

Código: [Seleccionar]
#include <p30f3014.h>
#include <i2c.h>

#define MIPS 5 // MIPS = cristal/4 = 20 Mhz/ 4 = 5

 _FOSC( CSW_FSCM_OFF & HS); 
 _FWDT(WDT_OFF);               //Watchdog  deshabilitado
 _FBORPOR(PBOR_OFF & PWRT_OFF & MCLR_EN);   //Reset por baja tensión deshabilitado, retardo al inicio deshabilitado, pint MCLR habilitado como reset
 _FGS(CODE_PROT_OFF);        //Protección de código deshabilitado

void Tdelay_ms(unsigned long x);  // Funcion para hacer retardos en milisegundos, Cortesía de Nocturno

int main ()
{
      unsigned char x=0;   
      unsigned int config2, config1;

      config1 = (I2C_ON & I2C_IDLE_CON & I2C_CLK_HLD &
      I2C_IPMI_DIS & I2C_7BIT_ADD &
      I2C_SLW_EN & I2C_SM_DIS &
      I2C_GCALL_DIS & I2C_STR_DIS &
      I2C_NACK & I2C_ACK_DIS & I2C_RCV_DIS &
      I2C_STOP_DIS & I2C_RESTART_DIS &
      I2C_START_DIS);

      config2 = 7; //((FCY/SPEED)-(FCY/1111111)) - 1;  para 5 mhz  & 400000 i2c rate   FCY = MIPS = 5
         //((5000000/400000)-(5000000/1111111))-1 = 7

      TRISBbits.TRISB0 = 0;           //Configuramos RB0 como salida                 
      OpenI2C(config1,config2);   //open the I2C module
      IdleI2C();                //make sure bus is idle
       
      while(1)                     
     {       
         LATBbits.LATB0=1;   
         Tdelay_ms(1000); 
         
         StartI2C();                //transmit Start bit
         while(I2CCONbits.SEN );    //wait till start sequence is complete
         MasterWriteI2C(0xa0);    // Write Slave address and set master for transmission
         while(I2CSTATbits.TBF);   // Wait till address is transmitted
         while(I2CSTATbits.ACKSTAT);
         MasterWriteI2C(x);     // Transmit data 
         while(I2CSTATbits.TBF);
         while(I2CSTATbits.ACKSTAT);
         StopI2C();
         while(I2CCONbits.PEN);     // Wait till stop sequence is completed
     
         LATBbits.LATB0=0; 
         Tdelay_ms(1000);

         x++;
      }

     return 0;
}

Ahora presento el programa para el oscilador de 7.3728 Mhz con PLL igual a 16 que no funciona

Código: [Seleccionar]
#include <p30f3014.h>
#include <i2c.h>

#define MIPS 29.49 // MIPS = cristal*16/4 = 7.3728*16 Mhz/ 4 = 29.49

 _FOSC( CSW_FSCM_OFF & XT_PLL16); 
 _FWDT(WDT_OFF);               //Watchdog  deshabilitado
 _FBORPOR(PBOR_OFF & PWRT_OFF & MCLR_EN);   //Reset por baja tensión deshabilitado, retardo al inicio deshabilitado, pint MCLR habilitado como reset
 _FGS(CODE_PROT_OFF);        //Protección de código deshabilitado

void Tdelay_ms(unsigned long x);  // Funcion para hacer retardos en milisegundos, Cortesía de Nocturno

int main ()
{
      unsigned char x=0;   
      unsigned int config2, config1;

      config1 = (I2C_ON & I2C_IDLE_CON & I2C_CLK_HLD &
      I2C_IPMI_DIS & I2C_7BIT_ADD &
      I2C_SLW_EN & I2C_SM_DIS &
      I2C_GCALL_DIS & I2C_STR_DIS &
      I2C_NACK & I2C_ACK_DIS & I2C_RCV_DIS &
      I2C_STOP_DIS & I2C_RESTART_DIS &
      I2C_START_DIS);

      config2 = 46; //((FCY/SPEED)-(FCY/1111111)) - 1;  para 29.49 mhz  & 400000 i2c rate   FCY = MIPS = 29.49
         //((29491200/400000)-(29491200/1111111))-1 = 46

      TRISBbits.TRISB0 = 0;           //Configuramos RB0 como salida                 
      OpenI2C(config1,config2);   //open the I2C module
      IdleI2C();                //make sure bus is idle
       
      while(1)                     
     {       
         LATBbits.LATB0=1;   
         Tdelay_ms(1000); 
         
         StartI2C();                //transmit Start bit
         while(I2CCONbits.SEN );    //wait till start sequence is complete
         MasterWriteI2C(0xa0);    // Write Slave address and set master for transmission
         while(I2CSTATbits.TBF);   // Wait till address is transmitted
         while(I2CSTATbits.ACKSTAT);
         MasterWriteI2C(x);     // Transmit data 
         while(I2CSTATbits.TBF);
         while(I2CSTATbits.ACKSTAT);
         StopI2C();
         while(I2CCONbits.PEN);     // Wait till stop sequence is completed
     
         LATBbits.LATB0=0; 
         Tdelay_ms(1000);

         x++;
      }

     return 0;
}

void Tdelay_ms(unsigned long x)
 {
  unsigned long Limite;
  Limite = x*MIPS*1000-48;
  TMR2=-(Limite);
  TMR3=(-Limite)>>16;
  T2CON = 0x8008;
  while (IFS0bits.T3IF==0);
  IFS0bits.T3IF=0;
}


Pues bien este ultimo codigo es el que tiene el problema de no enviar los datos por el I2C, el retardo de la funcion que hizo Nocturno si funciona con la configuracion del cristal y el PLL, no se que este fallando y cual es la configuracion que se deba modificar del I2C. Tambien probe con otro cristal de 8 mhz y un pll de 16 obteniendo por overclocking a 32 MIPS y  pasa lo mismo que el anterior, solo sirve la funcion del Tdelay_ms pero no transmite nada por I2C. Cualquier sugerencia es bienvenida GRACIAS.
« Última modificación: 06 de Enero de 2007, 21:25:44 por carsil »
Microcarsil

Desconectado microcarsil

  • PIC10
  • *
  • Mensajes: 44
Re: CONFIGURACION DEL I2C
« Respuesta #1 en: 07 de Enero de 2007, 17:27:40 »

Problema solucionado ya FUNCIONA  :-/ :-/ :-/

pues era solo cuestion de poner un retardo Tdelay_ms(1)  despues de las funciones MasterWriteI2C(0xa0); y MasterWriteI2C(x) quedando parte del codigo de la siguiente manera:

Código: [Seleccionar]
         StartI2C();                //transmit Start bit
         while(I2CCONbits.SEN );    //wait till start sequence is complete
         MasterWriteI2C(0xa0);    // Write Slave address and set master for transmission
         Tdelay_ms(1)   // RETARDO NECESARIO
         while(I2CSTATbits.TBF);   // Wait till address is transmitted
         while(I2CSTATbits.ACKSTAT);
         MasterWriteI2C(x);     // Transmit data 
         Tdelay_ms(1)   // RETARDO NECESARIO
         while(I2CSTATbits.TBF);
         while(I2CSTATbits.ACKSTAT);
         StopI2C();
         while(I2CCONbits.PEN);     // Wait till stop sequence is completed

El retardo que hay que esperar lo he bajado hasta los 50 us y sigue funcionando sin problemas.

Saludos  8)
Microcarsil

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: CONFIGURACION DEL I2C
« Respuesta #2 en: 08 de Enero de 2007, 02:34:43 »
Raro, raro.
En teoría con esta línea que ya tenías puesta no sería necesario retardo alguno:

while(I2CSTATbits.TBF);   // Wait till address is transmitted

Desconectado microcarsil

  • PIC10
  • *
  • Mensajes: 44
Re: CONFIGURACION DEL I2C
« Respuesta #3 en: 08 de Enero de 2007, 04:37:16 »

De hecho esa fue mi sorpresa que no funciona jejeje, pero estuve investigando y se puede resolver sin el retardo solo agregando la funcion  IdleI2C() que es la encargada de esperar hasta que el bus i2c este inactivo, bueno el codigo queda de la siguiente forma:

Código: [Seleccionar]
StartI2C();                //transmit Start bit
while(I2CCONbits.SEN );    //wait till start sequence is complete
MasterWriteI2C(0xa0);    // Write Slave address and set master for transmission
IdleI2C();
MasterWriteI2C(x);     // Transmit data 
IdleI2C();
StopI2C();
while(I2CCONbits.PEN);     // Wait till stop sequence is completed

Ya lo probe y funciona muy bien  8)

Saludos
Microcarsil

Desconectado stevengalindom

  • PIC10
  • *
  • Mensajes: 18
Re: CONFIGURACION DEL I2C
« Respuesta #4 en: 24 de Agosto de 2011, 18:27:05 »
hola es muy interesante este trabajo pero no enteidno nada y necesito configurar mi dspic30f4011 par q escuche datos de un sensor que trabaja con comunicacion i2c sera que conocen de algun tutorial que explique eso que hiciste desde 0 por que sinceramente es la primera vez que voy a intentar i2c y si tienen algun programa que configure los registros y no por libreria seria mejor por q esto de las librerias lo enteido poco

gracias por su ayuda sera de vital importancia