los esclavos interfieren al compartir la línea de bus i2c

2

Soy muy nuevo con los microcontroladores, y estoy usando PIC18F4620 (maestro) para comunicarme con el sensor de color TCS34725 (esclavo) y el reloj en tiempo real DS1307 (esclavo, a bordo) a través de I2C. En este momento, estoy experimentando algún tipo de interferencia entre esos dos. Si ejecuto cualquiera de ellos individualmente sin el otro conectado al puerto, entonces funciona bien. Si el otro está conectado sin siquiera estar iniciado, entonces se bloquea durante el proceso de lectura. Sus direcciones de esclavos no son las mismas, así que no veo por qué sucede esto. Este es el código para el sensor de color

 /* Initialize LCD. */
initLCD();

I2C_Master_Init(100000); //Initialize I2C Master with 100 kHz clock

while(1){
    /*read the id */
    I2C_Master_Start();
    I2C_Master_Write(0b01010010);
    I2C_Master_Write(0b10010010);
    I2C_Master_RepeatedStart();
    I2C_Master_Write(0b01010011);
    id = I2C_Master_Read(NACK);
    I2C_Master_Stop();   
    __delay_ms(200);

    /* Configure the RGBC Time register */
    I2C_Master_Start();
    I2C_Master_Write(0b01010010);
    I2C_Master_Write(0b10000001);
    I2C_Master_Write(0);
    I2C_Master_Stop();
    __delay_ms(200);

    /* Configure the Control register */
    I2C_Master_Start();
    I2C_Master_Write(0b01010010);
    I2C_Master_Write(0b10001111);
    I2C_Master_Write(0);
    I2C_Master_Stop();
    __delay_ms(200);

    /* Configure the Control register */
    I2C_Master_Start();
    I2C_Master_Write(0b01010010);
    I2C_Master_Write(0b10000000);
    I2C_Master_Write(0b00001011);
    I2C_Master_Stop();
    __delay_ms(200);

    /* Read red data */
    I2C_Master_Start();
    I2C_Master_Write(0b01010010);
    I2C_Master_Write(0b10010110);
    I2C_Master_RepeatedStart();
    I2C_Master_Write(0b01010011);
    tmp[0] = I2C_Master_Read(ACK);
    tmp[1]= I2C_Master_Read(NACK);
    I2C_Master_Stop();
    __delay_ms(1000);
    rC = (tmp[0])|(tmp[1]<<8);

    /* Read green data */
    I2C_Master_Start();
    I2C_Master_Write(0b01010010);
    I2C_Master_Write(0b10011000);
    I2C_Master_RepeatedStart();
    I2C_Master_Write(0b01010011);
    tmp[0] = I2C_Master_Read(ACK);
    tmp[1]= I2C_Master_Read(NACK);
    I2C_Master_Stop();
    __delay_ms(1000);
    gC = (tmp[0])|(tmp[1]<<8);

    /* Read blue data */
    I2C_Master_Start();
    I2C_Master_Write(0b01010010);
    I2C_Master_Write(0b10011010);
    I2C_Master_RepeatedStart();
    I2C_Master_Write(0b01010011);
    tmp[0] = I2C_Master_Read(ACK);
    tmp[1]= I2C_Master_Read(NACK);
    I2C_Master_Stop();
    __delay_ms(1000);
    bC = (tmp[0])|(tmp[1]<<8);

    /* Display data on the LCD */
    __lcd_home();
    __lcd_clear();
    printf("id: %d", id);
    __delay_ms(500);


    __lcd_clear();
    printf("r:%u,b:%u", rC, bC);
    __lcd_newline();
    printf("g:%u", gC);
    __delay_ms(1000);

    id = 0;
    rC = 0;
    bC = 0;
    gC = 0;
}

Este es el código para RTC

void main(void) {
   /* Write outputs to LATx, read inputs from PORTx. Here, all latche (LATx)
    * are being cleared (set low) to ensure a controlled start-up state. */  
    LATA = 0x00;
    LATB = 0x00; 
    LATC = 0x00;
    LATD = 0x00;
    LATE = 0x00;

    /* After the states of LATx are known, the data direction registers, TRISx
     * are configured. 0 --> output; 1 --> input. Default is  1. */
    TRISA = 0xFF; // All inputs (this is the default, but is explicated here for learning purposes)
    TRISB = 0xFF;
    TRISC = 0b10000000; /* RC3 is SCK/SCL (SPI/I2C),
                         * RC4 is SDA (I2C),
                         * RC5 is SDA (SPI),
                         * RC6 and RC7 are UART TX and RX, respectively. */
    TRISD = 0x00; // All output mode on port D for the LCD
    TRISE = 0x00;

    /************************** A/D Converter Module **************************/
    ADCON0 = 0x00;  // Disable ADC
    ADCON1 = 0b00001111; // Set all A/D ports to digital (pg. 222)

    /* Initialize LCD. */
    initLCD();

    I2C_Master_Init(100000); //Initialize I2C Master with 100 kHz clock
    /* Set the time in the RTC.
     * 
     * To see the RTC keep time, comment this line out after programming the PIC
     * directly before with this line included. */

    RTC_setTime();

    /* Declare local variables. */
    unsigned char time[7]; // Create a byte array to hold time read from RTC
    unsigned char i; // Loop counter

    /* Main loop. */
    while(1){
        /* Reset RTC memory pointer. */
        I2C_Master_Start(); // Start condition
        I2C_Master_Write(0b11010000); // 7 bit RTC address + Write
        I2C_Master_Write(0x00); // Set memory pointer to seconds
        I2C_Master_RepeatedStart(); // Start condition
        I2C_Master_Write(0b11010001); // 7 bit RTC address + Read
        for(i = 0; i < 6; i++){
            time[i] = I2C_Master_Read(ACK); // Read with ACK to continue reading
        }
        time[6] = I2C_Master_Read(NACK); // Final Read with NACK
        I2C_Master_Stop(); // Stop condition

        /* Print received data to LCD. */
        __lcd_home();
        printf("%02x/%02x/%02x", time[6],time[5],time[4]); // Print date in YY/MM/DD
        __lcd_newline();
        printf("%02x:%02x:%02x", time[2],time[1],time[0]); // HH:MM:SS
        __delay_ms(1000);
    }
}

void RTC_setTime(void){
    /* Writes the happynewyear array to the RTC memory.*/

    I2C_Master_Start();           // Start condition
    I2C_Master_Write(0b11010000); //7 bit RTC address + Write
    I2C_Master_Write(0x00);       // Set memory pointer to seconds

    /* Write array. */
    for(char i=0; i<7; i++){
        I2C_Master_Write(happynewyear[i]);
    }

    I2C_Master_Stop();            //Stop condition
}
    
pregunta sophattack

1 respuesta

1

No miré el código porque, por un lado, es un montón de llamadas de alto nivel sin mostrar lo que realmente sucede a nivel de bus.

Sin embargo, este es probablemente un problema eléctrico. Posiblemente los segundos esclavos cargan las líneas de autobús para que algo no funcione. No has dicho nada acerca de la tasa de bits o de las flexiones. Lo que importa Tal vez los pullups tengan una impedancia demasiado alta y / o esté intentando utilizar una velocidad de bits demasiado rápida. Mire las líneas con un alcance y vea lo que realmente está sucediendo. Asegúrese de que cuando cada línea esté alta, de que llegue allí dentro de poco tiempo.

    
respondido por el Olin Lathrop

Lea otras preguntas en las etiquetas