Probleem bij het lezen van een EEPROM-chip met behulp van het I2C-protocol

Ik probeer een EEPROM-chip te lezen die het I2C protocol ondersteunt (kan het IC-modelnummer niet vertellen omdat het niet wordt afgedrukt). Het ondersteunt zeker het I2C-protocol, omdat ik een code heb geschreven om het te detecteren met behulp van de I2C-bibliotheek en het adres van het apparaat dat ik heb ontvangen, is 0x51 . Nu probeer ik een code te schrijven die gegevens van deze IC-chip leest. De code is als volgt:

#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
}

Het probleem dat ik tegenkom is, ik krijg het adres terug (waarvan ik de gegevens wil lezen) als de gegevens zelf (voor bijvoorbeeld lezen (0) levert 0 op, leest (1) levert 1 op enzovoort). Ik probeerde zelfs de I2C-communicatie te debuggen met behulp van de logische analysator (in dit geval de Saleae-logica). Een screenshot wordt hieronder getoond.

enter image description here

Het screenshot toont de logica voor een leesbewerking vanaf een enkel adres (0x78), maar het verhaal geldt voor elk adres, d.w.z. ik krijg het adres terug in plaats van de gegevens van het adres.

De uitvoer van de bovenstaande code is als volgt:

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
  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
  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
  ronde voltooid

Kun je me helpen om te identificeren wat ik hier verkeerd doe?

Bedankt.

1
@MikaelPatel: Ik zal het proberen met een 16-bits adres en laten weten wat de resultaten zijn.
toegevoegd de auteur mcrumley, de bron
@NickGammon: om er zeker van te zijn dat de inhoud niet 0x00, 0x01, etc. is, probeerde ik een schrijfbewerking uit te voeren op de chip. Maar het resultaat voor het lezen na een schrijven, blijft hetzelfde. Misschien moet ik proberen 16-bit-adressen te gebruiken zoals je ook hebt gesuggereerd.
toegevoegd de auteur mcrumley, de bron
@NickGammon: ik heb geprobeerd de 16-bits adressen te gebruiken, maar zonder succes. De gegevens die ik daarvoor terugkrijg zijn allemaal nullen. Misschien omdat ik nu de eerste 8 bits terughaal die ik aan het schrijven ben, d.w.z. 0x00. Ik keek ook naar de I2c-bibliotheek die je in je blog hebt voorgesteld. dsscircuits.com/articles/arduino-i2c-master-library . Kun je me helpen bij het begrijpen, wat is hier precies registerAddress? Het wordt gebruikt in veel functies van deze bibliotheek, voor.e.g.I2c.write (adres, registerAddress, * data, numberBytes). Bedankt!
toegevoegd de auteur mcrumley, de bron
Ahh OK. Ik deed een reverse engineering-project en de chip is in feite een COB. Ik moet het op de een of andere manier decaperen en eronder zien. In ieder geval bedankt.
toegevoegd de auteur mcrumley, de bron
Hoeveel poten heeft de chip?
toegevoegd de auteur Nick Gammon, de bron
Ik ben het ook met Mikael eens, je zou kunnen proberen een 16-bits adres te sturen. Stuur bijvoorbeeld eerst een nul en vervolgens een adres. Kan je er in elk geval zeker van zijn dat de chip niet 0x00, 0x01, enz. In zijn geheugen heeft?
toegevoegd de auteur Nick Gammon, de bron
Het hangt af van het apparaat, maar sommige hebben een register waar het schrijven van iets naar toe leidt dat interne bits worden ingesteld. Eerlijk gezegd is het bijna onmogelijk om te proberen te schrijven naar/lezen van een onbekend apparaat. Voor $ 5 kun je een chip kopen waarvan je het artikelnummer weet en waarvoor je de datasheet kunt krijgen.
toegevoegd de auteur Nick Gammon, de bron
Hoe zit het met het gebruik van een 16-bits adres? Hier is een link naar een stuurprogramma dat ik heb geschreven voor Cosa; github.com/mikaelpatel/Cosa/blob/master/libraries/ AT24CXX/& hellip;
toegevoegd de auteur Mikael Patel, de bron

3 antwoord

U moet het adres één voor één doorgeven als twee bytes.

Doe niet:

Wire.write(address);

Integendeel:

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

Kortom, je zou moeten splitsen

Wire.write(address);

in

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

Ik gebruik de 1Mb-versie en deze gebruikt 0x51 en 0x50 omdat deze uit twee pagina's bestaat. Ik vermoed dat je je chip op zijn minst vergelijkbaar vindt vanwege het I2C-adres dat je hebt vermeld. Mogelijk hebt u een kleinere versie van dezelfde chip die alleen het ene adres gebruikt.

1
toegevoegd

Zonder de specifieke chipinformatie zal dit moeilijk zijn.

Mijn ervaring met EEPROMs en I2C is echter dat de eerste actie het schrijven van een opdracht is, vervolgens de parameter (s) voor die opdracht schrijven en vervolgens het antwoord lezen.

Vaak is er een statusregister in de EEPROM dat moet worden gelezen (door een opdracht te schrijven en vervolgens het antwoord te lezen) om te bepalen of de EEPROM klaar is om een ​​andere opdracht te ontvangen, zoals schrijven om het adres in te stellen voor een gelezen/of/write, dan is het daadwerkelijke leescommando.

0
toegevoegd