¿Cómo resolver los enfrentamientos de direcciones I2C?

39

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 se arreglan en el hardware.

¿Hay alguna forma de conectar múltiples 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.

Simon P Stevens
fuente

Respuestas:

24

No hay nada integrado en I2C para hacer esto, normalmente los dispositivos esclavos tendrán algunos pines externos que se pueden establecer 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 hackearlo.

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

marca
fuente
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 aún terminaría con enfrentamientos. No había pensado en usar un PIC. Eso debería funcionar. ¿No hay nada fuera de la plataforma que haga este tipo de cosas?
Simon P Stevens
11
NXP hace un montón de multiplexores / conmutadores para I2C, es posible que pueda armar algo de ellos: ics.nxp.com/products/i2cmuxes, por ejemplo, podría crear en su caso 3 sub ramas, cada una con 2 dispositivos en él , y use uno de los interruptores de NXP para lograr su objetivo.
Mark
Genial, ese es exactamente el tipo de cosas que estaba buscando. Simplemente no sabía el nombre. Gracias.
Simon P Stevens
Esta respuesta tiene 7 años, así que creo que podría haber sido la mejor en el momento en que se ofreció. Para otros que están llegando ahora, sin embargo, 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.
Brick
6

Acabo de encontrarme con este problema con múltiples dispositivos I2C con una dirección fija. Nuestra solución fue utilizar líneas de E / S en el microcontrolador para forzar las líneas SDA en los dispositivos que no queremos abordar, mientras que la línea de E / S para el dispositivo al que apuntamos 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 cualquier dato posterior.

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 baja cuando se transmiten datos al host.

Peter Gibson
fuente
Le agradezco que haya seguido y publicado esto. Esta es una solución bastante ingeniosa, estoy seguro de que será útil para otros.
Simon P Stevens
Un buen nicho que se puede usar en algunas aplicaciones. Me gusta mucho.
Harry Svensson
5

Si ninguno de los dispositivos I2C usa el estiramiento del reloj (apretón de manos), y si está golpeando el maestro I2C, un simple truco 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 (datos subiendo y bajando sin reloj) y verá cada bit "1" como una parada I2C y comenzar (el reloj sube mientras los datos están bajos, seguido por los datos subiendo y bajando, seguido por el reloj cayendo) Las condiciones de parada e inicio 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 arranque y parada entre "1" bits, sería poco probable que algún dispositivo "accidentalmente"

Super gato
fuente
66
No estoy votando mal, pero esto me parece un poco arriesgado. Mi experiencia con I2C es que es bastante 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.
Jason S
5

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

Los interruptores de bus generalmente tienen una característica extraña, que no importa para I2C porque usa dispositivos de drenaje abierto: un interruptor de bus tiene baja resistencia de conexión cuando se juntan voltajes cercanos a 0 (Vss), pero la resistencia aumenta dramáticamente a medida que se acercan los voltajes la fuente de alimentación Vdd. (Esto se debe a que son básicamente MOSFET con voltajes de puerta en la fuente de alimentación cuando se encienden, por lo que a medida que los voltajes conmutados se acercan a Vdd, los Vgs disponibles son mucho más bajos)

Jason S
fuente
1
El enlace está roto. fairchildsemi.com/product-technology/bus-switches funciona mejor.
florisla
4

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), parece que apagar la línea SDA evitaría que el chip se inicie o pare y, por lo tanto, lo deje 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 uno a mano.

David Hill
fuente
En realidad, esto no es un truco en absoluto, y diría que esta debería ser la respuesta aceptada. He visto esto usado 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 mux analógicos tienen mucho ancho de banda y son muy baratos.
Jay Carlson
4

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

usuario3608541
fuente
Componente muy interesante. La mayoría de los dispositivos I2C tienen 2 direcciones fijas y esto LTC4316 puede duplicar el direccionamiento en un costo razonable.
Mehrad
4

Varios fabricantes ofrecen circuitos integrados multiplex de bus I2C y conmutadores.

Un mux puede activar un canal a la vez; Un interruptor puede habilitar múltiples 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 (vs enfoque basado en microcontrolador)
  • Puede admitir las funciones y velocidades de I2C que necesita (frente a los muxes de bus analógico / digital normales). Por ejemplo, un MUX regular (no I2C) no pasará direcciones de llamadas generales a todos sus canales.
florisla
fuente
-1

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

Sócrates
fuente
66
SCL no solo se emite. Un esclavo puede estirar el reloj si necesita ralentizarlo.
stevenvh
Puede usar un multiplexor analógico (que es bidireccional) pero un decodificador puede no funcionar por el motivo indicado por stevenh. Si usa 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.
Kevin White