Colisión de escritura para múltiples lecturas - PIC24 I2C

0

Estoy tratando de sondear un sensor CAP188, así que le estoy enviando comandos de lectura en un bucle de tiempo, pero la primera lectura funciona y luego en la segunda lectura cuando envío la dirección del esclavo, detecta una colisión de escritura.

Para probar mi código, estoy intentando leer la ID del producto, que es un valor conocido. Cualquier ayuda sería apreciada, gracias!

void chipWrite(unsigned char reg, unsigned char data){
//Start bit
I2C2CONbits.SEN = 1;
while(I2C2CONbits.SEN);
IFS3bits.MI2C2IF = 0;

//Slave address bit
I2C2TRN = 0b01010000;
while(!IFS3bits.MI2C2IF);
IFS3bits.MI2C2IF = 0;

//Register address
I2C2TRN = reg;
while(!IFS3bits.MI2C2IF);
IFS3bits.MI2C2IF = 0;

//Data
I2C2TRN = data;
while(!IFS3bits.MI2C2IF);
IFS3bits.MI2C2IF = 0;

//Stop bit
I2C2CONbits.PEN = 1;
IFS3bits.MI2C2IF = 0;
while(I2C2CONbits.PEN);
}

void initChip(){
CLKDIVbits.RCDIV = 0;
AD1PCFG = 0x9FFC;
I2C2CON = 0;
TRISBbits.TRISB3 = 0;
TRISBbits.TRISB2 = 0;
I2C2CONbits.ACKDT = 1;
I2C2BRG = 157;
I2C2CONbits.I2CEN = 1;
_MI2C2IF = 0;
}

 unsigned char chipRead(unsigned char reg){   
unsigned char msb = 0;
while(!I2C2STATbits.P);

 /*start*/   
I2C2CONbits.SEN = 1;   
while(I2C2CONbits.SEN);

/*sensor address*/   
I2C2TRN = 0b01010000; 
while(I2C2STATbits.TBF);   
while(I2C2STATbits.TRSTAT);
while(I2C2STATbits.ACKSTAT);

 /*Register for reading*/   
I2C2TRN = reg;
while(I2C2STATbits.TBF);  
while(I2C2STATbits.TRSTAT);   
while(I2C2STATbits.ACKSTAT);

 /*repeated start*/   
I2C2CONbits.RSEN = 1;   
while(I2C2CONbits.RSEN);

/*Slave address with read = 1*/
I2C2TRN = 0b01010001;       
while(I2C2STATbits.TBF); 
while(I2C2STATbits.TRSTAT);
while(I2C2STATbits.ACKSTAT);

 /*receiver enabled*/   
I2C2CONbits.RCEN = 1;

/*read first byte data*/   
//while(!I2C2STATbits.RBF);   
while(I2C2CONbits.RCEN);
msb = I2C2RCV;

/*send nack*/   
I2C2CONbits.ACKEN = 1;
while(I2C1CONbits.ACKEN);

/*send stop*/   
I2C2CONbits.PEN = 1;   
while(I2C2CONbits.PEN);

return msb; 
}


int main(void) {
initChip();
char key = 0b00000000;
chipWrite(0x72,0xFF);
chipWrite(0x2B, 0x80);
chipWrite(0x26, 0xFF);

while(1){
    key = chipRead(0xFD);
    asm("nop");
    if(key == 0b01010000){
        asm("nop");
    }
    else{
        asm("nop");
    }
    key = 0x00;
}


return 0;
}
    
pregunta vazqu133

1 respuesta

1

No puedo encontrar ninguna hoja de datos del sensor CAP188 en línea, por lo que no puedo verificar esa reclamación.

Algunos sensores iniciarán la medición en su dirección de llamada, y necesitan algo de tiempo para hacerlo.

Es bastante común que mantengan la línea I2C baja durante ese tiempo, hasta que la medición esté lista para ser leída. Algunos chips pueden serializar la medición durante su medición, por lo que la primera lectura podría funcionar pero no la segunda.

Después de enviar tu primera dirección, haz un tiempo (_RBx! = 1); (rb es tu I2C SDA o prueba también la línea SCL) para esperar a que el chip libere la línea antes de la próxima escritura.

Otras razones pueden ser: - La velocidad de I2C es demasiado rápida para el chip. - El retraso I2C entre dos escrituras es demasiado corto.

    
respondido por el Damien

Lea otras preguntas en las etiquetas