domingo, 12 de junho de 2016

Utilizando EEPROM I²C Com Arduíno

Olá, neste post iremos explicar como utilizar uma memória externa EEPROM com o barramento I²C e com um Arduíno. Para mais informações sobre o I²C, consulte o post anterior (clique aqui).

A EEPROM(Electrically-Erasable Programmable Read-Only) é uma memória que permite escrita e gravação e seus dados não são apagados quando não há energia. As memórias flash(pen driver, SD e outros), são uma evolução desse tipo de memória. A EEPROM pode ser utilizada para armazenar algumas informações do seu programa que precisam ser salvas quando não houver energia. Para mais informações sobre esse tipo de memória, consulte aqui.

Os micro-controladores que estão presentes nas mais diversas versões do Arduíno, têm diferentes quantidades de memória EEPROM disponíveis.

  • ATmega328 - 1KB (1024 bytes)
  • ATmega168 e ATmega8 - 512 bytes
  • ATmega1280 e ATmega2560 - 4 KB (4096 bytes)
É possível acessar a EEPROM dos micro-controladores e há uma biblioteca disponível para isso na própria IDE do Arduíno. A documentação pode ser encontrada aqui.

Mas, neste post, iremos focar no uso de EEPROMs externas que utilizam o barramento I²C para leitura e escrita.

Existem no mercado diversas marcas e modelos de memória, com os mais diversos tamanhos e para cada uma delas, há um protocolo definido para se comunicar e por isso, é difícil ter um código genérico de acesso. Esse exemplo funcionará para as EEPROMs do tipo 24C16,que são bem comuns. 

EEPROM 24C16WP

Essa memória tem 16 Kbits (2 Kbytes) de armazenamento, permitindo a leitura e escrita byte-a-byte ou em blocos (páginas). Aqui, iremos abordar a leitura e escrita byte-a-byte.

Montagem

Segue a lista de materiais utilizados:
  • 1 Memória EEPROM 24C16WP
  • 1 Arduíno Uno
  • 1 Protoboard
  • Alguns fios

Segue abaixo os pinos da memória:
Pinagem 24C16WP

Os pinos 6 (SCL) e 5 (SDA), são utilizados para o barramento I²C e devem ser conectados aos pinos analógicos do Arduíno A4 (SDA - Data ) e A5 (SCL - Clock)

O endereçamento I²C da memória inicia em 0x50 e vai até 0x57. Os pinos NC são utilizados para o ajustar esse endereçamento se aterrados(GND) ou ligados ao VCC.

Exemplo:
  • NC - 0, NC - 0, NC - 0 -> Endereço da memória 0x50
  • NC - 0, NC - 0, NC - 1 -> Endereço da memória 0x51
  • NC - 0, NC - 1, NC - 0 -> Endereço da memória 0x52

Essa configuração é interessante, pois podemos colocar até 8 memórias no mesmo barramento.

O pino 7(WC), é utilizado para indicar se a memória está protegida contra gravação ou não. Se "0" - ligado ao GND, a memória pode ser escrita. Se "1" - ligada ao VCC, protegida contra gravação.

Para o nosso exemplo, utlizaremos os pinos abaixo:

EEPROM Arduíno
6(SCL) A5(SCL)
5(SDA) A4(SDA)
8(VCC) VCC
4(VSS) GND
7(WC) GND

Segue abaixo do esquemático:

Esquema feito no programa Fritzing
Vamos ao programa:


#include ‹Wire.h›    
 
#define i2cAddress 0x50 //Endereço da memoria
 
void setup(void)
{
  Serial.begin(115200);
  Wire.begin();  //inicializando I2C

  int sizeBuf = 21;
  char buf[sizeBuf] = "teste gravando eeprom";
  
  Serial.print("Gravando... \n");
  for(int i = 0; i < sizeBuf; i++)
  {
    writeI2CEEPROM(i2cAddress,i,buf[i]);
  }
  
  Serial.print("Lendo... \n");
  for(int i = 0; i < sizeBuf; i++)
  {
    Serial.print((char)readI2CEEPROM(i2cAddress,i));  
  }
  Serial.print("\nFim... \n");
}
 
void loop(){}

void writeI2CEEPROM(int i2cAddr, byte memoryAddress, byte data)
{
  Wire.beginTransmission(i2cAddr);//iniciando barramento para o endereco I2C da memoria
  Wire.write(memoryAddress);//informando endereco da memoria 
  Wire.write(data);//dados
  Wire.endTransmission();//finalizando transmissao do emissor
  delay(5);
}

byte readI2CEEPROM(int i2cAddr, byte memoryAddress)
{
   byte data = 0xFF;
 
   Wire.beginTransmission(i2cAddr);//iniciando barramento para o endereco I2C da memoria
   Wire.write(memoryAddress);//informando endereco da memoria
   Wire.endTransmission();//finalizando transmissao do emissor
   Wire.requestFrom(i2cAddr,1);//avisando a memoria que espera-se dado (1 byte)
   if (Wire.available()){
     data = Wire.read();
  }
  return data;
}


No código acima, iremos escrever na memória a frase "teste gravando eeprom" e na sequência, os valores serão recuperados.

Vamos explicar alguns pontos do código.

void writeI2CEEPROM(int i2cAddr, byte memoryAddress, byte data)
{
  Wire.beginTransmission(i2cAddr);//iniciando barramento para o endereco I2C da memoria
  Wire.write(memoryAddress);//informando endereco da memoria 
  Wire.write(data);//dados
  Wire.endTransmission();//finalizando transmissao do emissor
  delay(5);
}

O método writeI2CEEPROM tem três parâmetros:

  • i2cAddr - Endereço I²C da memória
  • memoryAddress - endereço da memória (0 até 255)
  • data - byte que será gravado

Como já citado anteriormente, essa memória suporta até 2 Kbytes e por isso, ela terá 256 endereços para escrita e leitura (de 0 atá 255). Para escrever na memória, é necessário iniciar a transmissão, indicar o endereço da memória, enviar o byte e finalizar a transmissão. Esse protocolo, está definido no datasheet da memória, que pode ser consultado aqui.

byte readI2CEEPROM(int i2cAddr, byte memoryAddress)
{
   byte data = 0xFF;
 
   Wire.beginTransmission(i2cAddr);//iniciando barramento para o endereco I2C da memoria
   Wire.write(memoryAddress);//informando endereco da memoria
   Wire.endTransmission();//finalizando transmissao do emissor
   Wire.requestFrom(i2cAddr,1);//avisando a memoria que espera-se dado (1 byte)
   if (Wire.available()){
     data = Wire.read();
  }
  return data;
}

O método readI2CEEPROM tem dois parâmetros e retorna o byte gravado.
  • i2cAddr - Endereço I²C da memória
  • memoryAddress - endereço da memória (0 até 255)
Assim como na escrita, o protocolo de leitura está definido no datasheet da memória mas, de maneira resumida temos: inicio da transmissão, envia-se o endereço, finalização a transmissão, requisita-se a resposta e faz-se a leitura do valor se estiver disponível.

Segue a saída desse programa:

Para comprovar a a gravação, você pode comentar o trecho que faz a gravação. Ficando assim:



Sem comentários:

Enviar um comentário