Fork me on GitHub

05/12/12

Comunicação I2C

Comunicação I2C

 I2C

Esse novo barramento foi batizado pela empresa Holandesa (Philips) como Inter IC ou I2C e possibilita a utilização de grande quantidade de componentes padronizados, os quais podem realizar diversas funções, além de possibilitar a troca eficaz de informações entre eles. Esse novo barramento obteve uma grande aceitação do mercado, tornando-se um dos mais utilizados e isso foi determinante para a crianção da versão 2.0, lançada em 1998.
O conceito do barramento I2C é facilitar a integração de circuitos de caráter final de aplicação como por exemplo sensores e conversores , com um sistema de controle, de modo que eles possam trabalhar com seus sinais de maneira direta.

 O barramento I2C

Uma característica bastante interessante deste barramento é a possibilidade de utilizar, em um mesmo sistema, componentes de tecnologias construtivas diferentes sem que haja incompatibilidade e nem conflitos na comunicação.
No I2C a transmissão da informação entre os dispositivos é feita através de 2 fios (Serial Data DAS e Serial Clock SCL).




Os dispositivos ligados em Inter IC possuem um endereço fixo (cada componente recebe um endereço específico), e podemos configurá-los para receber ou transmitir dados; dessa maneira eles podem ser classificados de várias formas, como: mestres (MASTER), escravos (SLAVE), entre outras.
O barramento I2C é do tipo multi-mestre, isso significa que mais de um dispositivo de controle pode ser conectado a ele. No entanto, durante uma comunicação, somente um dos mestres pode estar ativo, ou ocorrerá uma colisão de dados no barramento.
Por exemplo: enquanto um microcontrolador envia sinais a um conversor, um outro microcontrolador troca informações com uma memória usando o mesmo barramento. Tudo isso é possível, graças a uma "arbitragem" que determina qual dos sinais tem prioridade no envio dos dados.
As linhas SDA como SCL são bidirecionais e devem ser ligadas ao positivo da alimentação através de uma fonte de corrente ou de um resistor pull-up, para garantir que ambas as linhas permaneçam em nível alto, quando o barramento está livre. 
Uma das vantagens do padrão I2C é que ele não fixa a velocidade de transmissão (freqüência), pois ela será determinada pelo circuito MASTER (transmissão do SCL).

 Condições de Start e Stop
A comunicação entre os dispositivos mestres e os escravos, conectados ao barramento I2C, é iniciada pela condição de start (início) e finalizada pela condição de stop (fim). Acompanhe a condição de start e stop na figura seguinte:




Dentro da operação I2C, temos os procedimentos start e stop. 
Uma transição de nível alto para baixo na linha SDA, enquanto a linha SCL está no nível alto, é o indicativo da situação de START. Já uma transição do nível baixo para o nível alto da linha SDA enquanto a linha SCL se mantém no nível alto, define uma condição STOP. Sempre o mestre é o responsável pela geração dessas condições. Após uma condição de START o barramento é considerado ocupado, e apenas volta a ficar livre algum tempo depois da condição de STOP.


Se forem geradas condições START seguidamente, o barramento vai se manter ocupado, porém com circuitos apropriados pode-se implementar a função de detectar as condições START e STOP nos dispositivos que devem ser conectados ao barramento.


 Formato dos Dados e Reconhecimento

As informações colocadas na linha SDA devem ter comprimento de 1 byte. O número de bytes que pode ser transferido em cada operação de transferência é limitado, além disso os bytes são transferidos enviando primeiramente o bit mais significativo MSB.
Caso o dispositivo que está recebendo o sinal, por algum motivo, não puder trabalhar os dados recebidos, ele pode alterar a linha SCL, colocando-a no nível baixo, e assim forçar o mestre a entrar num estado de espera. Dessa forma, fomente quando a linha estiver novamente livre a transferência dos dados pode continuar.
Após o escrita/leitura de um byte no barramento, o dispositivo receptor gera um bit de reconhecimento (acknowledge). O sinal de reconhecimento permite a fluência da transferência dos dados. Assim, por exemplo, após a condição de Start e o endereçamento estarem concluídos, o estágio (escravo) selecionado deve fornecer o sinal de reconhecimento (ACK).
O reconhecimento dos dados transferidos é obrigatório. O pulso gerado para esta finalidade é visualizado na figura seguinte:
A linha SDA do receptor é colocada em nível baixo durante o pulso de clock de modo que ele permaneça estável no nível baixo durante o período alto do pulso de clock.

 Endereçamento-padrão

O formato básico de um comando I2C é constituído por 7 bits de endereço, utilizando para especificar o dispositivo escravo a ser acessado, seguido por um bit indicador de leitura/escrita.
Normalmente o endereço básico de um comando I2C é composto por duas partes: a primeira, de 4 bits, especifica o tipo de dispositivo escravo a ser acessado. A segunda, de 3 bits, especifica um entre até oito dispositivos daquele tipo, o qual será acessado.
O bit R/W indica se a operação é de leitura (nível 1) ou de escrita (nível 0).

 Formato da Transmissão

Em um dos formatos de transmissão, talvez o mais utilizado, o transmissor mestre envia os sinais para um receptor escravo, conforme a figura apresentada a seguir:




1)         A transmissão é inicializada pelo mestre através de um bit de start (S).
2)         Em seguida é enviado o endereço físico do escravo ligado ao barramento I2C. O bit LSB desse endereço (R/W) informa se queremos ler ou escrever na memória.
3)         Após a recepção do endereço, o escravo envia um bit de reconhecimento (ACK) na linha SDA, informando para o master que está pronto para receber dados.
4)         Master envia os dados para o escravo. A confirmação do recebimento de cada byte é fornecida pelo bit ACK enviado pelo escravo.
5)         Ao término da comunicação, o master envia a condição de stop.


Gravação

Diagrama de gravação de dados:




Para gravarmos dados (byte) na EEPROM 24CXX, temos de seguir estes processos:

1)         Envio do bit de início da comunicação - START .
2)         Envio do byte com o endereço físico da memória 24CXX no barramento I2C, sendo o bit LSB desse byte (R/W) em nível 0 (escrita), pois vamos escrever na memória.
1)         Envio do endereço na EEPROM em que o dado será gravado.
2)         Envio dos dados (byte).
3)         Envio do bit de finalização de comunicação - STOP.
No processo de escrita, os bits de reconhecimento de dados ACK são gerados pelo receptor (memória). 

Leitura 

Diagrama de leitura de dados:




1)         Envio do bit de início da comunicação - START.
2)         Envio do byte com o endereço físico da memória 24CXX no barramento I2C, sendo o bit LSB desse byte (R/W) em nível 0 (escrita).
3)         Envio do endereço na EEPROM em que será lido o dado.
4)         Envio novamente do bit de início da comunicação - START.
5)         Envio novamente do byte com o endereço físico da memória 24CXX no barramento I2C, sendo o bit LSB desse byte (R/W) agora em nível 1 (leitura), pois vamos ler dados da memória.
6)         Leitura dos dados na memória. A cada byte lido o mestre envia uma confirmação de recebimento de dado ACK no barramento. 
7)         Ao término da leitura, o master informa que não quer mais ler dados através do bit NOACK, e finaliza a leitura pelo bit stop. 

No processo de leitura, os bits de reconhecimento de dados ACK são gerados pelo mestre (receptor). 

Programa de Gravação I2C




Teremos então como exemplo de programa:
 I2C_Init(100000);         // frequencia de clock do barramento I2C (CONSULTAR DATASHEET DO CHIP PARA SABER SUA FREQUENCIA MÁXIMA)
                           //esta função só precisa ser inicializada somente 1 unica vez no programa

 I2C_Start();              // start no barramento i2c
 I2C_Wr(0xA0);             // endereço da memória no barramento + comando de escrita(0)
 I2C_Wr(0x00);             // endereço da eerprom onde será salvo o dado
 I2C_Wr(variavel_A);       // grava a variável A no endereço 00 da memória serial
 I2C_Wr(variavel_B);       // grava a variável B no endereço 01 da memória serial
 I2C_Wr(variavel_C);       // grava a variável C no endereço 02 da memória serial
 I2C_Wr(variavel_D);       // grava a variável D no endereço 03 da memória serial
 I2C_Stop();               // condição de stop na comunicação i2c




Este diagrama de comunicação I2C é padrão e utilizados em muitos dispositivos I2C. Apesar de estarmos se tratando do processo de gravação para a serie de memória 24Cxx, este bloco de comandos são válidos para quase todos outros componentes I2C.Por exemplo: conversores A/D e D/A I2C, como o PCF8591N; RTC - PCF8583N, DS1307, entre outros.

Programa de Leitura I2C




O processo de leitura já em um pouco mais trabalhoso e confuso para muitos programadores, acompanhe:

Teremos então como exemplo de programa:
 I2C_Start();              // start no barramento i2c
 I2C_Wr(0xA0);             // endereço da memória no barramento + comando de escrita(0)
 I2C_Wr(0x00);             // endereço da eeprom onde será lido o byte
 I2C_Repeated_Start();     // re-start no barramento
 I2C_Wr(0xA1);             // endereço da memória no barramento + comando de leitura(1)
 variavel_A = I2C_Rd(1);    // leitura do endereço 00h na variável_A
 variavel_B = I2C_Rd(1);    // leitura do endereço 01h na variável_B
 variavel_C = I2C_Rd(1);    // leitura do endereço 02h na variável_C
 variavel_D = I2C_Rd(0);    // leitura do endereço 03h na variável_D
 I2C_Stop();               // finaliza a comunicação i2c


Acompanhe passo a passo o diagrama de leitura e escrita de dispositivos no barramento I2C. Para programar outros tipos de componentes, basta verificar o diagrama de leitura e escrita no datasheet fornecido pelo fabricante.


referência: wikipedia


Veja também a Bibloteca I2C MikroC.



13 comentários:

  1. Companheiro, você poderia me informar o nome de quem fez o post e a data da postagem para eu utilizar como referência?
    Obrigado.

    ResponderExcluir
    Respostas
    1. Autor do Post: eu, Tiago Henrique Melo. a data da postagem e 5/12/12.

      Excluir
    2. Muito obrigado. Vai pra referência.

      Excluir
  2. vc sabe fazer a mesma coisa do post na limguagem assembly?

    ResponderExcluir
    Respostas
    1. amigo tentei executar este código no mickoc mais não funcionou,o dado que ele lê é o 0xA1 que são os comandos, e não o dado armazenado em 0x00 que é o valor da variavel_A que eu coloquei.

      Excluir
  3. Olá, Gostaria de saber quantos dispositivos é possível interligar nesta comunicação, e qual o limite de distância entre eletrônicas.

    ResponderExcluir
    Respostas
    1. as memorias EEPROM que possuem 3 pinos de enderecamento nomeados como A0, A1, A2 ou E0, E1, E2; podem ser ligados ate 8 no msm barramento! vc tem q saber codigo binario pra poder entender ate quantos podem ligar! com esses 3 pinos ligados ao GND temos 000, o segundo dispositivo vai ser 001, 010, 011, 100, 101, 110 e 111; onde 1 é o pino quando vai ligado a +5V e 0 representa ligacao ao GND! depende de quantos pinos temos para fazer enderecamento; entao temos 8 dispositivos ligados no msm barramento; se forem 2 pinos como A0, A1: somente 4 pq: 00, 01, 10, 11; sempre comecando do maior para o menor: a ordem de ligacao é A2A1A0! quanto mais pinos de enderecamento tiver mais dispositivos podemos ligar; o numero é limitado tb pela capacitancia de 400pF do barramento, isso impede q seja ligado ha mtos metros de distancia

      Excluir
  4. Eu quero usar este protocolo para fazer uma ligação entre o Arduino e o Ev3, esxiste uma contra indicação quanto a isso?

    ResponderExcluir
    Respostas
    1. todos os arduinos q usam ATMEGA328P (uno, nano, etc): A4 - SDA, A5 - SCL; MEGA: 20 - SDA, 21 - SCL! so observando isso! e da uma googlada pra ver conexoes, experimentos, etc.

      Excluir
  5. Olá,
    Tenho uma dúvida..
    Estou iniciando um projeto onde tenho um controle de numero de vagas de um estacionamento utilizando um Arduino UNO, sensores ultrassônicos em cada vaga e luzes de indicação de vagas (disponível ou não),
    porém, como as saídas do Arduino são limitadas estou pesquisando em como utilizar esse protocolo para expandir o número de sensores.
    Precisarei de um PIC para fazer a comunicação ente Arduino x Sensor?
    É possível utilizar LED's para comunicar com o Arduino através do Protocolo I2C?

    Obrigado!

    ResponderExcluir
  6. Boa noite
    Estou utilizando um RTC para mostrar a hora em um display porém a comunicação não está dando muito certo... Sei que um dos problemas pode ser a frequência diferente entre este CI e o pic. Você saberia como posso olhar e/ou configurar esta em cada um deles?
    Grata

    ResponderExcluir

Postagens Relacionadas!!