Como resolver conflitos de endereço I2C?

39

Desejo conectar vários dispositivos escravos I2C a um microcontrolador no mesmo conjunto de pinos, mas todos os dispositivos I2C compartilham o mesmo endereço. Os endereços são fixos no hardware.

Existe alguma maneira de conectar vários dispositivos com o mesmo endereço?

Talvez algum tipo de módulo de conversão de endereços I2C em cada dispositivo com um endereço configurável, para que eu possa atribuir meus próprios endereços a cada um.

Simon P Stevens
fonte

Respostas:

24

Não há nada embutido no I2C para fazer isso, normalmente os dispositivos escravos terão alguns pinos externos que podem ser configurados para 0 ou 1 para alternar alguns bits de endereço para evitar esse problema. Como alternativa, eu lidei com alguns fabricantes que têm 4 ou 5 números de peça, a única diferença é o endereço I2C.

A maioria dos dispositivos possui hardware específico que lida com a comunicação I2C, ou seja, o ACK escravo está no hardware, então você realmente não pode se esquivar disso.

Quanto ao módulo de tradução, você pode comprar alguns PICs de US $ 0,50 com 2 barramentos I2C e escrever um código rápido para fazê-los agir como tradutores de endereço, eu acho.

Marca
fonte
Obrigado. Sim, esses dispositivos têm um endereço selecionado, mas apenas entre dois endereços e eu quero conectar mais de 5 dispositivos, então ainda acabo enfrentando conflitos. Eu não tinha pensado em usar um PIC. Isso deve funcionar. Não há nada na prateleira que faça esse tipo de coisa?
Simon P Stevens
11
O NXP cria vários multiplexadores / switches para o I2C. Você pode criar algo a partir deles: ics.nxp.com/products/i2cmuxes, por exemplo, você pode criar no seu caso três sub-ramificações, cada uma com dois dispositivos e use um dos switches da NXP para atingir seu objetivo.
Mark
Ótimo, esse é exatamente o tipo de coisa que eu estava procurando. Eu simplesmente não sabia o nome. Obrigado.
Simon P Stevens
Esta resposta tem 7 anos e, portanto, acredito que poderia ter sido a melhor no momento em que foi oferecida. Para outros que estão chegando agora, no entanto, algumas das respostas mais recentes (atualmente com classificação mais baixa na lista) oferecem abordagens potencialmente melhores com base nos componentes mais novos que estão agora no mercado.
21417 Brick
6

Acabei de encontrar este problema com vários dispositivos I2C com um endereço fixo. Nossa solução foi usar linhas de E / S no microcontrolador para forçar as linhas SDA nos dispositivos que não queremos abordar, enquanto a linha de E / S para o dispositivo alvo é definida como entrada (alta impedância ) Isso significa que apenas o dispositivo de destino corresponde ao endereço I2C e os outros ignoram os dados subsequentes.

Vários dispositivos I2C com o mesmo endereço

Os resistores na linha SDA para os dispositivos inativos acabam agindo como pull-ups para o barramento, portanto, o valor exato dependerá de quantos dispositivos você possui e qual pull-up você precisa para seu barramento. Portanto, se você escolher resistores de 10K, três dispositivos inativos resultarão em um pullup de 3K3.

Os diodos schottky garantem que o dispositivo ainda possa puxar a linha SDA baixo o suficiente ao transmitir dados de volta ao host.

Peter Gibson
fonte
Agradeço que você tenha acompanhado e postado isso. Esta é uma solução bastante engenhosa, tenho certeza de que será útil para outras pessoas.
Simon P Stevens
Um bom nicho que pode ser usado em algumas aplicações. Eu gosto muito.
Harry Svensson
5

Se nenhum dos dispositivos I2C usa alongamento do relógio (handshake) e se você está batendo no mestre do I2C, um simples truque é fazer com que alguns deles troquem o relógio e os pinos de dados. Durante a transmissão de um byte, o dispositivo que possui o clock e os pinos de dados trocados verá cada bit "0" como um não evento (dados subindo e descendo sem relógio) e verá cada bit "1" como uma parada I2C e iniciar (o relógio aumenta enquanto os dados estão baixos, diminui com os dados aumentando e diminuindo, seguidos pela diminuição do relógio). As condições intencionais de parada e partida de um dispositivo podem ser vistas como bits de dados pelo outro, mas, a menos que um dispositivo tenha um número excessivo de condições de partida e parada entre os bits "1", seria improvável que qualquer dispositivo "acidentalmente"

supercat
fonte
6
Não estou com voto negativo, mas isso me parece um pouco arriscado. Minha experiência com o I2C é que ele é propenso a ruídos o suficiente com apenas a conexão usual. No entanto, você usa a palavra "hack" e menciona a ressalva "se nenhum dos dispositivos i2c usar o alongamento do relógio"; portanto, se ele funcionar para alguém, terá mais poder para eles.
Jason S
5

Eu consideraria o uso de comutadores de barramento para multiplexar o barramento I2C entre os dispositivos com endereços conflitantes. Os comutadores de barramento são de capacitância e resistência muito baixas e, diferentemente dos buffers / drivers, são comutadores verdadeiros que conectam ou desconectam dois nós do circuito.

Os comutadores de barramento geralmente têm uma característica estranha, o que não importa para o I2C porque usa dispositivos de dreno aberto: um comutador de barramento tem baixa resistência ao ligar tensões próximas a 0 (Vss), mas a resistência aumenta dramaticamente à medida que as tensões se aproximam. a fonte de alimentação Vdd. (Isso ocorre porque eles são basicamente MOSFETs com tensões de porta na fonte de alimentação quando ligam, portanto, quando as tensões comutadas se aproximam de Vdd, as Vgs disponíveis são muito mais baixas)

Jason S
fonte
11
O link está quebrado. fairchildsemi.com/product-technology/bus-switches funciona melhor.
Florisla
4

Eu tinha dois sensores de luz colorida TCS3414 que queria comparar (os pacotes FN e CS, que possuem filtros diferentes). O endereço I2C está conectado. Depois de examinar como o I2C funciona em termos das linhas SCL (relógio) e SDA (dados), parecia que desligar a linha SDA impediria o chip de começar ou parar um bit e, assim, deixá-lo inativo. Então, usei um comutador analógico CMOS (4066B) para ativar ou desativar a linha SDA para cada dispositivo. Isso funcionou muito bem para alternar entre os dois dispositivos. Eu sei que é um hack, e o PCA9548 seria muito melhor, mas eu não tinha um à mão.

David Hill
fonte
Na verdade, isso não é um hack, e eu diria que essa deve ser a resposta aceita. Eu já vi isso usado em vários produtos comerciais e não consigo pensar em uma solução melhor (a menos que você não tenha GPIO disponível e, portanto, precise de uma solução I2C pura, como os muxes específicos para I2C). Os bons e velhos muxes analógicos têm muita largura de banda e são muito baratos.
Jay Carlson
4

Agora existe uma resposta: a Linear Tech possui a série LTC4316 / 17/18 de tradutores de endereço. Eles são relativamente novos e a disponibilidade é incerta.

user3608541
fonte
Componente muito interessante. A maioria dos dispositivos I2C possui 2 endereços fixos e isso pode LTC4316 ser potencialmente o dobro do endereçamento a um custo razoável.
Mehrad 16/02
4

Vários fabricantes oferecem CIs de switch e multiplexador de barramento I2C.

Um mux pode ativar um canal de cada vez; um switch pode ativar vários em paralelo.

Veja, por exemplo, as ofertas de NXP , TI e Maxim .

Para experimentação, a Adafruit possui uma placa TCA9548a .

Se você tiver 8 chips de destino com endereços idênticos, selecione um MUX de 8 para um. Antes de acessar qualquer um dos chips de destino, configure o MUX para ativar o barramento I2C correto.

Vantagens

  • Não requer programação (abordagem baseada em microcontrolador)
  • Pode suportar os recursos e velocidades I2C que você precisa (vs muxes de barramento analógico / digital regulares). Por exemplo, um MUX comum (não I2C) não passa endereços de chamada geral para todos os seus canais.
florisla
fonte
-1

Use um chip demux simples (por exemplo, 74HC139 após) e conecte o pino I2C CLK à entrada (já que o pino I2C CLK é apenas de saída). Use pinos GPIO para controlar a saída desejada. O pino de dados I2C pode ser compartilhado entre todos os escravos.

Sócrates
fonte
6
SCL não é apenas saída. Um escravo pode esticar o relógio se precisar desacelerá-lo.
Stevenvh
Você pode usar um multiplexador analógico (bidirecional), mas um decodificador pode não funcionar pelo motivo indicado por stevenh. Se você usar o multiplexador, precisará de uma polpa fraca no lado escravo para garantir que seja mantida inativa. Também altere a seleção do multiplexador apenas quando o barramento estiver ocioso.
Kevin White