Проблема читання мікросхеми EEPROM за допомогою протоколу I2C

Я намагаюся прочитати мікросхему EEPROM, яка підтримує протокол I2C (неможливо вказати номер моделі IC, оскільки він не друкується). Напевно, він підтримує протокол I2C, оскільки я написав код для виявлення його за допомогою бібліотеки I2C, а адреса пристрою, яку я отримав, - 0x51 . Тепер я намагаюся написати код, який читає дані з цього IC-чіпа. Код виглядає наступним чином:

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

Проблема, з якою я стикаюсь, полягає в тому, що я повернув адресу (з якої я хочу прочитати дані) як самі дані (наприклад, читати (0) повертає 0, читати (1) повертає 1 і так далі). Я навіть намагався налагодити зв'язок I2C за допомогою логічного аналізатора (логіка Sellale у цьому випадку). Знімок екрана показано нижче.

enter image description here

На знімку екрана показано логіку операції читання з однієї адреси (0x78), але історія зберігається для кожної адреси, тобто я повертаю адресу замість даних з адреси.

Вихід вищезазначеного коду виглядає наступним чином:

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
  круглий комплект

Ви можете допомогти мені визначити, що я можу робити тут неправильно?

Дякую.

1
@MikaelPatel: Я спробую з 16-розрядною адресою і дам вам знати, які результати є.
додано Автор mcrumley, джерело
@NickGammon: щоб переконатися, що вміст не 0x00, 0x01 тощо, я намагався виконати операцію запису на чіпі. Але результат для читання після написання залишається незмінним. Може бути, я повинен спробувати використовувати 16-бітні адреси, як ви запропонували, а також.
додано Автор mcrumley, джерело
@NickGammon: Я спробував використати 16-розрядні адреси, але не маю успіху. Дані, які я отримав у зворотному порядку, - це всі нулі. Можливо, тому що зараз я повертаю перші 8 бітів, які я пишу, тобто 0x00. Я також дивився на бібліотеку I2c, яку ви запропонували у своєму блозі. dsscircuits.com/articles/arduino-i2c-master-library . Чи можете ви допомогти мені у розумінні, що таке registerAddress тут? Його використовують у багатьох функціях цієї бібліотеки, для.e.g.I2c.write (адреса, registerAddress, * data, numberBytes). Дякую!
додано Автор mcrumley, джерело
Ах ОК. Я виконував проект зворотного інжинірингу, і чіп насправді є COB. Я повинен тоді депакувати це як-небудь і побачити внизу. Спасибі в будь-якому випадку.
додано Автор mcrumley, джерело
Скільки ножів (штифтів) робить чіп?
додано Автор Nick Gammon, джерело
Я також згоден з Мікаелем, ви можете спробувати надіслати 16-розрядну адресу. Наприклад, спочатку відправте нуль, а потім адресу. У будь-якому випадку, чи можете ви бути впевнені, що в чіпі немає 0x00, 0x01 тощо всередині його пам'яті?
додано Автор Nick Gammon, джерело
Це залежить від пристрою, але деякі мають реєстр, де щось писати, викликає внутрішні біти. Чесно кажучи, спробу допомогти писати/читати з невідомого пристрою майже неможливо. За 5 доларів ви можете придбати чіп, який ви знаєте, номер деталі і можете отримати таблицю.
додано Автор Nick Gammon, джерело
Як щодо використання 16-розрядної адреси? Ось посилання на драйвер, який я написав для Кози; github.com/mikaelpatel/Cosa/blob/master/libraries/ AT24CXX/& hellip;
додано Автор Mikael Patel, джерело

3 Відповіді

Потрібно вказати адресу як два байти, один за іншим.

Не роби:

Wire.write(address);

Скоріше:

Wire.write((uint8_t)(address >> 8));//MSB
Wire.write((uint8_t)(address & 0xFF));//LSB
2
додано

Словом, ви повинні розділити

Wire.write(address);

в

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

Я використовую версію 1Mb, і вона використовує 0x51 та 0x50, оскільки вона має дві сторінки. Я підозрюю, що ви знайдете свій чіп, щоб принаймні бути подібним через вказану вами адресу I2C. У вас може бути менша версія того самого чіпа, який використовує лише одну адресу.

1
додано

Без конкретної інформації про чіп це буде важко.

Проте мій досвід роботи з EEPROM і I2C полягає в тому, що перша дія полягає у написанні команди, потім напишіть параметри (-и) для цієї команди, а потім прочитайте відповідь.

Нерідко у EEPROM-модулі є реєстр стану, який потрібно прочитати (написавши команду, а потім прочитавши відповідь), щоб визначити, чи є EEPROM готовий отримати іншу команду, як написання, щоб встановити адресу для read/or/write, тоді фактична команда read.

0
додано