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.
#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
#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.