¿Qué sucede si omito las resistencias pullup en las líneas I2C?

Recién ahora me di cuenta de que las líneas de reloj y de datos I 2 C (SDA y SCL) deben tener resistencias pullup.

Bueno, construí un par de relojes usando el RTC DS1307 (ver hoja de datos ) de acuerdo con el esquema a continuación. Tenga en cuenta que he omitido ambas resistencias pullup.

Esquema de mi reloj sin resistencias pullup en líneas I2C

Ambos relojes funcionan bien, uno de ellos funciona desde hace más de 3 meses. ¿Cómo es eso posible? En cualquier caso, quería saber:

  1. ¿Qué sucede cuando se omiten los pull-ups I 2 C?

  2. ¿Es probable que la falta de pullups dañe alguno de esos dos circuitos integrados en mi placa?

Busco respuestas que aborden mi caso específico de conectar ATmega328P a un RTC DS1307 como en los esquemas que proporcioné, pero si la pregunta no es demasiado amplia, sería útil saber qué sucede cuando se omiten los pullups en general. , es decir, en otros escenarios de operación I 2 C.

PD. Busqué en Internet para encontrar la respuesta, pero solo pude encontrar artículos sobre cómo dimensionar los pullups.

Actualización: estoy usando Arduino IDE 1.03 y mi firmware maneja el RTC usando la biblioteca Arduino DS1307RTC (a través de sus funciones RTC.read()y RTC.write()). Esa lib a su vez se usa Wire.hpara hablar con el RTC.

Actualización 2: a continuación se muestra una serie de fotografías de alcance que tomé para ayudar a explicar cómo funciona el I 2 C sin los pullups externos.

Tiro de alcance 1 Tiro de alcance 2

Actualización 3 (después de agregar I 2 C pullups): a continuación se muestra otra serie de tomas de alcance que tomé después de agregar resistencias pullup adecuadas (4K7) a las líneas I 2 C (en la misma placa). Los tiempos de subida se redujeron de aproximadamente 5 µs a 290 ns. I 2 C es mucho más feliz ahora.

Tiro de alcance 3 Tiro de alcance 4

¿Tu código deshabilita los pullups en esos pines?
@IgnacioVazquez-Abrams No hay una mención directa a los pines SDA y SCD (18 y 19) en mi código. Manejo el RTC usando el DS1307RTC lib Arduino lib y sus funciones RTC.read() y RTC.write().
Esa biblioteca, a su vez, usa Wire.h para hablar con el RTC.
Sí, definitivamente usando dominadas internas. Tenga en cuenta las curvas en lugar de los bordes afilados.

Respuestas (7)

1) ¿Qué sucede cuando se omiten los pullups I2C?

No habrá comunicación en el bus I 2 C. En absoluto. La MCU no podrá generar la condición de inicio I 2 C. La MCU no podrá transmitir la dirección I 2 C.

¿Se pregunta por qué funcionó durante 3 meses? sigue leyendo

2) ¿Es probable que la falta de pullups dañe alguno de esos dos circuitos integrados en mi placa?

Probablemente no. En este caso particular (MCU, RTC, nada más), definitivamente no.

3) ¿Por qué la MCU pudo comunicarse con el dispositivo esclavo I 2 C en primer lugar? I 2 C requiere resistencias pull-up. Pero no estaban incluidos en el esquema.

Probablemente, tenga habilitados los pull-ups internos en el ATmega. Por lo que he leído 1 , ATmega tiene pull-ups internos de 20kΩ, que se pueden habilitar o deshabilitar desde el firmware. 20kΩ es demasiado débil para el pull-up I 2 C. Pero si el bus tiene una capacitancia baja (físicamente pequeña) y la comunicación es lo suficientemente lenta, entonces 20 kΩ aún pueden hacer que el bus funcione. Sin embargo, este no es un buen diseño confiable, en comparación con el uso de resistencias pull-up discretas.

1 No soy un chico de ATmega.

actualización: En respuesta, las formas de onda I 2 C, que se agregaron al OP
Las formas de onda en el OP tienen una constante de tiempo de subida muy larga. Así es como se ven normalmente las formas de onda I 2 C

ingrese la descripción de la imagen aquí

PIC18F4550, Vcc=+5 V, 2,2 kΩ pull ups. La forma de onda muestra SCL. El tiempo de subida en SDA es casi el mismo. El tamaño físico del bus es moderado: 2 dispositivos esclavos, longitud de PCB ≈100 mm.

¡Gracias por tu respuesta! Sí, el ATmega tiene pullups que deben estar habilitados en mi caso. Verificaré dos veces el código y las bibliotecas que estoy usando y también pasaré la placa por el visor. Espero que eso aclare un poco las cosas.
Es posible que desee verificar primero con la hoja de datos de su dispositivo esclavo. Si no recuerdo mal, los pullups en los ATMega pueden estar entre 30k y 60k (depende del Vcc, la temperatura y una serie de otros factores; realmente no puede depender de ellos para una resistencia confiable). Debe asegurarse de enviar suficiente corriente al esclavo para garantizar una lógica adecuada. 1. Si la resistencia es demasiado grande, su dispositivo esclavo no recibirá suficiente corriente y estará en el mismo lugar en el que se encuentra. ahora.
Recientemente usé I2C para un acelerómetro (Invensense MPU-6050) y los pull-ups recomendados fueron menos de 30k si no recuerdo mal. Afortunadamente, la placa de conexión que utilicé los tenía integrados, así que no tuve que preocuparme por eso. Por $7, no puedes vencer a este pequeño; Sparkfun quiere $40 por el mismo chip y el tablero no tiene nada más. Este tiene pull-ups y reguladores de 3.3V por lo que puedo conectarlo con dispositivos de 5V. amazon.com/…
@audi Fanatic +1. Por cierto, en mi opinión, incluir resistencias pull-up en las placas de conexión e instalarlas de forma predeterminada es un error. Imagine lo que sucede si alguien tiene varias placas de conexión en un bus I2C. Cada pull-up suele ser de 2,2 kΩ más o menos. Las resistencias pull-up en todas las placas de conexión aparecen en paralelo. El pull-up combinado se vuelve demasiado rígido para I2C. [Más sobre este problema potencial aquí y aquí .]
Cierto, nunca lo había pensado de esa manera. Realmente no me molesté con eso porque solo tengo una cosa en el autobús. aunque es bueno saberlo para el futuro
Solo para que sepa que he agregado algunas tomas de alcance para ayudar a aclarar qué está pasando con mi configuración.
@Ricardo Ese no es un bus I2C feliz en sus tomas de alcance [primer conjunto de tomas de alcance en el OP]. También agregué un tiro de alcance a mi respuesta.
Este artículo tiene algunas formas de onda de señales i2c buenas y malas: dsscircuits.com/index.php/articles/…
@nick no es un error. Una característica. Es más fácil deshabilitar los pull-ups adicionales que agregarlos a un módulo.
@Passerby No es una característica. Una falla. Un defecto. No todo el mundo es consciente de que demasiadas dominadas en paralelo causarán un problema. (Por ejemplo, audiFanatic no lo sabía. Este problema de los pull-ups en varias placas base ha surgido antes en EE.SE). La única forma honesta de convertirlo en una función es dejar almohadillas para los pull-ups en el placa de conexiones despoblada, incluya resistencias pull-up por separado en el kit, agregue un párrafo al manual y el esquema de la placa.
@Passerby ¿Por qué Sparkfun y demás lo hacen de la forma en que lo hacen? Quieren una experiencia sencilla e inmediata. Muchos de sus clientes usan solo una placa de conexión, por lo que no se encuentran con el problema de los pull-ups paralelos en varias placas de conexión. Pero cuando se topan con él, pueden estar completamente desconcertados: " cada tablero pequeño funciona bien por separado, pero no funcionan juntos. wtf ". Muchos usuarios de tableros emergentes son nuevos en el I2C. El propósito de las resistencias pull-up es una novedad para ellos. Todavía no han leído la especificación I2C. Sin ofender.
@ford El enlace que analiza las señales I2C buenas y malas es excelente. También aborda cómo seleccionar buenos valores de resistencia pull-up de acuerdo con nuestro propio diseño particular (cantidad de dispositivos conectados y sus capacitancias). ¡¡Gracias!!
@audiFanatic: tres factores impiden el uso con pull-ups muy débiles: (1) si un dispositivo pierde corriente de entrada a tierra, es posible que un pullup demasiado débil no pueda elevar una señal en absoluto; (2) Las entradas con pull-ups más débiles serán más susceptibles al ruido que aquellas con más fuertes; (3) Los pull-ups más débiles no generarán entradas tan rápido como los más fuertes. Operar un bus I2C a 400 kbps requerirá pull-ups bastante fuertes; operar uno a 1kbps no lo hará. Incluso un pull-up de 100K sería viable en muchos casos si uno operara lo suficientemente lento.

La biblioteca que usa y las bibliotecas de las que depende (Wire) habilitan los pull-ups internos de ATMega. Estos son pull-ups débiles y, en uso normal, complementan cualquier pull-up externo (dos resistencias en paralelo). Debido a la resistencia relativamente alta de 20k a 70k, no causan muchos o ningún problema con los externos en uso.

¿Qué sucede cuando se omiten los pull-ups I2C?

Ahora, sin resistencias externas, los débiles pull-ups internos son lo único que hace que la línea suba. Dependiendo del diseño de su placa, la velocidad de su línea i2c, la frecuencia con la que accede, la interferencia externa, etc., pueden funcionar o no. Tuviste suerte. Tienes dominadas, pero no las que esperabas.

¿Es probable que la falta de pullups dañe alguno de esos dos circuitos integrados en mi placa?

Incluso sin los pull-ups internos, la falta de pull-ups no dañará ninguno de los circuitos integrados. La construcción interna de las líneas SCl y SDA del dispositivo i2c es como transistores NPN. Son colectores abiertos , esencialmente diodos controlados/conmutados por corriente.

Sin embargo, lo último que debe tener en cuenta es que tener los pull-ups internos activados, cuando su ATMega está a 5v, y el dispositivo i2c es un dispositivo de solo 3.3v, puede causar problemas. O si tiene activados los pull-ups internos y las resistencias externas conectadas a 3.3v u otro voltaje, también pueden causar problemas. Esencialmente, es un error ignorado intencionalmente en la biblioteca Wire.

+1 - You do have pull-ups, just not ones you expected.- Supongo que lo lograste. ¡Gracias!
Solo para que sepa que he agregado algunas tomas de alcance para ayudar a aclarar qué está pasando con mi configuración.
@Ricardo sí, viendo esos, a 33khz. Un tercio de la velocidad más baja especificada por i2c y la señal sigue siendo muy mala. A 100 khz o 400 khz, no tendría una comunicación que funcionara. Sin embargo, lo mejor es que muchos dispositivos i2c funcionan a una fracción de las velocidades máximas. Solo recuerde, los pullups internos pueden ser de hasta 70k ohm, una resistencia i2c típica es de 4.7k

Por lo general, necesitará tener las resistencias pullup para un circuito de interfaz I 2 C. Si la interfaz es realmente una especificación I 2 C completa en ambos extremos de los cables, entonces las líneas de señal sin las resistencias nunca podrán llegar al nivel alto. Pueden permanecer bajos o ir a algún nivel intermedio determinado por la corriente de fuga en las partes de cada extremo. La razón de esto es que el verdadero I 2 C es un bus de drenaje abierto.

Algunos dispositivos pueden tener resistencias pullup en el chip en el rango de 20K a 100K ohmios solo para mantener los pines de la interfaz en un nivel inactivo alto cuando la interfaz I 2 C de la pieza no está en uso. Para interfaces simples y cortas, estas resistencias pullup pueden ser suficientes para proporcionar la corriente necesaria para elevar las líneas mientras se señalan los relojes y/o los datos.

Es difícil saberlo a partir de su esquema, pero en algunos casos, las interfaces I 2 C se implementan utilizando pines de puerto de E / S de uso general y luego se golpean en el software. A veces, es posible que el implementador no opere los pines de E/S en esta configuración usando una metodología de drenaje abierto y esto puede influir en por qué una interfaz sin resistencias pullup parece funcionar.

Al final del día, probablemente se deba verificar la señalización en uno de sus relojes anteriores usando un osciloscopio para ver si los 1 y 0 en la interfaz funcionan dentro de los niveles de voltaje especificados. Entonces sabrás con certeza si tuviste mucha suerte con esa implementación o si uno de los factores que mencioné anteriormente está en juego.

¿Qué sucede cuando se omiten los pull-ups I2C?

Lo más probable es que el bus I2C simplemente no funcione.

¿Es probable que la falta de pullups dañe alguno de esos dos circuitos integrados en mi placa?

Probablemente no.

Sus líneas I2C no funcionarán en absoluto. Si no me equivoco, I2C solo afirma señales bajas, pero no las devuelve a un estado alto, por lo que necesita esas resistencias.

Cualquier falta de pull-ups no debería dañar ningún IC.

Los pines I2C son de drenaje abierto.

I2C es un protocolo lógico TTL; por lo que sus datos y líneas de reloj son de drenaje abierto. En otras palabras, el hardware I2C solo puede reducir estas líneas; se dejan flotando cuando no es un cero. Ahí es donde entran las resistencias pull-up. Este es un diagrama simplificado, pero trabaje conmigo por un segundo.

esquemático

simular este circuito : esquema creado con CircuitLab


Como puedes ver; la resistencia pull-up es necesaria para garantizar que se vea un 1 lógico en la salida cuando la lógica TTL no está bajando la salida. La lógica TTL no puede impulsar las líneas altas como ya mencioné. Si esto no estuviera presente, la salida quedaría flotando y es impredecible lo que puede ver en la salida (por lo que sabe, su microondas o las disfunciones intestinales de sus compañeros de trabajo causadas por cierto osito de goma sin azúcar podrían causar el valor a fluctuar).

Ahora, si tuviera que implementar I2C en el software con un microcontrolador, esto probablemente no sería un gran problema, ya que lo más probable es que use la lógica CMOS, que puede impulsar salidas tanto altas como bajas.

Me alegro de que haya ayudado.
No importa si los dispositivos usan lógica TTL o CMOS: las salidas TTL normal y CMOS normal subirán y bajarán la señal. Las señales I2C son TTL de colector abierto o (más probablemente) CMOS de drenaje abierto; en ambos casos, el transistor que elevaría la señal falta en la etapa de salida de la fuente, por lo que se requieren resistencias pull-up para tirar de las señales de alta. Es posible que el microcontrolador tenga pull-ups internos en esas pintas.
-1 Como dijo Peter Bennett, gran parte de esta respuesta es simplemente incorrecta. Llamar a las señales TTL "de drenaje abierto" es el regalo.
Tenga en cuenta que hay ventajas al hacer I2C con TTL, a saber, que a menudo no necesita traductores de nivel para manejar componentes con diferentes voltajes de suministro conectados al mismo bus. Basta con configurar el voltaje pullup al voltaje de entrada de aceptación más alto del chip de voltaje más bajo muchas veces suficiente con las etapas de entrada TTL. En CMOS, eso no funcionaría.
@BenVoigt: No, llamar a la configuración "requiere una resistencia pull-up" "TTL" es incorrecto, ya que este arreglo se puede hacer con CMOS o TTL, y el DS1307 es una parte de CMOS. La hoja de datos de Maxim establece claramente que las salidas son de drenaje abierto y el diagrama de bloques muestra un FET para una salida.
@Peter Estoy completamente de acuerdo. Mis comentarios se refieren a lo que realmente es TTL, no a la versión confusa en esta respuesta. Dijiste que TTL vs CMOS no importa, pero aunque el umbral de entrada solo está relacionado tangencialmente con pullups débiles, termina siendo importante en circuitos individuales.

Cuando golpeé I2C con un micro como el maestro que suministra el reloj, pude conducir el SCL sin pullup.

Sin embargo, SDA necesita estar OC con pullup para que el dispositivo esclavo pueda desplegarse y responder correctamente.

Saludos