Memória EEPROM externa com o Arduino


Incorporando memória EEPROM ao registrador de dados

Obs: O nome EEPROM significa que estamos usando uma memória que é apagada eletricamente ( electrically erasable programmable read-only memory). Nos inícios dos tempos as memórias ROM tinham que ser apagadas com um “banho” de ultravioleta. Felizmente a EEPROM surgiu, pois tornou possível aplicações antes inimagináveis!

Em muitos projetos a memória interna do Arduino não é suficiente. Em casos de equipamentos de registro de dados esta situação ocorre praticamente sempre. Neste experimento vamos incorporar uma memória de 32Kbits (4 Kbytes) à placa UNO. Utilizaremos a memória AT24C32. Esta memória se comunica com o Arduino através do barramento I2C, o mesmo empregado com o RTC visto anteriormente. Em termos de hardware, utilizaremos a placa tinyRTC , que já estudamos anteriormente.

A configuração da memória AT24C32, e da maioria das memórias I2C, é a seguinte:

Pinagem da memória AT24C32

O significado da pinagem é o seguinte:

  • A0-A2: endereçamento básico da memória. Uma boa placa de hardware deve te permitir ajustar este endereço em qualquer faixa de 000 a 007, pois assim você poderá utilizar até oito chips de memória no mesmo barramento.
  • GND: terra
  • SDA: Serial data. Parte do barramento I2C
  • SCL: Serial clock. Parte do barramento I2C
  • WP: Write protect. Deve ficar em 0 (zero) para podermos efetuar gravações na memória
  • Vcc: Alimentação, 2.7 a 5.5 volts.

Se você estiver utilizando a mesma placa TinyRTC utilizada no experimento com o RTC, toda a ligação de hardware entre o arduino e a memória já está completa. Se estiver utilizando o chip sozinho, lembre-se de que o SLC e o SDA necessitam de um resistor de pull-up da ordem de 4k7.

Biblioteca para acesso à 24C32

Observando o esquema da placa TinyRTC podemos verificar que o endereço da EEPROM é o 50H. Este dado, e a biblioteca descrita a seguir são o que necessitamos para acessar uma memória I2C.

O código que será descrito a seguir, além de rotinas que demostram a funcionamento e testam o acesso à memória eeprom externa, pode ser obtido em https://cadernodelaboratorio.com.br/scripts-softwares-e-arquivos-de-configuracao/ , sob o nome pack170925.tar.gz


Para escrever um byte na EEPROM I2C

/*
 * deviceaddress:  endereço do dispositivo- no caso da placa tinyRTC o endereço é fixo m 0x50
 * eeaddress: endereço do byte na memória
 * data: byte a ser escrito
 */

void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
    int rdata = data;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.write(rdata);
    Wire.endTransmission();
}

Para escrever um grupo de bytes na EEPROM I2C

Atenção. Devido a limites da biblioteca wire, o conjunto de bytes deve ter o máximo de 32 elementos


/*
 * obs:Máximo número de bytes: 30
 * deviceaddress:  endereço do dispositivo- no caso da placa tinyRTC o endereço é fixo em 0x50
 * eeaddress: endereço do byte na memória
 * *data: ponteiro para o início dos bytes a serem escritos
 * length: número de bytes a escrever. Max 30 
 */
  
void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddresspage >> 8)); // MSB
    Wire.write((int)(eeaddresspage & 0xFF)); // LSB
    byte c;
    for ( c = 0; c < length; c++)
        Wire.write(data);
    Wire.endTransmission();
}

Para ler um byte na EEPROM I2C


/*
 * Para ler  um byte da eeprom
 * deviceaddress:  endereço do dispositivo- no caso da placa tinyRTC o endereço é fixo em 0x50
 * eeaddress: endereço do byte na memória
 * retorna o byte lido
 */

byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
    byte rdata = 0xFF;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,1);
    if (Wire.available()) rdata = Wire.read();
    return rdata;
}

Para ler um conjunto de bytes da EEPROM I2C

Atenção. Devido a limites da biblioteca wire, o conjunto de bytes deve ter o máximo de 32 elementos


/*
 * Para ler um conjunto de bytes da eeprom
 * obs:Máximo número de bytes: 30
 * deviceaddress:  endereço do dispositivo- no caso da placa tinyRTC o endereço é fixo em 0x50
 * eeaddress: endereço do byte na memória
 * *data: ponteiro para o início dos bytes a serem lidos
 * length: número de bytes a ler. Max 30 
 */

void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,length);
    int c = 0;
    for ( c = 0; c < length; c++ )
        if (Wire.available()) buffer = Wire.read();
}

Para escrever um inteiro na EEPROM I2C

Atenção: Um inteiro ocupa dois bytes. Lembre-se disto ao indicar o endereço de leitura ou escrita


/*
 * Para escrever um inteiro (2 bytes) na eeprom
 * deviceaddress:  endereço do dispositivo- no caso da placa tinyRTC o endereço é fixo em 0x50
 * eeaddress: endereço do byte na memória
 * nValue: inteiro a ser escrito
 *  
 */

void i2c_eeprom_write_int( int deviceaddress, unsigned int eeaddresspage, int nValue) 
	{
    byte lowByte = (byte) ((nValue >> 0) & 0xFF);
    byte highByte = (byte) ((nValue >> 8) & 0xFF);

    i2c_eeprom_write_byte( deviceaddress, eeaddresspage, lowByte);
    delay(1);
    i2c_eeprom_write_byte( deviceaddress, eeaddresspage+1, highByte);
    } 

Para escrever um inteiro na EEPROM I2C

Atenção: Um inteiro ocupa dois bytes. Lembre-se disto ao indicar o endereço de leitura ou escrita

/*
 * Para ler um inteiro da eeprom
 * deviceaddress:  endereço do dispositivo- no caso da placa tinyRTC o endereço é fixo em 0x50
 * eeaddress: endereço do byte na memória
 * retorna o inteiro lido
 */

int  i2c_eeprom_read_int( int deviceaddress, unsigned int eeaddress ) 
	{
	byte lowByte= i2c_eeprom_read_byte(deviceaddress, eeaddress );
	byte highByte= i2c_eeprom_read_byte(deviceaddress, eeaddress+1 );
	return ((lowByte & 0xFF) | ((highByte << 8) & 0xFF00));
}

Faça o download dos arquivos e das rotinas de teste para compreender bem como utilizar estas rotinas para acessar a memória EEPROM externa. https://cadernodelaboratorio.com.br/scripts-softwares-e-arquivos-de-configuracao/ , sob o nome pack170925.tar.gz

Até a próxima!

Deixe um comentário