avr/eeprom.h.

La libreria standard avr/eeprom.h viene fornita con il compilatore avr-gcc, che compila i nostri schizzi dall'IDE Arduino. Per collegare la libreria allo sketch, scrivere #include <avr/eeprom.h> La libreria ha un insieme di funzioni per lavorare con tipi di dati interi (byte - 1 byte, word - 2 byte, dword - 4 byte), float, e block "blocchi" - set di dati di qualsiasi formato (strutture, array, ecc.). Il lavoro si riferisce alla scrittura, alla lettura e all'aggiornamento. L'aggiornamento è uno strumento estremamente importante per evitare la sovrascrittura non necessaria delle celle di memoria. L'aggiornamento scrive se il valore in fase di scrittura è diverso dal valore corrente in quella cella. 
Lettura:
eeprom_read_byte(indirizzo) - restituirà un valore.
eeprom_read_word(indirizzo) - restituirà il valore.
eeprom_read_dword(indirizzo) - restituirà il valore.
eeprom_read_float(indirizzo) - restituirà un valore.
eeprom_read_block(indirizzo in SRAM, indirizzo in EEPROM, dimensione) - legge il contenuto dall'indirizzo in EEPROM all'indirizzo in SRAM.
Registrazione: 
eeprom_write_byte(indirizzo, valore)
eeprom_write_word(indirizzo, valore)
eeprom_write_dword(indirizzo, valore)
eeprom_write_float(indirizzo, valore)
eeprom_write_block(indirizzo in SRAM, indirizzo in EEPROM, dimensione) - scrive il contenuto all'indirizzo in SRAM nell'indirizzo in EEPROM.
Aggiornare:
eeprom_update_byte(indirizzo, valore)
eeprom_update_word(indirizzo, valore)
eeprom_update_dword(indirizzo, valore)
eeprom_update_float(indirizzo, valore)
eeprom_update_block (indirizzo nella SRAM, indirizzo nella EEPROM, dimensione) - aggiorna il contenuto dall'indirizzo nella SRAM all'indirizzo nella EEPROM. 
Macro:
_EEPUT(addr, val) - scrive (write) il byte val nell'indirizzo addr. Il casting del tipo non è richiesto (è fatto nella macro).
_EEGET(val, addr) - legge un byte in addr e lo scrive in val. Il casting del tipo non è richiesto (è fatto nella macro)
Considera un semplice esempio in cui i singoli tipi di dati vengono scritti e letti in celle diverse:
#include <avr/eeprom.h>
void setup() 
     Serial.begin(9600);
     // dichiarare dati di diverso tipo
     byte dataB = 120; 
     float dataF = 3.14; 
     int16_t dataI = -634;
     // scrivetevi l'un l'altro 
     eeprom_write_byte(0, dataB); // 1 byte
     eeprom_write_float(1, dataF); // 4 bytes
     // per una diversità "aggiornamento" 
     eeprom_update_word(5, dataI);
     // dichiariamo le variabili dove leggeremo 
     byte dataB_read = 0; 
     float dataF_read = 0; 
     int16_t dataI_read = 0;
     // leggere
     dataB_read = eeprom_read_byte(0); 
     dataF_read = eeprom_read_float(1); 
     dataI_read = eeprom_read_word(5);
     // visualizzerà 120 3,14 -634
     Serial.println(dataB_read); 
     Serial.println(dataF_read); 
     Serial.println(dataI_read);
}
void loop() 
{
}
Memorizzare i dati in questo modo non è molto conveniente, perché la gestione degli indirizzi deve essere fatta manualmente, contando il numero di byte di ogni tipo e "spostando" l'indirizzo della quantità richiesta. È molto più conveniente archiviare dati eterogenei in strutture. Dobbiamo passare alla funzione l'indirizzo dei dati in memoria (operatore &), appunto un puntatore, e convertirlo anche nel tipo void*, perché la funzione di lettura/scrittura del blocco accetta proprio questo tipo. Inoltre, alla funzione di lettura/scrittura del blocco deve essere passata la dimensione del blocco di dati in byte. Questo può essere fatto manualmente (con un numero), ma è meglio usare sizeof(), che calcolerà questa dimensione e la passerà alla funzione. 
#include <avr/eeprom.h> 
void setup() 
     Serial.begin(9600); 
     // dichiarare una struttura
     struct MyStruct 
     { 
          byte a; 
          int b; 
          float c; 
     }; 
     // creare e riempire la struttura 
     MyStruct myStruct; 
     myStruct.a = 10; 
     myStruct.b = 1000; 
     myStruct.c = 3.14; 
     // scrivere all'indirizzo 10, specificando le dimensioni della struttura e getto da void* 
     eeprom_write_block((void*)&myStruct, 10, sizeof(myStruct)); 
     // creare una nuova struttura vuota 
     MyStruct newStruct; 
     // leggere dall'indirizzo 10
     eeprom_read_block((void*)&newStruct, 10, sizeof(newStruct)); 
     // controllo
     // visualizzerà 10, 1000, 3.14 
     Serial.println(newStruct.a); 
     Serial.println(newStruct.b); 
     Serial.println(newStruct.c); 
void loop() 
{
}
Puoi memorizzare gli array allo stesso modo:
#include <avr/eeprom.h> 
void setup() 
     Serial.begin(9600); 
     // creare un array
     float dataF[] = {3.14, 60.25, 9132.5, -654.3}; 
     // scrivere all'indirizzo 20, specificando la dimensione
     eeprom_write_block((void*)&dataF, 20, sizeof(dataF)); 
     // creare un nuovo array vuoto dello stesso tipo e dimensione
     float dataF_read[4]; 
     // leggere dall'indirizzo 20 
     eeprom_read_block((void*)&dataF_read, 20, sizeof(dataF_read)); 
     // controllo
     // visualizzerà 3.14, 60.25, 9132.5, -654.3 
     for (byte i = 0; i < 4; i++) 
     Serial.println(dataF_read[i]); 
void loop() 
{
}
La libreria avr/eeprom.h ha un altro strumento molto utile - EEMEM, che permette di indirizzare automaticamente i dati creando dei puntatori, il cui valore verrà assegnato dal compilatore. Consideriamo un esempio in cui scriviamo diverse variabili, una struttura e un array in EEPROM, distribuendo loro automaticamente gli indirizzi. Punto importante! Gli indirizzi sono specificati dal basso verso l'alto nell'ordine della dichiarazione EEMEM:
#include <avr/eeprom.h>
struct MyStruct 
     byte val1; 
     int val2; 
     float int3;
};
uint8_t EEMEM byteAddr; // 27
uint16_t EEMEM intAddr; // 25
uint32_t EEMEM longAddr; // 21
MyStruct EEMEM myStructAddr; // 14
int EEMEM intArrayAddr[5]; // 4
float EEMEM floatAddr; // 0
EEMEM stesso distribuisce gli indirizzi in base alla dimensione dei dati. Un punto importante: questo approccio non occupa spazio di memoria aggiuntivo, ad es. numerare gli indirizzi manualmente con i numeri, senza creare "variabili" EEMEM, non occupa meno memoria! Torniamo al nostro primo esempio e lo riscriviamo con EEMEM. Quando si specifica un indirizzo tramite EEMEM, è necessario utilizzare l'operatore di acquisizione indirizzi &.
#include <avr/eeprom.h> 
byte EEMEM dataB_addr; 
float EEMEM dataF_addr; 
int16_t EEMEM dataI_addr; 
void setup() 
     Serial.begin(9600); 
     // dichiarare dati di diverso tipo 
     byte dataB = 120; 
     float dataF = 3.14; 
     int16_t dataI = -634; 
      // scrivetevi l'un l'altro 
     eeprom_write_byte(&dataB_addr, dataB); 
     eeprom_write_float(&dataF_addr, dataF); 
      // per una diversità "aggiornamento"
     eeprom_update_word(&dataI_addr, dataI); 
      // dichiariamo le variabili dove leggeremo 
     byte dataB_read = 0; 
     float dataF_read = 0; 
     int16_t dataI_read = 0; 
      // leggiamo 
     dataB_read = eeprom_read_byte(&dataB_addr); 
     dataF_read = eeprom_read_float(&dataF_addr); 
     dataI_read = eeprom_read_word(&dataI_addr); 
     // visualizzerà 120, 3.14, -634 
     Serial.println(dataB_read); 
     Serial.println(dataF_read); 
     Serial.println(dataI_read); 
void loop() 
{
}
Scrivere e leggere un blocco tramite EEMEM. L'indirizzo dovrà essere convertito in (const void*) manualmente:
#include <avr/eeprom.h> 
// ottenere l'indirizzo (sarà 0 qui) 
int EEMEM intArrayAddr[5]; 
void setup() 
     Serial.begin(9600); 
     // creare un array  
     int intArrayWrite[5] = {10, 20, 30, 40, 50}; 
     // scrivere all'indirizzo intArrayAddr 
     eeprom_write_block((void*)&intArrayWrite, (const void*)&intArrayAddr, sizeof(intArrayWrite));
     // creare un nuovo array di lettura 
     int intArrayRead[5]; 
     //leggere all'indirizzo intArrayAddr
     eeprom_read_block((void*)&intArrayRead, (const void*)&intArrayAddr, sizeof(intArrayRead)); 
     // controllo  
     for (byte i = 0; i < 5; i++) 
     Serial.println(intArrayRead[i]); 
void loop() 
{
}
In questo modo è possibile aggiungere "dati" da memorizzare in EEPROM proprio durante lo sviluppo del programma, senza pensare agli indirizzi. Consiglio di aggiungere nuovi dati sopra quelli vecchi in modo che l'indirizzamento non vada fuori strada (ricordo che l'indirizzamento va dal basso verso l'alto, partendo da zero). 
Crea il tuo sito web gratis! Questo sito è stato creato con Webnode. Crea il tuo sito gratuito oggi stesso! Inizia