مشكلة في قراءة شريحة 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 باستخدام محلل المنطق (منطق Saleae في هذه الحالة). تظهر لقطة الشاشة أدناه.

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 هنا؟ استخدامه في العديد من وظائف هذه المكتبة ، for.e.g.I2c.write (العنوان ، registerAddress ، * البيانات ، numberBytes). شكر!
وأضاف المؤلف mcrumley, مصدر
ااه حسنا. كنت أفعل مشروع هندسي عكسي والرقاقة هي في الواقع COB. لا بد لي من ثم decap على نحو ما ونرى تحتها. شكرا على اية حال.
وأضاف المؤلف mcrumley, مصدر
كم عدد الأرجل (الدبابيس) التي بها الرقاقة؟
وأضاف المؤلف Nick Gammon, مصدر
أتفق مع Mikael أيضًا ، يمكنك محاولة إرسال عنوان 16 بت. على سبيل المثال ، أرسل صفرًا أولاً ، ثم عنوانًا. في أي حال ، هل يمكن أن تكون على يقين من أن الشريحة لا يحدث أن يكون 0x00 ، 0x01 ، وما إلى ذلك داخل ذاكرتها؟
وأضاف المؤلف Nick Gammon, مصدر
يعتمد ذلك على الجهاز ، لكن البعض لديه سجل حيث تؤدي كتابة شيء إليه إلى تعيين أجزاء داخلية. بصراحة ، من المستحيل تقريباً محاولة المساعدة في الكتابة/القراءة من جهاز غير معروف. مقابل 5 دولارات ، يمكنك شراء شريحة تعرف رقم الجزء الخاص بها ويمكن الحصول على ورقة البيانات الخاصة بها.
وأضاف المؤلف Nick Gammon, مصدر
ماذا عن استخدام عنوان 16 بت؟ هنا رابط لسائق قمت بكتابته لـ Cosa ؛ 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 جاهزة لاستلام أمر مختلف ، مثل الكتابة لتعيين عنوان لقراءة/أو/الكتابة ، ثم الأمر القراءة الفعلية.

0
وأضاف