Tengo un problema al hacer que LPC2148 funcione con el sensor SRF10. LPC es un dispositivo de 3.3v con i2c compatible con 5v (al menos el documento de usuario afirma eso). Por otro lado, hay un dispositivo SRF10 que es de 5v. He probado con ambos niveles como pull-up lvl conectado con una resistencia de 4.7k (tengo 3 dispositivos en la misma línea, así que usé una resistencia de mayor valor).
Lo extraño es que a veces lee el valor correctamente pero falla al leer valores de 2 registros... Básicamente, no funciona.
Ahora, lo que es extraño en esta imagen, es que el nivel lógico en SDA es 0 por defecto y debería ser 1. ¿Eso significa que pull-up no está haciendo bien el trabajo? ¿Podría estar relacionado con las diferencias de nivel lógico entre uc y esclavo?
EDITAR: 01.03
Aquí está mi implementación del estado 0x50, a_chn es i2c0 o i2c1
void slaveDataReceived (uint8_t a_chn)
{
uint8_t k;
volatile unsigned char *i2cConClear;
volatile unsigned char *i2cConSet;
volatile unsigned char *i2cData;
if (a_chn == 1) {
i2cData = (volatile unsigned char *)(0xE005C008);
i2cConClear = (volatile unsigned char *)(0xE005C018);
i2cConSet = (volatile unsigned char *)(0xE005C000);
}
else {
i2cData = (volatile unsigned char *)(0xE001C008);
i2cConClear = (volatile unsigned char *)(0xE001C018);
i2cConSet = (volatile unsigned char *)(0xE001C000);
}
k = *i2cData;
appendToDataBuffer (a_chn, k);
if (i2cDataRcv[a_chn] == i2cDataHead[a_chn]){
I2CMasterState[a_chn] = I2C_IDLE;
*i2cConSet = I2CON_SET_STO;
*i2cConClear = I2CON_CLR_AAC;
}
else {
*i2cConSet = I2CON_SET_AA;
}
*i2cConClear = I2CON_CLR_SIC;
}
Veo condiciones válidas de inicio y reinicio en su forma de onda, por lo que no creo que SDA sea la 'polaridad incorrecta'. La condición de inicio válida está antes de escribir 0xC0 (indicado por el primer punto verde en la captura) y el reinicio válido es el segundo punto verde (antes de 0xC1). El hecho de que SDA permanezca bajo después de que el maestro ACK ACK del esclavo no debería ser un problema siempre que el maestro lo libere antes del próximo flanco ascendente de SCL.
Un problema podría ser el tamaño de los pull-ups. Si está tratando de operar a más de 100 kHz, es posible que necesite pull-ups más rígidos para asegurarse de que los bordes estén nítidos.
Otro problema es que el maestro debe NACK el último byte leído esperado, incluso si se trata de datos válidos, ya que muchos esclavos esperan un NACK antes de permitir que se produzca una condición de parada válida. Para sus lecturas de un solo byte, el maestro debe NACK el byte de datos. Para los registros de 16 bits, debe ACK el primer byte y NACK el segundo. He visto bastantes dispositivos esclavos colgar el bus o funcionar mal si la última lectura no es 'terminada' por un NACK.
*i2cConSet = I2CON_SET_STO;
del código en la publicación de la pregunta. Todos esos o algunos de esos cambios recientes en el código hicieron que i2c funcionara ahora. Ahora tengo que analizar qué causó exactamente los problemas al volver a habilitar el código anterior línea por línea.
Transeúnte
Telaraña
Transeúnte
Telaraña
Gustavo Litovsky