Problema ao ler um chip EEPROM usando o protocolo I2C

Estou tentando ler um chip EEPROM que suporta o protocolo I2C (não é possível informar o número do modelo do IC, pois ele não é impresso). Com certeza ele suporta o protocolo I2C, já que eu escrevi um código para detectá-lo usando a biblioteca I2C e o endereço do dispositivo que eu obtive é 0x51 . Agora estou tentando escrever um código que lê dados deste chip IC. O código é o seguinte:

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

O problema que estou enfrentando é, eu recebo de volta o endereço (do qual eu quero ler os dados) como os dados em si (por exemplo, read (0) retorna 0, read (1) retorna 1 e assim por diante). Eu até tentei depurar a comunicação I2C usando o analisador lógico (lógica Saleae neste caso). Uma captura de tela é mostrada abaixo.

enter image description here

A captura de tela mostra a lógica de uma operação de leitura de um único endereço (0x78), mas a história é válida para todos os endereços, por exemplo, recebo o endereço em vez dos dados do endereço.

A saída do código acima é a seguinte:

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
  rodada completa </​​p>

Você pode me ajudar a identificar o que possivelmente estou fazendo de errado aqui?

Obrigado.

1
@MikaelPatel: Vou tentar um endereço de 16 bits e informar quais são os resultados.
adicionado o autor mcrumley, fonte
@NickGammon: Apenas para garantir que o conteúdo não seja 0x00, 0x01, etc. Tentei executar uma operação de gravação no chip. Mas o resultado da leitura depois de uma gravação permanece o mesmo. Talvez eu tenha que tentar usar endereços de 16 bits como você sugeriu também.
adicionado o autor mcrumley, fonte
@NickGammon: Eu tentei usar os endereços de 16 bits, mas sem sucesso. Os dados que recebi em retorno são todos zeros. Talvez porque agora eu estou recebendo de volta os primeiros 8 bits que estou escrevendo, ou seja, 0x00. Eu também estava olhando para a biblioteca I2c que você sugeriu em seu blog. dsscircuits.com/articles/arduino-i2c-master-library . Você pode me ajudar a entender, o que exatamente é registerAddress aqui? É usado em muitas funções desta biblioteca, for.e.g.I2c.write (endereço, registerAddress, * data, numberBytes). Obrigado!
adicionado o autor mcrumley, fonte
Ahh, certo. Eu estava fazendo um projeto de engenharia reversa e o chip é na verdade um COB. Eu tenho que então decapitá-lo de alguma forma e ver por baixo. Obrigado de qualquer forma.
adicionado o autor mcrumley, fonte
Quantas pernas (pinos) o chip tem?
adicionado o autor Nick Gammon, fonte
Eu também concordo com o Mikael, você poderia tentar enviar um endereço de 16 bits. Por exemplo, envie um zero primeiro e depois um endereço. Em qualquer caso, você pode ter certeza de que o chip não possui 0x00, 0x01, etc. dentro de sua memória?
adicionado o autor Nick Gammon, fonte
Depende do dispositivo, mas alguns têm um registro em que escrever algo para ele faz com que os bits internos sejam configurados. Honestamente, tentar ajudar a escrever/ler de um dispositivo desconhecido é quase impossível. Por US $ 5 você poderia comprar um chip que você sabe o número de peça e pode obter a folha de dados para.
adicionado o autor Nick Gammon, fonte
Que tal usar um endereço de 16 bits? Aqui está um link para um driver que escrevi para Cosa; github.com/mikaelpatel/Cosa/blob/master/libraries/ AT24CXX/& hellip;
adicionado o autor Mikael Patel, fonte

3 Respostas

Você precisa passar o endereço como dois bytes, um por um.

Não faça:

Wire.write(address);

Pelo contrário, faça:

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

Em suma, você deve dividir

Wire.write(address);

para dentro

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

Eu estou usando a versão de 1Mb e usa 0x51 e 0x50 porque tem duas páginas. Eu suspeito que você vai encontrar o seu chip, pelo menos, ser semelhante por causa do endereço I2C que você listou. Você pode ter uma versão menor do mesmo chip que usa apenas o endereço.

1
adicionado

Sem as informações específicas do chip, isso será difícil.

No entanto, minha experiência com EEPROMs e I2C é que a primeira ação é escrever um comando, depois escrever o (s) parâmetro (s) para esse comando e ler a resposta.

Muitas vezes, há um registro de status na EEPROM que precisa ser lido (escrevendo um comando e depois lendo a resposta) para determinar se a EEPROM está pronta para receber um comando diferente, como escrever para definir o endereço para uma leitura/ou/write, em seguida, o comando de leitura real.

0
adicionado