Cómo almacenar un conjunto de valores en la EEPROM de ATmega16 y luego leerlo en secuencia

4

Tengo este programa en el que puedo almacenar un solo valor en EEPROM. ¿Puedo almacenar una matriz de valores en EEPROM? ¿Cómo?

    #include <avr/io.h>
    #include <avr/eeprom.h>

    // macro for easier usage
    #define read_eeprom_word(address) eeprom_read_word ((const uint16_t*)address)
    #define write_eeprom_word(address,value) eeprom_write_word ((uint16_t*)address,(uint16_t)value)

    //declare an eeprom variable
    unsigned int EEMEM   my_eeprom_word;

    int main(void)
   {

    write_eeprom_word(&my_eeprom_word,OCR1A);       // store value in eeprom

    OCR1A = read_eeprom_word(&my_eeprom_word);     // restore from eeprom

    while(1)
    {

    }
    }
    
pregunta user3052614

1 respuesta

5

Puede declarar una matriz eeprom y escribir posiciones individuales. Tenga en cuenta que, a diferencia de la matriz ram, solo puede leer y escribir en la matriz eeprom utilizando la macro eeprom de lectura / escritura.

El siguiente código es para leer / escribir valores sin signo de 16 bits

#include <avr/io.h>
#include <avr/eeprom.h>

// macro for easier usage
#define read_eeprom_word(address) eeprom_read_word ((const uint16_t*)address)
#define write_eeprom_word(address,value) eeprom_write_word ((uint16_t*)address,(uint16_t)value)
#define update_eeprom_word(address,value) eeprom_update_word ((uint16_t*)address,(uint16_t)value)

//declare an eeprom array
unsigned int EEMEM  my_eeprom_array[10];

// declare a ram array
unsigned int my_ram_array[10];

int main(void)

{    
    // write to eeprom array
    write_eeprom_word(&my_eeprom_array[0], 1);  // write value 1 to position 0 of the eeprom array
    write_eeprom_word(&my_eeprom_array[1], 2);  // write value 2 to position 1 of the eeprom array
    write_eeprom_word(&my_eeprom_array[2], 3);  // write value 3 to position 2 of the eeprom array

    // read from eeprom array
    my_ram_array[0] = read_eeprom_word(&my_eeprom_array[0]);   // read value from position 0 of the eeprom array to ram array position 0
    my_ram_array[1] = read_eeprom_word(&my_eeprom_array[1]);   // read value from position 1 of the eeprom array to ram array position 1
    my_ram_array[2] = read_eeprom_word(&my_eeprom_array[2]);   // read value from position 2 of the eeprom array to ram array position 2

    while(1);    
}

Una alternativa es usar actualizar en lugar de escribir. Esta función verifica el contenido de la celda eeprom y solo escribe los datos si es diferente del valor existente para reducir las escrituras innecesarias y reducir el desgaste de la eeprom.

 // update eeprom array
    update_eeprom_word(&my_eeprom_array[0], 1);  // write value 1 to position 0 of the eeprom array only if it differs
    update_eeprom_word(&my_eeprom_array[1], 2);  // write value 2 to position 1 of the eeprom array only if it differs
    update_eeprom_word(&my_eeprom_array[2], 3);  // write value 3 to position 2 of the eeprom array only if it differs

Las rutinas de manejo de AVR eeprom están listadas enlace

Hay otra alternativa que puede copiar la matriz RAM completa a la matriz eeprom y viceversa, utiliza la escritura de bloque:

#include <avr/io.h>
#include <avr/eeprom.h>

// macro for easier usage
#define read_eeprom_array(address,value_p,length) eeprom_read_block ((void *)value_p, (const void *)address, length)
#define write_eeprom_array(address,value_p,length) eeprom_write_block ((const void *)value_p, (void *)address, length)


//declare an eeprom array
unsigned int EEMEM  my_eeprom_array[10];

// declare a ram array and initialize
unsigned int my_ram_array[10]={1,2,3,4,5,6,7,8,9};

// declare another ram array
unsigned int my_other_ram_array[10];

int main(void)

{    
    // Copy data from my_ram_array to eeprom array
    write_eeprom_array(my_eeprom_array,my_ram_array,sizeof(my_eeprom_array));

    // restore to my_other_ram_array from eeprom
    read_eeprom_array(my_eeprom_array,my_other_ram_array,sizeof(my_eeprom_array));

    while(1);    
}

El último parámetro en la escritura de bloque es cuántos bytes escribir. En el ejemplo anterior, la longitud de la matriz es de 10 enteros de 16 bits, lo que significa 10 * 2 bytes = 20 bytes.
En lugar de utilizar

write_eeprom_array(my_eeprom_array,my_ram_array,20);

He utilizado la función sizeof () que devuelve la longitud del byte de la matriz, por lo que no es necesario cambiarla cada vez que se cambia el tamaño de la matriz

write_eeprom_array(my_eeprom_array,my_ram_array,sizeof(my_eeprom_array));

Si lo desea, puede utilizar ese valor para manipular la longitud de escritura / lectura, por ejemplo, puede escribir solo los primeros 3 valores

write_eeprom_array(my_eeprom_array,my_ram_array,3);

o valores my_ram_array [3], my_ram_array [4], my_ram_array [5]

write_eeprom_array(&my_eeprom_array[3],&my_ram_array[3],3);
    
respondido por el alexan_e

Lea otras preguntas en las etiquetas