Pages: [1]   Go Down
Author Topic: eeprom i2c [solucionado]  (Read 1332 times)
0 Members and 1 Guest are viewing this topic.
Madrid
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Pues resulta que tengo una memoria eeprom como esta


en el arduino he cargado el siguiente código y no va, me devuelve FF. Creo que no está en write protected y que escribe bien, no se si igual esta el circuito mal o el codigo tiene error, pero en principio no se me ocurre que puede ser... igual es por muerte de sueño o algo, el circuito esta tal que asi

circuito corregido (explicacion de pullup abajo)
 
y el código es este:
IMPORTANTE EL DELAY
Code:
#include <Wire.h>         //  EEPROM 24LC256, bibliotecas i2c
#define eeprom 0x50    // direccion de la eeprom shift

void setup(void){
  Wire.begin();           // Iniciar i2c
  Serial.begin(9600); // serial

  unsigned int address = 0;
  Serial.println("escribimos 33 en los 10 primeros bytes!");
  for(address = 0; address<10; address++) writeEEPROM(eeprom, address, '3');   // escribimos los 10 primeros bytes con 33
  Serial.println("Vamos leer si esta todo ok, debes ver 33, 33, 33, 33... 10 veces 33");

  for(address = 0; address<10; address++) {
  Serial.print(readEEPROM(eeprom, address), HEX); //aqui me falla y da FF
     Serial.print(", ");
  }
}

void loop(){
}



void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) {
  delay(5);
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));   // MSB
  Wire.send((int)(eeaddress & 0xFF)); // LSB
  Wire.send(data);
  Wire.endTransmission();
}

byte readEEPROM(int deviceaddress, unsigned int eeaddress ) {
  delay(5);
  byte rdata = 0xFF;
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));   // MSB
  Wire.send((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.receive();
  return rdata;
}

editado:


La resistencia correcta para el pullup en un bus I2C depende de la capacitancia del bus y de la frecuencia de operación del mismo.

la formula extraida del datasheet del ATmega168 (no se si deriva de las especificaciones de I2C) es

Freq < 100KHz Rmin = (Vcc - 0.4V) / 3mA Rmax = 1000nS / Cbus

Freq > 100KHz Rmin = (Vcc - 0.4V) / 3mA Rmax = 300nS / Cbus

La EEPROM "Microchip 24LC256" specifica una capacitancia máxima por pin de 10pF .

Si utilizas alimentación por baterias es preferible utilizar resistencias que se aproximen a lo mas alto del rango. Si no existen limitaciones de consumo es preferible usar las más bajas.

parece ser que una configuración típica es 10 kΩ para 100 kHz, 2 kΩ para 400 kHz y 1 MHz.
« Last Edit: September 27, 2011, 09:31:42 am by Zid_ » Logged

Ciudad Real
Offline Offline
God Member
*****
Karma: 1
Posts: 747
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

que memoria tienes ?

una 24lc16 no se lee y escribe igual que una 24lc32

un saludo
Logged

Madriz
Offline Offline
Full Member
***
Karma: 0
Posts: 176
Glober Arduiner
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
for(address = 0; address<10; address++) writeEEPROM(eeprom, address, '3');


creo que le estás pasando 3 como string, quitale las comillas


Edit: me he colado, es un char.
« Last Edit: September 27, 2011, 01:35:27 am by aero_yo » Logged

Madrid
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

que memoria tienes ?

una 24lc16 no se lee y escribe igual que una 24lc32

un saludo

es una 24LC256
Logged

Ciudad Real
Offline Offline
God Member
*****
Karma: 1
Posts: 747
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

revisa el montaje, creo que has cogido los pines 4 y 5 de los digitales, el BUS I2C son el 4 y el 5 analógicos, A4 (SDA) y A5 (SCL)

Un saludo ¡
Logged

Madrid
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ala que mal! muchas gracias, en cuanto vuelva a casa lo miro, pero va a ser eso seguro. Muchas gracias!
Logged

Venezuela
Offline Offline
Full Member
***
Karma: 0
Posts: 124
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola buenos dias, una cosa a tomar en cuenta es que en el protocolo I2C hay que colocar resistencias pull-up.
Revisa eso y nos comentas.

Saludos.
Logged

Madrid
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

cierto, no tenia conocimiento, para los que lean esto en un futuro, esto he podido averiguar:

La resistencia correcta para el pullup en un bus I2C depende de la capacitancia del bus y de la frecuencia de operación del mismo.

la formula extraida del datasheet del ATmega168 (no se si deriva de las especificaciones de I2C) es

Freq < 100KHz Rmin = (Vcc - 0.4V) / 3mA Rmax = 1000nS / Cbus

Freq > 100KHz Rmin = (Vcc - 0.4V) / 3mA Rmax = 300nS / Cbus

La EEPROM "Microchip 24LC256" specifica una capacitancia máxima por pin de 10pF .

Si utilizas alimentación por baterias es preferible utilizar resistencias que se aproximen a lo mas alto del rango. Si no existen limitaciones de consumo es preferible usar las más bajas.

parece ser que una configuración típica es 10 kΩ para 100 kHz, 2 kΩ para 400 kHz y 1 MHz.

Logged

Madrid
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

sigue fallando ahora el output es:

escribimos 33 en los 10 primeros bytes!
Vamos leer si esta todo ok, debes ver 33, 33, 33, 33... 10 veces 33
33, FF, FF, FF, FF, FF, FF, FF, FF, FF,
Logged

Ciudad Real
Offline Offline
God Member
*****
Karma: 1
Posts: 747
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

segun la que utilizo yo hay un delay de 5 milis antes de leer de la memoria

te pongo el codigo que he utilizado yo hasta ahroa

un saludo

Code:

24LC512 I2C EEPROM Driver

A simple example of interfacing with the 24LC512 I2C EEPROM.

With just two pins, 3.3V and ground and no other electronics, the following sketch will interface with an I2C EEPROM, reading and writing bytes and ints.

It builds on the work of others (wayoda and JohnZero) whilst cutting the cruft. (It was my experience that the paging didn't work as hoped and that, without the delays, reading & writing was unreliable.) More details and data types to follow.

#include <Wire.h>

const int theDeviceAddress = 80;

void setup(void) {
  Serial.begin(9600);
  Wire.begin();
}

void loop(void) {
  for (unsigned int theMemoryAddress = 0; theMemoryAddress < 256; theMemoryAddress++) {
    WireEepromWriteByte(theDeviceAddress, theMemoryAddress, (byte)theMemoryAddress);
  }
  for (unsigned int theMemoryAddress = 0; theMemoryAddress < 256; theMemoryAddress++) {
    Serial.print("Byte: ");
    Serial.print(theMemoryAddress);
    Serial.print(", ");
    Serial.print((int)WireEepromReadByte(theDeviceAddress, theMemoryAddress));
    Serial.println(".");
  }
  for (unsigned int theMemoryAddress = 0; theMemoryAddress < 1024; theMemoryAddress++) {
   WireEepromWriteInt(theDeviceAddress, theMemoryAddress * 2, (int)theMemoryAddress);
   }
   for (unsigned int theMemoryAddress = 0; theMemoryAddress < 1024; theMemoryAddress++) {
   Serial.print("Int: ");
   Serial.print(theMemoryAddress);
   Serial.print(", ");
   Serial.print(WireEepromReadInt(theDeviceAddress, theMemoryAddress * 2));
   Serial.println(".");
   }
}

void WireEepromRead(int theDeviceAddress, unsigned int theMemoryAddress, int theByteCount, byte* theByteArray) {
  for (int theByteIndex = 0; theByteIndex < theByteCount; theByteIndex++) {
    Wire.beginTransmission(theDeviceAddress);
    Wire.send((byte)((theMemoryAddress + theByteIndex) >> 8));
    Wire.send((byte)((theMemoryAddress + theByteIndex) >> 0));
    Wire.endTransmission();
    delay(5);
    Wire.requestFrom(theDeviceAddress, sizeof(byte));
    theByteArray[theByteIndex] = Wire.receive();
  }
}

byte WireEepromReadByte(int theDeviceAddress, unsigned int theMemoryAddress) {
  byte theByteArray[sizeof(byte)];
  WireEepromRead(theDeviceAddress, theMemoryAddress, sizeof(byte), theByteArray);
  return (byte)(((theByteArray[0] << 0)));
}

int WireEepromReadInt(int theDeviceAddress, unsigned int theMemoryAddress) {
  byte theByteArray[sizeof(int)];
  WireEepromRead(theDeviceAddress, theMemoryAddress, sizeof(int), theByteArray);
  return (int)(((theByteArray[0] << 8)) | (int)((theByteArray[1] << 0)));
}

void WireEepromWrite(int theDeviceAddress, unsigned int theMemoryAddress, int theByteCount, byte* theByteArray) {
  for (int theByteIndex = 0; theByteIndex < theByteCount; theByteIndex++) {
    Wire.beginTransmission(theDeviceAddress);
    Wire.send((byte)((theMemoryAddress + theByteIndex) >> 8));
    Wire.send((byte)((theMemoryAddress + theByteIndex) >> 0));
    Wire.send(theByteArray[theByteIndex]);
    Wire.endTransmission();
    delay(5);
  }
}

void WireEepromWriteByte(int theDeviceAddress, unsigned int theMemoryAddress, byte theByte) {
  byte theByteArray[sizeof(byte)] = {(byte)(theByte >> 0)};
  WireEepromWrite(theDeviceAddress, theMemoryAddress, sizeof(byte), theByteArray);
}

void WireEepromWriteInt(int theDeviceAddress, unsigned int theMemoryAddress, int theInt) {
  byte theByteArray[sizeof(int)] = {(byte)(theInt >> 8), (byte)(theInt >> 0)};
  WireEepromWrite(theDeviceAddress, theMemoryAddress, sizeof(int), theByteArray);
}


Modifico para que se vea el código bien.

Un saludo, me alegro que se solucione.
« Last Edit: September 27, 2011, 09:48:57 am by SrDonGato » Logged

Madrid
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Mil gracias! le he introducido el delay y ahora va perfecto, actualizo el código.
Logged

Pages: [1]   Go Up
Jump to: