Problema citește un cip EEPROM utilizând protocolul I2C

Încerc să citesc un cip EEPROM care acceptă protocolul I2C (nu poate spune numărul modelului IC deoarece nu este tipărit). Sigur că acceptă protocolul I2C, deoarece am scris un cod pentru a-l detecta folosind biblioteca I2C și adresa dispozitivului pe care am primit-o este 0x51 . Acum încerc să scriu un cod care citește date de pe acest chip IC. Codul este după cum urmează:

#include 

int addr = 0;

void setup() {
    Wire.begin();//initialise the connection
    Serial.begin(9600);
    while (!Serial) {}
    delay(100);
}

void loop() {
  byte deviceAddress = 0x51;
  byte data = readData(addr, deviceAddress);
  Serial.print(data, HEX);
  Serial.print(" ");
  addr++;
  if(addr%16 == 0) {
     Serial.print('\n');
  }
 //check for 1Kbits first
  if (addr%128 == 0) {
     Serial.println("round complete");
     Serial.println();
     addr = 0;
  }
  delay(100);
}

byte readData(int address, int deviceAddress) {
 //sending device address
  Wire.beginTransmission(deviceAddress);
  Wire.write(address);
  Wire.endTransmission();
  Wire.requestFrom((short int)deviceAddress, 1);
  if(Wire.available()) {
    byte data = Wire.read();
    return data;  
  }
  return 0xAA;//random data
}

Problema cu care mă confruntă este că recuperez adresa (din care vreau să citesc datele) ca datele în sine (de exemplu, citit (0) returnează 0, citește (1) returnează 1 și așa mai departe). Am încercat chiar să depanez comunicarea I2C utilizând analizorul logic (logica Saleae în acest caz). O captură de ecran este prezentată mai jos.

enter image description here

Imaginea de ecran afișează logica pentru o operație de citire dintr-o singură adresă (0x78), dar povestea este valabilă pentru fiecare adresă, adică primesc adresa în loc de date de la adresă.

Rezultatul codului de mai sus este următorul:

0 1 2 3 4 5 6 7 8 9 A B C D E F   10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 1   20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F   30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F   40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 4   50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F   60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F   70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F   rotund complet

Poți să mă ajuți la identificarea a ceea ce fac, probabil, greșit aici?

Mulțumiri.

1
@MikaelPatel: Voi da o încercare cu adresa pe 16 biți și vă informez ce rezultate sunt.
adăugat autor mcrumley, sursa
@NickGammon: Doar pentru a vă asigura că conținutul nu este 0x00, 0x01, etc. Am încercat să efectuez o operație de scriere la chip. Dar rezultatul citirii după scriere rămâne același. Poate că trebuie să încerc să folosesc adrese pe 16 biți așa cum ați sugerat de asemenea.
adăugat autor mcrumley, sursa
@NickGammon: Am încercat să folosesc adresele de 16 biți, dar fără succes. Datele pe care le primesc în schimb sunt toate zerouri. Poate pentru că acum recuperez primele 8 biți pe care le scriu, adică 0x00. De asemenea, m-am uitat la biblioteca I2c pe care ați sugerat-o în blogul dvs. dsscircuits.com/articles/arduino-i2c-master-library . Puteți să mă ajuți să înțeleg, ce anume este înregistrarea aici? Se folosește în multe funcții ale acestei biblioteci, de exemplu: I2c.write (adresa, registerAddress, * data, numberBytes). Mulțumiri!
adăugat autor mcrumley, sursa
Ahh bine. Am făcut un proiect de inginerie inversă și cipul este de fapt un COB. Trebuie să-l decap oarecum și să văd dedesubt. Mulțumesc oricum.
adăugat autor mcrumley, sursa
Câte picioare au chipul?
adăugat autor Nick Gammon, sursa
Sunt de acord și cu Mikael, puteți încerca să trimiteți o adresă pe 16 biți. De exemplu, trimiteți mai întâi un zero, apoi o adresă. În orice caz, puteți fi sigur că chipul nu se întâmplă să aibă 0x00, 0x01, etc. în memoria sa?
adăugat autor Nick Gammon, sursa
Depinde de dispozitiv, dar unii au un registru în care scris ceva pentru a face ca biții interne să fie stabilite. Sincer, încercarea de a ajuta la scrierea/citirea de pe un dispozitiv necunoscut este aproape imposibilă. Pentru $ 5 ați putea cumpăra un cip pe care îl cunoașteți numărul piesei și puteți obține fișa tehnică pentru.
adăugat autor Nick Gammon, sursa
Ce zici de folosirea unei adrese pe 16 biți? Aici este o legătură cu un șofer pe care l-am scris pentru Cosa; AT24CXX/& hellip;
adăugat autor Mikael Patel, sursa

3 răspunsuri

Trebuie să treci adresa ca doi octeți, unul câte unul.

Nu fa:

Wire.write(address);

Mai degrabă, faceți:

Wire.write((uint8_t)(address >> 8));//MSB
Wire.write((uint8_t)(address & 0xFF));//LSB
2
adăugat

Pe scurt, ar trebui să vă despărțiți

Wire.write(address);

în

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

I am working on a similar project right now. I have searched through many different codes and libraries and found the following to work the best: https://playground.arduino.cc/Code/I2CEEPROM

I am using the 24LC1025 who's datasheet can be found here: http://www.microchip.com/datasheet/24LC1025

Folosesc versiunea 1Mb și utilizează 0x51 și 0x50 deoarece are două pagini. Bănuiesc că veți găsi cipul dvs. cel puțin să fie similar din cauza adresei I2C pe care ați enumerat-o. Este posibil să aveți o versiune mai mică a aceluiași cip care utilizează numai o singură adresă.

1
adăugat

Fără informații specifice despre chip, acest lucru va fi dificil.

Cu toate acestea, experiența mea cu EEPROM și I2C este că prima acțiune este de a scrie o comandă, apoi scrie parametrul (parametrii) pentru acea comandă, apoi citiți răspunsul.

Adesea, există un registru de stare în EEPROM care trebuie citit (prin scrierea unei comenzi și citirea răspunsului) pentru a determina dacă EEPROM este gata să primească o comandă diferită, cum ar fi scrierea pentru a seta adresa pentru o citire// write, apoi comanda reală de citire.

0
adăugat