Hola de nuevo, después de un finde bastante productivo, he conseguido configurar el modulo I2C y hacerlo funcionar, eso despues de leer en este foro algunos ejemplos. Este código esta basado en el ejemplo que puso Microcarsil sobre I2C en este foro.
EJEMPLO 3: Comunicación I2C
/*****************************************************************
NIUTON
Fecha: 7-3-2010
Descripción: Comunicación mediante I2C a 400KHz
Oscilador: cristal XT a 7.37MHZ con PLL16
/*****************************************************************/
#include "p30f3013.h"
#include "stdlib.h"
#include "stdio.h"
#include "libpic30.h" // LIBRERIA PARA DELAYS
#include "uart.h" // LIBRERIAS PARA RS232
#include "i2c.h" // LIBRERIAS PARA I2C
// FUSES DE CONFIGURACIÓN
_FOSC(CSW_FSCM_OFF & XT_PLL16); // CONFIGURACIÓN DEL OSCILADOR A 7.37MHz con PLL 16
_FWDT(WDT_OFF);
_FBORPOR(MCLR_EN & PBOR_OFF & PWRT_OFF);
_FGS(CODE_PROT_OFF & GWRP_OFF); // NO PROTECCIÓN DE CODIGO
unsigned char ack = 0, no_ack=1;
unsigned char datos_int_reg = 0;
// DEFINICIONES DE CONSTANTES
#define FCY 29480000UL // VALOR DE OS MIPS PARA LA FUNICON DELAY Y BAUDIOS
#define FSCL_I2C 400000 // VALOR DE BAUDE RATE DE COMUNICACIÓN I2C
#define I2CBRGVAL ((FCY/FSCL_I2C)-(FCY/1111111))-1
void inicializar_I2C(void){
unsigned int config2, config1;
CloseI2C(); // Cierra el modulo I2C
ConfigIntI2C(MI2C_INT_OFF & SI2C_INT_OFF); //COnfiguracion de interrupciones
config2 = I2CBRGVAL; //Configuración de la velocidad en el bus I2C 400KHz
// Configure I2C for 7 bit address mode
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);
OpenI2C(config1, config2);
IdleI2C(); //Antes de hacer una escritura en el I2C debe estar en modo IDLE
}
int main(void){
int i=0;
char address_W;
// VARIABLES
address_W = 0x64; // Dirección para escritura
TRISB=0x0011; // Configuramos RB9-RB0 como salidas.
TRISC=0x0000; // Configuramos RB9-RB0 como salidas.
inicializar_I2C();
LATBbits.LATB9 = 0x1; // ACTIVAR LED
while(i==0){
__delay_ms(500);
IdleI2C(); // Realiza una espera hasta que el I2C esté listo para usarse
StartI2C();
while(I2CCONbits.SEN); //ESPERO QUE SE COMPLETE START
MasterWriteI2C(address_W);
while(I2CSTATbits.ACKSTAT == no_ack);
MasterWriteI2C(0x01); // valor = 0x01 para empezar a medir
while(I2CSTATbits.ACKSTAT == no_ack);
StopI2C();
while(I2CCONbits.PEN); //Espero a que termine la secuencia de stop
IdleI2C(); // Realiza una espera hasta que el I2C esté listo para usarse
StartI2C();
datos_int_reg = MasterReadI2C(); IdleI2C(); NotAckI2C();
StopI2C();
while(I2CCONbits.PEN); //Espero a que termine la secuencia de stop
printf("\r\n Registro interno: %d\n", datos_int_reg);
}
return(0);
}
Bueno este es el ejemplo, digo lo de siempre, si hay algo que se pueda mejorar en la eficiencia pues soy todo oidos. Si me ha sucedido algo extraño y es que he necesitado colocar la instrucción IdleI2C para que funcione, ¿se supone que esta función espera a que este disponible el bus?, yo he programado para 400KHZ pero al medir con el analizador se obtiene una frecuencia de 500KHZ ¿ sabéis que puede pasar?.
Esta es una imagen de mi analizador con el ejemplo funcionando: