Usare 2 eeprom

Salve a tutti
io vorrei utilizzare due eeprom (come da titolo), ma effettivamente EEPROM.h non consente di selezionare l’indirizzo del chip, ma solo quello all’interno di esso
al che ho guardato la prima inclusione di EEPROM.h

#include <avr/eeprom.h>

e dopo vari rigiri sono arrivato al codice di questa libreria…

il problema è che non ci ho capito molto… anzi… dire che è incasinata è dir poco…

da quello che ho intuito, comunque, qua è dove concatena l’indirizzo dell’eeprom ad 0x, per formarne un esadecimale… il fatto è che questa macro HEXNR viene usata per creare altre 3 macro:

# undef EECR
# define EECR _SFR_IO8((HEXNR >> 16) & 0xFF)

# undef EEDR
# define EEDR _SFR_IO8((HEXNR >> 8) & 0xFF)

# undef EEAR
# define EEAR _SFR_IO8(HEXNR & 0xFF)

e quindi qui non capisco più niente… o per meglio dire… quale di questi (EECR, EEDR, EEAR) è l’indirizzo utilizzato? (oppure qualsiasi altra cosa in quella libreria…)

io ho la versione 1.9 di arduino, ma credo sia uguale per tutti…
in ogni caso il percorso del file è questo

C:\Documents and Settings\User\Desktop\arduino-0019\hardware\tools\avr\avr\include\avr

so che è una domanda difficile… ma spero che qualcuno riesca ad aiutarmi! grazie!!

edit: avevo scritto una cavolata!!

Credo che la libreria eeprom.h serva per accedere solo alla Eeprom interna dell'Atmega. Per usare Eeprom esterne generalmente si usano chip I2C e si usa la libreria wire.h.

EDIT: Vedi qui: http://arduino.cc/playground/Code/I2CEEPROM

effettivamente è una risposta molto sensata...

resta il fatto che è una libreria veramente complicata!! c'è da fare i complimenti a chi si è messo a scriverla e poi la ha condivisa!!!

Al che ti chiedo perché:

Wire.send((int)(eeaddress >> 8)); // MSB
Wire.send((int)(eeaddress & 0xFF)); // LSB

lui manda due interi, uno composto da tutti zero unito agli 8 bit meno significativi dell'indirizzo a cui vuole scrivere il dato, e uno l'esatto contrario, ovvero i primi 8 bit dell'indirizzo e gli altri zero (se non erro)

al che tu mi dirai è dovuto alle specifiche dell'eeprom... mi basta sapere questo o c'è qualche altra ragione?

Lui manda l'indirizzo in formato byte basso/byte alto. Quindi prima spedisce gli 8 bit più significativi (che sono quelli a SX che infatti vengono spostati a DX di 8 posizioni, per poter spedire 1 byte, altrimenti nel troncamento la parte alta sparirebbe perché 1 byte considera solo i primi 8 bit) e poi spedisce il byte meno significativo composto dai primi 8 bit.

Quindi: EEADDRESS mettiamo che sia 00001000-11000000

Prima manda 00001000 (perché 00001000-11000000 >>8 da appunto 00000000-00001000) e poi manda 11000000 (perché 00001000-11000000 & $FF da appunto 00000000-11000000).

leo72: ...prima spedisce gli 8 bit più significativi

hai ragione... mi sono confuso... ma come mai gli manda degli interi e non dei byte? (facendo appunto il cast)

cmq suppongo che le specifiche dell'eeprom permettano il discorso di "spezzare" l'indirizzo che poi se lo ricostruisce da solo...

Confermo che EEPROM.h accede al eeprom interna al Atmega. Ciao Uwe

No, gli manda byte, non interi. Sui fili viaggiano solo byte. Ecco perché l'indirizzo, che è un intero (2 byte) viene spezzato in 2 byte. Quindi la libreria prima "sveglia" il chip indicato dall'indirizzo, poi manda l'indirizzo. A questo punto se deve leggere, "chiede" il byte all'indirizzo specificato, altrimenti spedisce il byte da scrivere

leo72: No, gli manda byte, non interi. Sui fili viaggiano solo byte. Ecco perché l'indirizzo, che è un intero (2 byte) viene spezzato in 2 byte.

perdonami... mi sto incasinando io... ma lui fa

Wire.send((int)(eeaddresspage >> 8)); // MSB
Wire.send((int)(eeaddresspage & 0xFF)); // LS

quindi manda un intero... che poi magari la send spezzerà a sua volta in due byte... no?

Credo che faccia il cast su integer perché l'indirizzo lo riceve come integer. Se però leggi la documentazione di Wire.send vedrai che la trasmissione di valori è fatta per byte. Probabilmente evita di trasformare l'indirizzo di tipo int in 2 byte per non mettere nel mezzo 2 variabili in più. Cioè, probabilmente funziona anche così:

  wire.send(lowByte(addressbyte));
  wire.send(highByte(addressbyte));

ma consuma più memoria.

leo72:  wire.send(lowByte(addressbyte));  wire.send(highByte(addressbyte));

ma consuma più memoria.

consuma più memoria l'invocazione delle funzioni lowByte e highByte? si potrebbe provare con macro...

cmq non mi torna appunto perché fa quel cast ad int... andrebbe provato senza... edit: mi sa che da errore la compilazione se non metti int

Ho riguardato anche uno sketch che feci tempo fa per provare 2 chip Eeprom ed effettivamente anch'io ho usato (int): probabilmente è la libreria che richiede dati di tipo int, non so perché.

leo72: probabilmente è la libreria che richiede dati di tipo int, non so perché.

I misteri della vita!!! e intanto ti ringrazio!

discutendo con dei miei amici, mi sono accorto che te passi due byte all'eeprom (che corrisponde all'indirizzo a cui vuoi scrivere). Con due byte indirizzi 2^16, ma io ho le eeprom da 512k, ovvero necessiterei di 19 bit, al contrario dei 16 che gli passo... C'è modo di arrivare ai 512k oppure sono limitato a 64k??

Devi vedere sul datasheet delle Eeprom come esse vogliono ricevere i dati.

Ma ora che ci penso... sono da 512 kbit o 512 kbyte?? C'è molta differenza.

Mi pare strano 512 KB, sarebbe tanto. Sarebbe una Eeprom da 4096 kbit! Se, come penso, ne hai una da 512 kb, sono 64 kB di capacità, quindi ti bastano 16 bit per l'indirizzo.

Perfetto :P

dovresti avermi risolto tutto :) grazie!