HOME PROJETOS PROGRAMAÇÃO MÓDULOS EMAIL




BIBLIOTECA PARA ACESSO A DISPOSITIVOS I2C PARA A FAMÍLIA 16F

Dispositivos I2C estão se tornando cada vez mais atraentes para desenvolvimento de projetos com microcontroladores pois, usando apenas dois pinos, podemos conectar muitos dispositivos no mesmo bus I2C e economizar muitas portas do microcontrolador. Foi pensando nisso que resolvemos apresentar uma biblioteca com funções de protocolo I2C capaz de se comunicar com dispositivos I2C conectados a microcontroladores da família 16F.

Os microcontroladores da família 16F não pussuem em seu hardware o módulo MSSP, responsável por fornecer comunicação com vários tipos de dispositivos SPI e I2C sem que o programador tenha que se preocupar com detalhes de protocolo.

Com a biblioteca aqui apresentada, será possível fazer a comunicação com dispositivos I2C alocando-se os sinais SDA e SCL em quaisquer pinos do microcontrolador, contanto que pertençam a mesma porta de I/O.

Esta biblioteca foi testada e funcionou perfeitamente para dispositivos como RTC DS1307, expansor de portas de I/O de 8 bits como o PCF8574, displays de LCD I2C e displays LCD OLED tipo SSD1306.

Para conhecer o funcionamento geral de um bus I2C, é importante que se leia as explicações em UM POUCO SOBRE O BUS I2C.



FUNÇÕES DA BIBLIOTECA

A biblioteca "i2cproto_services.inc" fornece 7 funções básicas de baixo nível para controlar qualquer dispositivo I2C.

i2c_Start

A função i2c_Start envia a condição de START ao dispositivo, iniciando a comunicação entre o Master e o Slave. A função i2c_Start não tem parâmetros de entrada.
Veja exemplos i2cPut e i2cGet mais abaixo.

i2c_Stop

A função i2c_Stop envia a condição de STOPT ao dispositivo, encerrando a comunicação entre o Master e o Slave. A função i2c_Stop não tem parâmetros de entrada.
Veja exemplos i2cPut e i2cGet mais abaixo.

i2c_GetACK

A função i2c_GetACK deve sempre ser usada após a função i2c_Put para o Master aguardar a resposta do dispositivo Slave. Esta função sincroniza a comunicação liberando o bus I2C apenas quando a transmissão do byte terminar. A função i2c_GetACK não tem parâmetros de entrada.
Veja exemplos i2cPut e i2cGet mais abaixo.

i2c_SendACK

A função i2c_SendACK deve ser usada pelo Master para dizer ao Slave que o byte foi recebido.
Veja exemplos i2cPut e i2cGet mais abaixo.

i2c_NACK

A função i2c_NACK deve ser usada pelo Master para sinalizar ao Slave o fim da transmissão. Em seguida, o Master deve usar a função i2c_Stop para encerrar definitivamente a comunicação.
Veja exemplos i2cPut e i2cGet mais abaixo.

i2c_Put

A função i2c_Put envia a um byte de dado, contido no registrador W, ao dispositivo Slave. Após usar a função i2c_Put, o Master deve usar a função i2c_GetACK para esperar o Slave responder se realmente recebeu o dado enviado. A função i2c_Put requer que o registrador W seja previamente carregado com o valor a enviar. Exemplo:
Abaixo, um exemplo completo de uma função para acertar data e hora num RTC DS1307:

i2c_Get

A função i2c_Get lê um byte no dispositivo Slave e armazena no registrador i2c_IBUFF. Após chamar essa função, o Master deve usar a função i2c_SendACK para dizer ao Slave que o byte foi recebido. Se o Master desejar encerrar a leitura, deverá usar a função i2c_NACK para sinalizar ao Slave o fim da transmissão e, em seguida, usar a função i2c_Stop para encerrar definitivamente a comunicação.
Abaixo, um exemplo completo de uma função para ler um RTC DS1307:




USANDO AS FUNÇÕES DA BIBLIOTECA

Antes de continuar, baixe o arquivo que contem a biblioteca i2cproto_services no seu HD descomprima o arquivo e mova-o para a pasta de seus projetos.

A biblioteca permite a escolha dos pinos do microcontrolador que serão usados como SDA e SCL, observando que eles devem pertencer a mesma porta de I/O. Para selecionar quais portas serão usadas no projeto, modifique os símbolos i2c_TRIS, i2c_PORT, i2c_SDA e i2c_SCL para refletirem a especificação desejada. Os outros registradores não devem ser alterados.

Para usar as funções da biblioteca, inclua no programa o arquivo:
#include "i2cproto_services.inc"

A seguir, inclua os registradores e símbolos necessários, definindo a porta e os pinos que deseja usar:
UDATA 0x20 PULSE_DUTY equ .25 i2c_N0 RES 1 i2c_IBUFF RES 1 i2c_OBUFF RES 1 #define i2c_TRIS TRISB ; <-- Modifique #define i2c_PORT PORTB ; <-- Modifique a porta de I/O #define i2c_SDA 4 ; <-- Modifique o pino SDA #define i2c_SCL 5 ; <-- Modifique o pino SCL




ENVIANDO DADOS A UM DISPOSITIVO I2C

O procedimento mostrado aqui é apenas um modelo geral. Há dispositivos I2C que necessitam que se enviem outros comandos antes de poder receber dados do Master. Consulte sempre o data sheet do dispositivo.

Para enviar um ou vários bytes ao dispositivo I2C, usando as funções da biblioteca, siga o modelo apresentado abaixo.
call i2cStart ; envia condição de START movlw 0x4E ; pega o endereço de escrita do dispositivo call i2cPut ; envia o endereço de escrita ao slave call i2cGetACK ; aguarda o slave responder (ACK) movlw "O" ; pega o caracter "O" call i2cPut ; envia o caracter ao slave call i2cGetACK ; aguarda o slave responder (ACK) movlw "L" ; pega o caracter "L" call i2cPut ; envia o caracter ao slave call i2cGetACK ; aguarda o slave responder (ACK) movlw "A" ; pega o caracter "A" call i2cPut ; envia o caracter ao slave call i2cGetACK ; aguarda o slave responder (ACK) call i2cStop ; encerra a transmissão




RECEBENDO DADOS DE UM DISPOSITIVO I2C

O procedimento mostrado aqui é apenas um modelo geral. Há dispositivos I2C que necessitam que se enviem outros comandos antes de poder devolver dados ao Master. Consulte sempre o data sheet do dispositivo.

O procedimento de leitura é um pouco diferente da esctrita. Primeiro é necessário enviar START e, em seguida, enviar o endereço de escrita. Após receber o primeiro ACK, deve-se enviar START novamente e, em seguida, enviar o endereço de leitura. Só então estaremos aptos a iniciar a leitura dos dados propriamente ditos. O modelo abaixo mostra um exemplo de leitura.
call i2cStart ; envia condicao de START movlw 0x4E ; endereco de escrita call i2cPut ; envia endereco de escrita call i2cGetACK ; espera ACK do slave call i2cStart ; envia condição de START novamente movlw 0x4F ; endereco de leitura call i2cPut ; envia endereco de leitura call i2cGetACK ; espera ACK do slave call i2cGet ; le o dado 1 call i2cSendACK ; envia um ACK ao slave movf i2c_IBUFF, w ; pega o byte lido ..... .... ; faz algo com o dado lido call i2cGet ; le o dado 2 call i2cSendACK ; envia um ACK ao slave movf i2c_IBUFF, w ; pega o byte lido ..... .... ; faz algo com o dado lido continue lendo quantos dados forem necessários call i2cSendNACK ; informa que vai parar a leitura call i2cStop ; fim da transacao





Índice dos circuitos


H P S P I N

Desde 04 de Março de 2010

Atualização: 26 de Junho de 2020