¿Cómo resolver los conflictos de direcciones I2C?

Quiero conectar varios dispositivos esclavos I2C a un microcontrolador, todos en el mismo conjunto de pines, pero todos los dispositivos I2C comparten la misma dirección. Las direcciones están fijadas en el hardware.

¿Hay alguna forma de conectar varios dispositivos con la misma dirección?

Tal vez algún tipo de módulo de traducción de direcciones I2C con cada dispositivo con una dirección configurable para que pueda asignar mis propias direcciones a cada uno.

Respuestas (8)

No hay nada integrado en I2C para hacer esto, normalmente los dispositivos esclavos tendrán algunos pines externos que se pueden configurar en 0 o 1 para alternar un par de bits de dirección para evitar este problema. Alternativamente, he tratado con algunos fabricantes que tienen 4 o 5 números de parte para una parte, la única diferencia es su dirección I2C.

La mayoría de los dispositivos tienen hardware específico que maneja la comunicación I2C, es decir, el ACK esclavo está en el hardware, por lo que realmente no puede piratearlo.

En cuanto al módulo de traducción, puede comprar algunos PIC de $ 0.50 con 2 buses I2C y escribir un código rápido para que actúen como traductores de direcciones, supongo.

Gracias. Sí, estos dispositivos tienen una selección de dirección, pero solo entre dos direcciones y quiero conectar más de 5 dispositivos, por lo que todavía terminaría con conflictos. No había pensado en usar un PIC. Eso debería funcionar. ¿No hay nada disponible que haga este tipo de cosas?
NXP fabrica un montón de multiplexores / conmutadores para I2C, es posible que pueda armar algo con ellos: ics.nxp.com/products/i2cmuxes , por ejemplo, podría crear en su caso 3 ramas secundarias, cada una con 2 dispositivos. y use uno de los interruptores de NXP para lograr su objetivo.
Genial, ese es exactamente el tipo de cosa que estaba buscando. Simplemente no sabía el nombre. Gracias.
Esta respuesta tiene 7 años, por lo que creo que podría haber sido la mejor en el momento en que se ofreció. Sin embargo, para otros que están llegando ahora, algunas de las respuestas mucho más nuevas (actualmente clasificadas más bajas en la lista) ofrecen enfoques potencialmente mejores basados ​​en componentes más nuevos que ahora están en el mercado.

Acabo de encontrarme con este problema con varios dispositivos I2C con una dirección fija. Nuestra solución fue usar líneas de E/S en el microcontrolador para forzar las líneas SDA en lo alto de los dispositivos que no queremos abordar, mientras que la línea de E/S para el dispositivo al que nos dirigimos se configura como entrada (alta impedancia). ). Esto significa que solo el dispositivo de destino coincide con su dirección I2C y los demás ignoran los datos posteriores.

Múltiples dispositivos I2C con la misma dirección

Las resistencias en la línea SDA para los dispositivos inactivos terminan actuando como pull-ups para el bus, por lo que el valor exacto dependerá de cuántos dispositivos tenga y qué pull-up necesite para su bus. Entonces, si elige resistencias de 10K, entonces 3 dispositivos inactivos dan un pullup de 3K3.

Los diodos schottky aseguran que el dispositivo aún pueda tirar de la línea SDA lo suficientemente bajo cuando transmite datos al host.

Aprecio que hayas seguido y publicado esto. Esta es una solución bastante ingeniosa, estoy seguro de que será útil para otros.
Un buen nicho que se puede utilizar en algunas aplicaciones. Me gusta mucho.
¿No es esta una solución para el diseño incorrecto de HW? ¿Qué sucede si no tenemos pines IO adicionales de sobra?
Esta es la solución menos costosa. Nuestro producto tiene dos sensores iguales y no tiene presupuesto para ningún IC adicional. Aquí solo agregamos dos diodos y una resistencia. ¡Gracias!

Ahora hay una respuesta: Linear Tech tiene la serie LTC4316/17/18 de traductores de direcciones. Son relativamente nuevos y la disponibilidad es incierta.

Componente muy interesante. La mayoría de los dispositivos I2C tienen 2 direcciones fijas y este LTC4316 podría duplicar potencialmente el direccionamiento a un costo razonable.

Si ninguno de los dispositivos I2C usa la extensión del reloj (apretón de manos), y si está golpeando el maestro I2C, un truco simple es hacer que algunos de los dispositivos intercambien el reloj y los pines de datos. Durante la transmisión de un byte, el dispositivo que tiene el reloj y los pines de datos intercambiados verá cada bit "0" como un no evento (los datos suben y bajan sin reloj) y verá cada bit "1" como una parada I2C y comienzo (el reloj sube mientras los datos están bajos, seguido por el aumento y la caída de los datos, seguido por la caída del reloj). Las condiciones de inicio y detención intencionales para un dispositivo pueden ser vistas como bits de datos por el otro, pero a menos que un dispositivo tenga un número excesivo de condiciones de inicio y detención entre los bits "1", sería poco probable que algún dispositivo "accidentalmente"

No estoy votando negativamente, pero esto me parece un poco arriesgado. Mi experiencia con I2C es que es lo suficientemente propenso al ruido con solo la conexión habitual. Sin embargo, sí usa la palabra "piratear" y menciona la advertencia "si ninguno de los dispositivos i2c usa el estiramiento del reloj", por lo que si puede funcionar para alguien, entonces más poder para ellos.

Varios fabricantes ofrecen circuitos integrados de conmutación y multiplexación de bus I2C.

Un mux puede activar un canal a la vez; un interruptor puede habilitar varios en paralelo.

Compruebe, por ejemplo, las ofertas de NXP , TI y Maxim .

Para la experimentación, Adafruit tiene una placa TCA9548a .

Si tiene 8 chips de destino con direcciones idénticas, seleccione un MUX de 8 a uno. Antes de acceder a cualquiera de los chips de destino, configure el MUX para activar el bus I2C correcto.

Ventajas

  • No requiere programación (frente al enfoque basado en microcontrolador)
  • Puede admitir las funciones y velocidades de I2C que necesita (frente a los muxes de bus analógicos/digitales regulares). Por ejemplo, un MUX normal (no I2C) no pasará direcciones de llamadas generales a todos sus canales.

Tenía dos sensores de luz de color TCS3414 que quería comparar (los paquetes FN y CS, que tienen diferentes filtros). La dirección I2C está cableada. Después de observar cómo funciona I2C en términos de las líneas SCL (reloj) y SDA (datos), parecía que apagar la línea SDA evitaría que el chip obtuviera un bit de inicio o parada y, por lo tanto, lo dejaría inactivo. Así que usé un interruptor analógico CMOS (4066B) para encender o apagar la línea SDA de cada dispositivo. Esto funcionó bien para cambiar entre los dos dispositivos. Sé que es un truco, y el PCA9548 sería mucho mejor, pero no tenía ninguno a mano.

En realidad, esto no es un truco en absoluto, y diría que esta debería ser la respuesta aceptada. He visto este uso en varios productos comerciales, y no puedo pensar en una mejor solución (a menos que no tenga GPIO disponible y, por lo tanto, necesite una solución I2C pura, como los muxes específicos de I2C). Los buenos y viejos muxes analógicos tienen mucho ancho de banda y son increíblemente baratos.

Consideraría usar conmutadores de bus para multiplexar el bus I2C entre los dispositivos con direcciones en conflicto. Los interruptores de bus son de muy baja capacitancia y resistencia y, a diferencia de los controladores/búferes, son verdaderos interruptores que conectan o desconectan dos nodos de circuito.

Los interruptores de bus suelen tener una característica extraña, que no importa para I2C porque utiliza dispositivos de drenaje abierto: un interruptor de bus tiene una resistencia de encendido baja cuando une voltajes cercanos a 0 (Vss), pero la resistencia aumenta drásticamente a medida que se acercan los voltajes. la fuente de alimentación Vdd. (Esto se debe a que básicamente son MOSFET con voltajes de compuerta en la fuente de alimentación cuando se encienden, por lo que a medida que los voltajes conmutados se acercan a Vdd, el Vgs disponible es mucho más bajo)

El enlace está roto. fairchildsemi.com/product-technology/bus-switches funciona mejor.

Use un chip demux simple (por ejemplo, 74HC139 afaik) y conecte el pin I2C CLK a la entrada (ya que el pin I2C CLK es solo de salida). Use pines GPIO para controlar la salida deseada. Luego, el pin de datos I2C se puede compartir entre todos los esclavos.

SCL no es solo de salida. Un esclavo puede estirar el reloj si necesita hacerlo más lento.
Puede usar un multiplexor analógico (que es bidireccional), pero es posible que un decodificador no funcione por el motivo indicado por stevenh. Si usa un multiplexor, necesitará una pulpa débil en el lado esclavo para asegurarse de que se mantenga inactivo. Además, solo cambie la selección del multiplexor cuando el bus esté inactivo.
Si bien no es una solución general, se puede hacer con la mayoría de los circuitos integrados que no usan un microcontrolador interno para la interfaz I2C. Los dispositivos que son seguros de usar generalmente se pueden determinar mirando las descripciones de los pines o el diagrama de bloques en las hojas de datos respectivas. Si SCL está configurado como solo una entrada, esto funcionaría.