EEPROM 24LC512

Odpovědět
mato
Příspěvky: 49
Registrován: 18 říj 2019, 20:24
Reputation: 0

EEPROM 24LC512

Příspěvek od mato » 21 úno 2020, 15:13

Ahoj,
Prosím o radu ohledně zápisu a následného čtení dat z externí EEPROM 24LC512.
Níže uvedený kod jsem ořezal pro přehlednost na minimum.
V konečném výsledku to má fungovat tak,že na každou 20-tou adresu ukládám 19 znaků.
Jde mi o to proč, když takovýmto způsobem ukládám do paměti data,jde tedy o 19 znaků,
tak na adrese 100 je vše ještě v pořádku,ale od adresy 110 mi znaky od konce pustupně začínají chybět.
Můžete poradit kde mám chybu,resp. jak jí napravit???
Děkuji
M.

V tomto konkrétním příkladě mi chybí na konci 6 znaků....

Kód: Vybrat vše

#include <Wire.h>
// definování adresy EEPROM paměti,
#define eeprom 0x50
// vytvoření proměnné pro uložení zprávy do pole znaků
char zpravaChar[19];

void setup() {
  // zahájení komunikace po sériové lince rychlostí 9600 baud
  Serial.begin(9600);
  // zahájení komunikace po sběrnici I2C
  Wire.begin();
  //ukázková zpráva
  char zprava[19] = "ID01O1R319022018560";
  // zapsání vytvořené zprávy na zařízení eeprom, od adresy 115,
  // data z proměnné "zprava" o velikosti proměnné "zprava"
  eeprom_zapis_zpravu(eeprom, 115, zprava, sizeof(zprava));
  // krátká pauza po zápise
  delay(10);
  
  Serial.print("Cteni od adresy 115: ");
  // načtení zprávy ze zařízení eeprom, od adresy 115,
  // data uložíme do proměnné "zpravaChar" o velikosti proměnné "zpravaChar"
  eeprom_precti_zpravu(eeprom, 115, zpravaChar, sizeof(zpravaChar));
  // vytištění celé zprávy po sériové lince
  Serial.print(zpravaChar);
  Serial.println(" ");
}

void loop() {
  
}

// podprogram pro zapsání zprávy
void eeprom_zapis_zpravu( int adresaZarizeni, unsigned int adresaUlozeniZpravy, byte* data, byte delkaDat ) {
  Wire.beginTransmission(adresaZarizeni);
  Wire.write((int)(adresaUlozeniZpravy >> 8)); // MSB
  Wire.write((int)(adresaUlozeniZpravy & 0xFF)); // LSB
  byte c;
  for ( c = 0; c < delkaDat; c++)
    Wire.write(data[c]);
  Wire.endTransmission();
}

// podprogram pro přečtení zprávy 
void eeprom_precti_zpravu( int adresaZarizeni, unsigned int adresaCteni, byte *buffer, int delkaDat) {
  Wire.beginTransmission(adresaZarizeni);
  Wire.write((int)(adresaCteni >> 8)); // MSB
  Wire.write((int)(adresaCteni & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(adresaZarizeni,delkaDat);
  int c = 0;
  for ( c = 0; c < delkaDat; c++ )
    if (Wire.available()) buffer[c] = Wire.read();
}

Uživatelský avatar
gilhad
Příspěvky: 774
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: EEPROM 24LC512

Příspěvek od gilhad » 21 úno 2020, 15:32

Proste ti pretece stranka - 110+20=130 > 127 takze poslednich par bytu se ti zapise od zacatku te stranky
• 128-Byte Page Write Buffer
Note:
Page write operations are limited to writing
bytes within a single physical page,
regardless of the number of bytes
actually being written. Physical page
boundaries start at addresses that are
integer multiples of the page buffer size (or
‘page size’) and end at addresses that are
integer multiples of [page size – 1]. If a
Page Write command attempts to write
across a physical page boundary, the
result is that the data wraps around to the
beginning of the current page (overwriting
data previously stored there), instead of
being written to the next page as might be
expected. It is therefore necessary for the
application software to prevent page write
operations that would attempt to cross a
page boundary.

mato
Příspěvky: 49
Registrován: 18 říj 2019, 20:24
Reputation: 0

Re: EEPROM 24LC512

Příspěvek od mato » 21 úno 2020, 15:47

Ahaaa...,já měl takové tušení,že je někde nějaká hranice 128 Bytů,když jsem to přepočítával.
Takže jestli tomu dobře rozumím tak konkrétně tato pamět(24LC512) má nějakých 500 stránek,
kde do každé stránky můžu uložit max. 127 znaků..., je to tak???

Uživatelský avatar
gilhad
Příspěvky: 774
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: EEPROM 24LC512

Příspěvek od gilhad » 21 úno 2020, 16:18

do kazde stranky muzes ulozit 128 znaku - tedy obecne bytu, at uz znamenaji cokoli - (v ramci stranky cislovanych 0..127) a mas 64KB/128=512 stranek, cislovanych 0..511 - plus teda pomoci A0..A2 to muzes "posouvat" na 512..1023 atd. (proste prvni 3 bity adresy), takze z 8 takovychto pameti, paralelne spojenych (az na rozdilne nastavene A0..A2) muzes postavit jednu pamet adresovatelnou (a pouzitelnou) v rozsahu 512KB = 4Mb
The Microchip Technology Inc. 24AA512/24LC512/
24FC512 (24XX512*) is a 64K x 8 (512 Kbit) Serial
Electrically Erasable PROM, capable of operation
across a broad voltage range (1.7V to 5.5V).
This device is capable of both
random and sequential reads up to the 512K boundary.
Functional address lines (A0..A2) allow up to eight devices on
the same bus, for up to 4 Mbit address space.

mato
Příspěvky: 49
Registrován: 18 říj 2019, 20:24
Reputation: 0

Re: EEPROM 24LC512

Příspěvek od mato » 21 úno 2020, 17:24

Děkuji za vysvětlení....
Příznám se ,že s těmi bity bojuji.....
Tak to jsem si naivně myslel,jak cyklem For načtu z každé 20-té adresy 19 bajtů a ono se mi to
trošku zkomplikovalo :o .Jak to původně vypadalo jednoduše :roll:
Nebo na to existuje už nějaká funkce???
Prozatím bojuji s jednou pamětí potřeboval bych zapojit dvě.
Ještě k tomu čtení ze dvou. Samozřejmě nastavením A0...A2 určím adresu jedné nebo druhé paměti(0x50,0x51...) to tak nějak chápu,ale
přistupovat k jednotlivým datům na nich můžu u obou následně stejně. Takže i u druhé můžu začínat zapisovat/číst od adresy 0,pouze
určím s kterou pamětí chci zrovna pracovat..,je to tak?

Uživatelský avatar
gilhad
Příspěvky: 774
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: EEPROM 24LC512

Příspěvek od gilhad » 21 úno 2020, 18:15

Delej to tak, ze for cyklem tam budes psat jednotlive byty a kazdemu das predem adreu - pak to bude bez problemu

Kód: Vybrat vše

0 A
1 h
2 o
3 j
4 !
5 \0
......
Nebo si vtipne spocti, kde je hranice 128 a pokud to jde prez, tak to zapis jako dva bloky - prvni do 127, druhy od 128 ... (samozrejme totez u nasobku)

----

S tema A0..A2 je to naopak - proste kazde te pameti nastavis ty A0..A2 na spravne hodnoty natvrdo - pripajenim k zemi ci plusu - (000,001,010,...) a pak to pouzivas jako jednu velkou pamet, ktera ma proste vetsi rozsah adres - takze proste adresujes 00..64K-1,64K,64K+1 ... a ony uz si to preberou, se kterou z nich zrovna mluvis. Z pohledu programu to je proste jedna dlouhatanska pamet a neresi, ze se to sklada z vice obvodu.

Takze s prvnim chipem mluvis na adresach 0..64K-1, s druhym na adresach 64K..128K-1, s tretim na adresach 128K..192K-1 a tak dal. Otatni piny (krome A0..A2) pak ty chipy maji proste natvrdo propojene

mato
Příspěvky: 49
Registrován: 18 říj 2019, 20:24
Reputation: 0

Re: EEPROM 24LC512

Příspěvek od mato » 21 úno 2020, 19:11

Aaaa,tak to jsem uvažoval s A0....A2 špatně!!!
jo joo,tak jsem teď uvažoval,ale dávat to natvrdo je celkem peklo.
Potřebuji ukládat data dvou měsíců a jeden měsíc obsahuje cca 2000 adres a každá adresa obsahuje těch 19 znaků :roll:
Zkusil jsem jen letmo to ukládat(zadat) ručně a to tak, aby se mi to lépe počítalo(zaokrouhluji adresy na desítky bajtů),
ale potom to potřebuji ještě právě násobit 1x-15x.
Navíc UNO by mi asi kleklo na velikost projektu(dal bych MEGA,to není problém)
Původní záměr byl ten,že každý sudý měsíc budu ukládat na jednu pamět,každý lichý měsíc
na druhou.Každý další sudý/lichý měsíc bych ty původní přemazal novými daty.
Jooo člověk miní,život mění :D
Noo zkusím se s tím poprat.Alespoň už vím,že ta paměť má stránky :)
Děkuji za trpělivost!

mato
Příspěvky: 49
Registrován: 18 říj 2019, 20:24
Reputation: 0

Re: EEPROM 24LC512

Příspěvek od mato » 21 úno 2020, 21:42

Tak to vypadá,že jsem z toho vybruslil a celkem pohodlně i za pomoci cyklu For.
Alespoň prozatím s jednou pamětí,ale tu druhou snad už také dám.....
Děkuji gilhade za rady. Bez té informace existencí stránek, bych to nejspíš nedal....!!

Uživatelský avatar
gilhad
Příspěvky: 774
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: EEPROM 24LC512

Příspěvek od gilhad » 22 úno 2020, 03:01

ono ty datasheety se docela hodi cist :lol:

mato
Příspěvky: 49
Registrován: 18 říj 2019, 20:24
Reputation: 0

Re: EEPROM 24LC512

Příspěvek od mato » 22 úno 2020, 14:34

Tak to každopádně :) ,problém je spíš..
a)angličtina
b)člověk musí vědět co vůbec hledat :shock: ,a že jsem se fakt snažil hledat...!
ale to je už můj problém :roll:
Ohledně toho přístupu k dalším EEPROM-kám a použití A0....A2 jsem vycházel z tohoto příkladu....
Vždyť tady přeci na čtyřech pamětech zapisuje/vyhledává na stejné adrese......, na dalších eepromkách adresu nikam neposouvá....,
nebo zase vidím něco špatně???

Kód: Vybrat vše

#include "Wire.h"

#define EEPROM_I2C_ADDRESS0 0x50
#define EEPROM_I2C_ADDRESS1 0x51
#define EEPROM_I2C_ADDRESS2 0x52
#define EEPROM_I2C_ADDRESS3 0x53

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

  int address = 0;
  byte val0 = 110;
  byte val1 = 111;
  byte val2 = 112;
  byte val3 = 113;

  // Write and read from chip 0
  writeAddress(EEPROM_I2C_ADDRESS0, address, val0); 
  byte readVal = readAddress(EEPROM_I2C_ADDRESS0, address);
  
  Serial.print("The returned value is ");
  Serial.println(readVal);

  // Write and read from chip 1
  writeAddress(EEPROM_I2C_ADDRESS1, address, val1); 
  readVal = readAddress(EEPROM_I2C_ADDRESS1, address);  

  Serial.print("The returned value is ");
  Serial.println(readVal);  

  // Write and read from chip 2
  writeAddress(EEPROM_I2C_ADDRESS2, address, val2); 
  readVal = readAddress(EEPROM_I2C_ADDRESS2, address);  

  Serial.print("The returned value is ");
  Serial.println(readVal);

  // Write and read from chip 3
  writeAddress(EEPROM_I2C_ADDRESS3, address, val3); 
  readVal = readAddress(EEPROM_I2C_ADDRESS3, address);  

  Serial.print("The returned value is ");
  Serial.println(readVal);    

}

void loop() 
{

}

void writeAddress(byte i2cAddress, int address, byte val)
{
  Wire.beginTransmission(i2cAddress);
  Wire.write((int)(address >> 8));   // MSB
  Wire.write((int)(address & 0xFF)); // LSB
  
   
  Wire.write(val);
  Wire.endTransmission();

  delay(5);
}

byte readAddress(byte i2cAddress, int address)
{
  byte rData = 0xFF;
  
  Wire.beginTransmission(i2cAddress);
  
  Wire.write((int)(address >> 8));   // MSB
  Wire.write((int)(address & 0xFF)); // LSB
  Wire.endTransmission();  


  Wire.requestFrom(i2cAddress, 1);  

  rData =  Wire.read();

  return rData;
}


Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 2 hosti