Go Down

Topic: arduino e eeprom 24c08 (Read 3203 times) previous topic - next topic

zuzzuz

Salve vorrei utilizzare una eeprom 24c08 per salvare dei dati provenienti da un sensore.
La parte della sensoristica funziona ho problemi con la scrittura e lettura dei dati sulla eeprom.
Provo a scrivere il valore 0xAB sulla eeprom ma mi ritrovo il valore FF qualcuno mi sa dire dove sbaglio?
Code: [Select]
/*
  *  Use the I2C bus with small EEPROMs
  *  24C01, 20C02, 24C04, 24C08, 24C16
  *  Sketch:    I2C_EEPROM_Small.pde
  * 
  *  Derived from sketch for 24C64 devices posted on
  *     http://www.arduino.cc/playground/Code/I2CEEPROM
  *  From  hkhijhe   Date: 01/10/2010
  *
  *  This one by davekw7x
  *  March, 2011
  *
  * For a single device, connect as follows:
  * EEPROM 4 (GND) to GND
  * EEPROM 8 (Vcc) to Vcc (5 Volts)
  * EEPROM 5 (SDA) to Arduino Analog Pin 4
  * EEPROM 6 (SCL) to Arduino Analog Pin 5
  * EEPROM 7 (WP)  to GND
  * EEPROM 1 (A0)  to GND
  * EEPROM 2 (A1)  to GND
  * EEPROM 3 (A2)  to GND
  */

#include <Wire.h>


// The seven-bit device address for EEPROMs
// I'll define it here rather than hard-code it inside all of the
// functions.
//
const byte DEVADDR = 0x50;

void setup()
{
   
    Wire.begin();
    Serial.begin(9600);
eeprom_write_byte( DEVADDR, 0, 0xAB );
    Serial.println("Memory written");
    delay(2000);

}

void loop()
{
   byte b = eeprom_read_byte(DEVADDR, 0);
        Serial.println(b, HEX);
         delay(2000);
   
}

void eeprom_write_byte(byte deviceaddress, int eeaddress, byte data)
{
    // Three lsb of Device address byte are bits 8-10 of eeaddress
    byte devaddr = deviceaddress | ((eeaddress >> 8) & 0x07);
    byte addr    = eeaddress;
    Wire.beginTransmission(devaddr);
    Wire.write(int(addr));
    Wire.write(int(data));
    Wire.endTransmission();
    delay(10);
}

  // Pages are blocks of 16 bytes, starting at 0x000.
  // That is, pages start at 0x000, 0x010, 0x020, ...
  // For a device "page write", the last byte must be
  // on the same page as the first byte.
  //
  // No checking is done in this routine.
  //
  // TODO: Do some checking, or, better yet (maybe)
  // make length an int and do repeated device
  // page writes if necessary. (Then maybe rename to
  // eeprom_write_pages or some such thing.)
  //
void eeprom_write_page(byte deviceaddress, unsigned eeaddr,
                       const byte * data, byte length)
{
    // Three lsb of Device address byte are bits 8-10 of eeaddress
    byte devaddr = deviceaddress | ((eeaddr >> 8) & 0x07);
    byte addr    = eeaddr;
    Wire.beginTransmission(devaddr);
    Wire.write(int(addr));
    for (int i = 0; i < length; i++) {
        Wire.write(data[i]);
    }
    Wire.endTransmission();
    delay(10);
}

// TODO: Change to integer data type and return -1 if can't
// read.
//
int eeprom_read_byte(byte deviceaddress, unsigned eeaddr)
{
    byte rdata = -1;

    // Three lsb of Device address byte are bits 8-10 of eeaddress
    byte devaddr = deviceaddress | ((eeaddr >> 8) & 0x07);
    byte addr    = eeaddr;

    Wire.beginTransmission(devaddr);
    Wire.write(int(addr));
    Wire.endTransmission();
    Wire.requestFrom(int(devaddr), 1);
    if (Wire.available()) {
        rdata = Wire.read();
    }
    return rdata;
}

//
// Returns number of bytes read from device
//
// Due to buffer size in the Wire library, don't read more than 30 bytes
// at a time!  No checking is done in this function.
//
// TODO: Change length to int and make it so that it does repeated
// EEPROM reads for length greater than 30.

int eeprom_read_buffer(byte deviceaddr, unsigned eeaddr,
                        byte * buffer, byte length)
{
    // Three lsb of Device address byte are bits 8-10 of eeaddress
    byte devaddr = deviceaddr | ((eeaddr >> 8) & 0x07);
    byte addr    = eeaddr;
   
    Wire.beginTransmission(devaddr);
    Wire.write(int(addr));
    Wire.endTransmission();

    Wire.requestFrom(devaddr, length);
    int i;
    for (i = 0; i < length && Wire.available(); i++) {
        buffer[i] = Wire.read();
    }
    return i;
}

//
// The display is like hexdump -C.  It will always
// begin and end on a 16-byte boundary.
//

void eeprom_dump(byte devaddr, unsigned addr, unsigned length)
{
    // Start with the beginning of 16-bit page that contains the first byte
    unsigned startaddr = addr & (~0x0f);

    // stopaddr is address of next page after the last byte
    unsigned stopaddr  = (addr + length + 0x0f) & (~0x0f);

    for (unsigned i = startaddr; i < stopaddr; i += 16) {
        byte buffer[16]; // Hold a page of EEPROM
        char outbuf[6];  //Room for three hex digits and ':' and ' ' and '\0'
        sprintf(outbuf, "%03x: ", i);
        Serial.print(outbuf);
        eeprom_read_buffer(devaddr, i, buffer, 16);
        for (int j = 0; j < 16; j++) {
            if (j == 8) {
                Serial.print(" ");
            }
            sprintf(outbuf, "%02x ", buffer[j]);
            Serial.print(outbuf);           
        }
        Serial.print(" |");
        for (int j = 0; j < 16; j++) {
            if (isprint(buffer[j])) {
                Serial.print(buffer[j]);
            }
            else {
                Serial.print('.');
            }
        }
        Serial.println("|");
    }
}



Il codice l'ho preso da internet era relativo ad un 24c16 che dovrebbe essere simile (dimensione minore a parte).
I collegamenti tra arduino e la eeprom sono effettuati come scritto sul codice un dubbio mi è venuto sull'indirizzo, il codice di esempio scriveva 0x51 ma in realtà da datasheet dovrebbe essere 0x50 con quei collegamenti, ho provato comunque in entrambi i modi ma ottengo sempre lo stesso risultato.
Grazie.

nid69ita

Comunica con I2C, vero?

Cerca i2c_scanner, con quello scaricato su Arduino ti trova tutti gli indirizzi dei dispositivi I2C collegati, così sei sicuro.
my name is IGOR, not AIGOR

zuzzuz

mmmm ottengo questo
Code: [Select]
I2C Scanner
Scanning...
I2C device found at address 0x50  !
I2C device found at address 0x51  !
I2C device found at address 0x52  !
I2C device found at address 0x53  !
done

zuzzuz

ok, avevo invertito sda e scl per sbaglio  :smiley-red:
Adesso riesco a scrivere in maniera esatta.
Un ultima domanda, questa eeprom dovrebbe avere 8k bit di memoria disponibile.
Da datasheet c'è scritto che i dati sono divisi in 1024 celle da 8 bit o anche  64 pages da 16 bytes non mi è chiaro cosa sono le "pages" .

leo72


Un ultima domanda, questa eeprom dovrebbe avere 8k bit di memoria disponibile.
Da datasheet c'è scritto che i dati sono divisi in 1024 celle da 8 bit o anche  64 pages da 16 bytes non mi è chiaro cosa sono le "pages" .

Puoi indirizzare la memoria sia a singole celle che a pagine. Nel primo caso, passi l'indirizzo e il valore da memorizzare e la circuiteria della memoria salva il dato dove tu gli hai detto. Per spedire 64 byte, devi fare 64 invii separati. Quindi se per scrivere un dato il tempo di scrittura è x, per scrivere 64 byte il tempo di scrittura è minimo x*64.
Nel secondo, la circuiteria accetta l'indirizzo della pagina e poi tutti i dati da scrivere, che salverà in un'unica operazione.

PS:
perché hai preso una EEPROM esterna da solo 1K? L'Atmega328 dell'Arduino già integra 1K di EEPROM sul chip per cui avresti potuto usare quella. Visto quanto costano, prendi un 24C256 o un 24C512, sono 32/64KB di spazio.

zuzzuz

grazie sei stato molto chiaro.
Non l'ho comprata ce l'avevo in un altro circuito che non utilizzavo, per iniziare uso questa per un progetto definitivo comprerò magari qualcosa di meglio.

testato

grazie leo per la spiegazione,
la eeprom interna non supporta il page mode giusto ?
Quote
Table 7-1. EEPROM Mode Bits
EEPM1 EEPM0
Programming
Time Operation
0 0 3.4 ms Erase and Write in one operation (Atomic Operation)
0 1 1.8 ms Erase Only
1 0 1.8 ms Write Only
1 1 - Reserved for future use
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

leo72

non mi pare, ma vado a memoria

Go Up