Hola!, tal vez me expresé mal... No son 10useg entre cada línea de código, sino entre cada fase de la comunicación
La secuencia para leer un registro es así:
-Aseguro que el bus está libre
-Envío Start y espero que termine
-Retardo
-Envío 0x42 al bus y espero que se complete el envío
-Espero ACK de cámara
-Retardo
-Envío dirección de registro a leer y espero que se complete el envío.
-Espero ACK de cámara
-Retardo
-Envío Stop
;Hasta aquí enviamos dos palabras a la cámara: dirección en bus y dirección de registro en cámara
;Ahora abrimos de nuevo el bus y nos preparamos para recibir su respuesta.
-Me aseguro que el bus está libre.
-Envío Start y espero que termine.
-Envío 0x43 y espero que se complete el envío.
-Espero ACK de cámara.
-Retardo
-Cambio dirección de bus para permitirle enviar información a la cámara.
-Espero que se complete el envío desde cámara.
-Retardo.
-Leo dato y lo guardo en alguna variable.
-Envío NACK y espero que se complete el envío.
-Retardo.
-Envío Stop.
-Retardo
Primero intenté sin retardos, y me leía mal, luego de agregarlos, me quedó funcionando perfecto.
Te paso mi código en C30 para un dsPIC. Es una función sencilla que le mandas una dirección de registro de la cámara y devuelve el valor guardado en él. Tal vez puedas sacarle algo:
unsigned char LeerOV7670(unsigned char direccion){
unsigned char dato = 0;
while(I2C1CONbits.SEN || I2C1CONbits.RSEN || I2C1CONbits.PEN ||
I2C1CONbits.RCEN || I2C1CONbits.ACKEN);//Aseguro que el bus está ocioso.
I2C1CONbits.SEN=1; //Inicio secuencia de start.
while(I2C1CONbits.SEN); //Espero aquí hasta que finalice secuencia de start.
__delay_us(DELAY_US);
I2C1TRN = WriteAddressOV7670; //Cargo dato a enviar en buffer.
while(I2C1STATbits.TBF); //Espero aquí hasta que se completa envío de byte.
while(!IFS1bits.MI2C1IF); //Espero interrupción por sucesión de noveno bit.
IFS1bits.MI2C1IF = 0; //Limpio bandera de inetrrupción.
while(I2C1STATbits.ACKSTAT); //Espero aquí hasta que recibo confirmación de recepción.
__delay_us(DELAY_US);
I2C1TRN = direccion; //Cargo dato a enviar en buffer.
while(I2C1STATbits.TBF); //Espero aquí hasta que se completa envío de byte.
while(!IFS1bits.MI2C1IF); //Espero interrupción por sucesión de noveno bit.
IFS1bits.MI2C1IF = 0; //Limpio bandera de inetrrupción.
while(I2C1STATbits.ACKSTAT); //Espero aquí hasta que recibo confirmación de recepción.
__delay_us(DELAY_US);
while(I2C1CONbits.SEN || I2C1CONbits.RSEN || I2C1CONbits.PEN ||
I2C1CONbits.RCEN || I2C1CONbits.ACKEN);//Aseguro que el bus está ocioso.
I2C1CONbits.PEN =1; //Inicio secuencia de STOP.
while(I2C1CONbits.PEN); //Espero aquí hasta que finalice secuencia STOP.
__delay_us(DELAY_US);
while(I2C1CONbits.SEN || I2C1CONbits.RSEN || I2C1CONbits.PEN ||
I2C1CONbits.RCEN || I2C1CONbits.ACKEN);//Aseguro que el bus está ocioso.
I2C1CONbits.SEN=1; //Inicio secuencia de start.
while(I2C1CONbits.SEN); //Espero aquí hasta que finalice secuencia de start.
__delay_us(DELAY_US);
I2C1TRN = ReadAddressOV7670; //Cargo dato a enviar en buffer.
while(I2C1STATbits.TBF); //Espero aquí hasta que se completa envío de byte.
while(!IFS1bits.MI2C1IF); //Espero interrupción por sucesión de noveno bit.
IFS1bits.MI2C1IF = 0; //Limpio bandera de inetrrupción.
while(I2C1STATbits.ACKSTAT); //Espero aquí hasta que recibo confirmación de recepción.
__delay_us(DELAY_US);
while(I2C1CONbits.SEN || I2C1CONbits.RSEN || I2C1CONbits.PEN ||
I2C1CONbits.RCEN || I2C1CONbits.ACKEN);//Aseguro que el bus está ocioso.
I2C1CONbits.RCEN = 1; //Cambio dirección de bus.
while(I2C1CONbits.RCEN); //Espero aquí hasta que se completa envío de byte (8 bits).
__delay_us(DELAY_US);
dato = I2C1RCV; //Leo dato.
I2C1CONbits.ACKDT=1; //Prepara para enviar NACK
while(I2C1CONbits.SEN || I2C1CONbits.RSEN || I2C1CONbits.PEN ||
I2C1CONbits.RCEN || I2C1CONbits.ACKEN);//Aseguro que el bus está ocioso.
I2C1CONbits.ACKEN=1; //Envío NACK
while(I2C1CONbits.ACKEN); //Espero aquí hasta que finalice secuencia NACK.
I2C1CONbits.ACKDT=0; //Reestablezco ACK.
__delay_us(DELAY_US);
while(I2C1CONbits.SEN || I2C1CONbits.RSEN || I2C1CONbits.PEN ||
I2C1CONbits.RCEN || I2C1CONbits.ACKEN);//Aseguro que el bus está ocioso.
I2C1CONbits.PEN =1; //Inicio secuencia de STOP.
while(I2C1CONbits.PEN); //Espero aquí hasta que finalice secuencia STOP.
__delay_us(DELAY_US);
return dato;
}
Saludos.
Luis.