Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Hola chicos,
Tenemos un problema con un i2c esclavo, estamos usando una rutina para atender al maestro, usando un pic 16F876A como esclavo i2c. El problema es que no se completa nunca una transmisión, es decir el estado que devuelve i2c_isr_state se va incrementando cada vez más y no completarse el envío de datos, al enviar nuevos comandos, se cree que son datos del primer comando.
Estoy usando el puerto serie para depurar y vemos como el state va y va creciendo y al no completarse la transmisión no volvemos al estado 0.
#INT_SSP
void ssp_interupt ()
{
BYTE state;
state = i2c_isr_state(i2cS);
printf("st 0x%xrn", state);
if(state<0x80) //master is sending data
{
if (state==0)
{
} else if (state==1) //first received byte
{
comando = i2c_read(i2cS);
} else if (state==2) { // 2º byte recibido
dato=i2c_read(i2cS);
printf("c: %d, d: %drn", comando, dato);
switch(comando) {
case INIT: printf("Se ha recibido el comando: INITrn");
StopMotores();
break;
case CONSULTA_MOTOR1: printf("Se ha recibido el comando: CONSULTA_MOTOR1rn");
break;
case CONSULTA_MOTOR2: printf("Se ha recibido el comando: CONSULTA_MOTOR2rn");
break;
case MUEVE_MOTOR1: printf("Se ha recibido el comando: MUEVE_MOTOR1rn");
MueveMotor1(dato);
break;
case MUEVE_MOTOR2: printf("Se ha recibido el comando: MUEVE_MOTOR2rn");
MueveMotor2(dato);
break;
case INTERRUPTOR1: printf("Se ha recibido el comando: INTERRUPTOR1rn");
break;
case INTERRUPTOR2: printf("Se ha recibido el comando: INTERRUPTOR1rn");
break;
case INTERRUPTOR3: printf("Se ha recibido el comando: INTERRUPTOR1rn");
break;
case INTERRUPTOR4: printf("Se ha recibido el comando: INTERRUPTOR1rn");
break;
case STOP_MOTOR1: printf("Se ha recibido el comando: STOP_MOTOR1rn");
StopMotor1();
break;
case STOP_MOTOR2: printf("Se ha recibido el comando: STOP_MOTOR2rn");
StopMotor2();
break;
case STOP_MOTORES: printf("Se ha recibido el comando: STOP_MOTORESrn");
StopMotores();
break;
}
i2c_write(i2cS, 67);
} else {
i2c_write(i2cS, 67);
printf("Estado: %drn", state);
dato=i2c_read(i2cS);
printf(" con dato: %drn", dato);
}
}else if (state==0x80) { //master is requesting data
printf("Estado 0x%xrn", state);
output_high(PIN_B1);
switch(comando) {
case INTERRUPTOR1:
if (input(PIN_B4)) {
i2c_write(i2cS, 1);
} else {
i2c_write(i2cS, 0);
}
break;
case INTERRUPTOR2:
if (input(PIN_B5)) {
i2c_write(i2cS, 1);
} else {
i2c_write(i2cS, 0);
}
break;
case INTERRUPTOR3:
if (input(PIN_B6)) {
i2c_write(i2cS, 1);
} else {
i2c_write(i2cS, 0);
}
break;
case INTERRUPTOR4:
if (input(PIN_B7)) {
i2c_write(i2cS, 1);
} else {
i2c_write(i2cS, 0);
}
break;
default:
i2c_write(i2cS, 68);
}
} else {
printf("estado mayor que 0x80, igual %xdrn", state);
i2c_write(i2cS, 68);
}
}
Quizás hay algunos i2c_write de mas o con valores un poco raros, están puestos simplemente para probar, pero no damos con la solución.
Cualquier sugerencia se agradece.
Ciao!