Hola gente
Estoy tratando de implementar una comunicacion I2C completa entre un 18f452 a 20mhz como master y un 18f2550 a 48mhz (20mhz PLL5 :2) como esclavo. Las resistencias pullup son 2K2 con 10K en paralelo, resultando en 1K8. Pensaba que el circuito 18f452 no llevaba pullups, y en el circuito slave los implementé. Aun asi esa resistencia segun he leido, esta aun en baremos aceptables.
El codigo del slave, resumido:
#include <18f2550.h>
#fuses HSPLL,PLL5,CPUDIV1,NOWDT
#use delay(clock=48000000)
#use I2C(slave,sda=PIN_B0,scl=PIN_B1,address=0xa0,force_hw)
...
#INT_SSP
//
void isr4()
{
state = i2c_isr_state();
output_a(0xFF); //Para tener constancia de que ha ocurrido. A esta configurado como digital total.
if(state>=0x80) // Solicitud de envio
{
i2c_write(I2C_BUFFER[i2c_addr+(state-0x80)]); //Envio dato desde direccion, esta
} //se incrementa por cada solicitud antes del STOP.
if (state>=2) // Recibe datos II
{
I2C_BUFFER[i2c_addr+state-2]=i2c_read(); //Segundo y consecutivos datos, la direccion
//se incrementa por cada envio antes del STOP.
if(i2c_addr==9) I2C_READ_RDY=1; //Si se escribe el comando, se sube flag de datos recibidos.
}
if(state==1) //Recibe PRIMER dato
{
i2c_addr=i2c_read(); //Primer dato direccion
}
}
Mencionar, que se sobreentiende que he puesto "enable_interrupts(INT_SSP);" en el programa.
Y el master:
#include <18f452.h>
#fuses HS,NOWDT
#use delay(clock=20000000)
#use i2c(master, sda=PIN_C4,scl=PIN_C3,force_hw)
int i2c_data[10];
int tmp;
void main()
{
output_float(PIN_C4);
output_float(PIN_C3);
setup_timer_0 (RTCC_INTERNAL|RTCC_DIV_4);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);
lcd_init();
printf(LCD_PUTC,"INICIO!!");
delay_ms(1000);
lcd_putc('\f');
while(1)
{
printf(LCD_PUTC,"Start");
delay_ms(1000);
lcd_putc('\f');
i2c_start();
i2c_write(0xa0);
i2c_write(0x00);
i2c_write(0x80);
printf(LCD_PUTC,"Datos");
lcd_putc('\f');
i2c_stop();
printf(LCD_PUTC,"Dato enviado");
delay_ms(1000);
lcd_putc('\f');
i2c_start();
i2c_write(0xa0);
i2c_write(0x00);
i2c_start();
i2c_write(0xa1);
tmp=i2c_read();
printf(LCD_PUTC,"%u",tmp);
i2c_stop();
}
}
Bueno, pues en fin. Alimento los dos, enciendo el tinglado... y el 18f452 funciona como si enviara y leyera bien. Pero el dato que recibo siempre es 0xFF. Quito el 18f2550 de su zocalo, enciendo y... hale! igual igual, se comporta igual. Y el 18f2550 no da constancia de haber entrado en interrupcion (recordemos que cuando entra, se encienden todos los pines del puerto A).
La conexion I2C fisica es correcta, lo he comprobado 1000 veces con el polimetro. Y los pines de SDA y SCL no estan intercambiados ni nada por el estilo. No se que es lo que funciona mal, de veras.
Espero vuestra ayuda!
PD: El slave, simple y llanamente, no entra en la interrupcion...
PD2: El slave, tampoco hace ACK al recibo de un dato.