ruidos en el BUS I2C

0

Estoy usando stm32f407 y LM75 con la comunicación serial del bus I2C. En este código, estoy usando muchas interrupciones y, etc. A veces, I2C puede dar un error. Puedo aceptar esto pero me siento incómodo con las señales. Solo hay LM75 IC en la línea de autobús y Rp es 4.7K ohm.

A veces, el bus I2C da un error BERR o el estado I2C está ocupado o la línea del bus i2c permanece a cero voltios.

¿Cómo puedo arreglar la señal? ¿O es normal?

He probado condensadores de 10pf entre tierra y scl y entre tierra y sda. Pero las señales son las mismas.

Hay vistas de osciloscopio debajo

Foto 1: Diagrama de I2CBUS

Foto2: 1MHZ de velocidad I2CBUS

Foto3: 100KHZ de velocidad I2CBUS

Foto4: velocidad de 400KHZ I2CBUS

Photo5: PROPS

Foto6: RUTAS I2C

Foto7: Ruidos de tierra y suministro (Canal 1: Tierra de MCU, Canal 2: Suministro de MCU)

    
pregunta O.Blue

3 respuestas

2

Supongo que el zumbido en el borde descendente es un artefacto de medición (los cables del clip de cocodrilo negro que vienen con sondas de alcance son MALOS), pero aparte de eso:

1MHz es muy, muy rápido para I2C, especialmente con ese valor relativamente alto de recuperación. ¿Está seguro de que sus dispositivos esclavos I2C (todos ellos, no solo el que está tratando de solucionar) son capaces de cumplir con el cronograma a esa velocidad?

Tu forma de onda de 100 kHz me parece bien, y tu de 400 kHz no es horrible (pero podría reducir las resistencias de pull up a 2,2 k más o menos).

Me gustaría secundar la nota de que el LM75 está un poco satisfecho con el bloqueo, y observaría que un reinicio del bus como el que se muestra en otra parte es una buena idea en el momento del arranque, ya que de lo contrario puede terminar con la máquina de estado periférica del bus Coincidiendo con la idea de los procesadores del estado del bus, muy molesto al intentar usar un depurador.

Mi respuesta instintiva a I2C es que con mucho gusto haré el enrutamiento adicional para usar SPI. Si tengo alguna opción, mucho menos molesto desde una perspectiva de software (también una perspectiva de ruido e inmunidad).

Habiendo visto las fotos adicionales, el zumbido en el borde descendente es casi seguro que se debe a la longitud del cable de fondo del alcance y no está realmente presente, y las formas de onda están bien a 100k, y en su mayoría a 400k (2.2k los pull ups harán que ambos estén bien), sus problemas restantes probablemente sean de software.

    
respondido por el Dan Mills
3

Hay 2 problemas diferentes:
1. ruido
2. Usted está recibiendo errores en la comunicación

Intento responder la segunda:
Intente usar resistencias con valores más bajos, como 2.2k en lugar de 4.7k. No utilice condensadores para líneas SDA o SCL. Utilice una frecuencia I2C inferior a 1MHz, probablemente esté recibiendo errores no debido al ruido, sino a una frecuencia demasiado alta (según la primera foto, el flanco ascendente es demasiado lento para usar 1MHz).

El ruido puede ser causado por muchas cosas. Probablemente cables largos (inductancia parásita), puesta a tierra no muy buena, etc.

    
respondido por el Chupacabras
3

Muestras tres frecuencias de reloj SCL diferentes en tus tomas de alcance. En dos de los disparos, el ciclo de trabajo de SCL no es el 50% como debería ser. En los casos en que el SCL no tiene un ciclo de trabajo del 50%, el tiempo de aumento lento es un problema real. El LM75 es un dispositivo de 100 KHz, por lo que el reloj SCL a la hora del reloj no debe ser más de 10useg. El tiempo bajo de SCL debe estar cerca de 5usegundos y el tiempo alto debe ser lo más cercano a 5usegs posible reduciendo el valor de sus resistores pullup como otros ya lo han recomendado.

El sensor de temperatura LM75 es notoriamente susceptible de quedar bloqueado cuando hay violaciones de protocolo en la interfaz I2C, lo que en su caso es más probable debido a un ciclo de trabajo deficiente del reloj o una frecuencia de reloj demasiado alta.

Si pretende permanecer con el LM75, es esencial que implemente una rutina de recuperación de bus I2C que ejecute al inicio o cuando vea que el bus I2C está generando errores debido a que está bloqueado. Aquí hay una muestra de rutina de recuperación I2C que uso en mi código. (Esto está codificado para PIC-32, por lo que tendrá que traducir el concepto a su entorno y conjunto de herramientas MCU).

//
//
// function to temporarily disable the I2C port and the run sequence to 
// unstuck any slave devices that may be hung in read mode waiting for an
// ACK to come. this recovery sequence consists of a start, >9 clocks and a 
// stop. This is followed again with another start/stop sequence that permits
// state machine logic reset in most slave peripheral chips
//

void i2c_recovery(void)
{
    uint32_t loop;

    // Disable I2C0 controller to free the I/O pins
    PLIB_I2C_Disable(I2C_ID_2);
    i2c_dly();

    i2c_start();
    // let SDA be able to go high
    PLIB_PORTS_PinDirectionInputSet(PORTS_ID_0, PORT_CHANNEL_A, PORTS_BIT_POS_3);   // set SDA2 hig-z (input mode)
    i2c_dly();

    // loop to make at least 9 clocks
    for (loop = 0; loop < 9; loop++)
    {
        // let SCL go high by pullup
        PLIB_PORTS_PinDirectionInputSet(PORTS_ID_0, PORT_CHANNEL_A, PORTS_BIT_POS_2);   // set SCL2 hig-z (input mode)
        i2c_dly();
        // pull SCL back low
        PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_A, PORTS_BIT_POS_2);               // set SCL2 low output
        PLIB_PORTS_PinDirectionOutputSet(PORTS_ID_0, PORT_CHANNEL_A, PORTS_BIT_POS_2);  // set SCL2 low-z output driver
        i2c_dly();
    }
    i2c_stop();

    // run a start stop sequence. this performs a state machine reset
    // in most slave i2c devices
    i2c_start();
    i2c_stop();
    i2c_dly();

    // re-enable  I2C0 controller
    PLIB_I2C_Enable(I2C_ID_2);
}
    
respondido por el Michael Karas

Lea otras preguntas en las etiquetas