I2C प्रोटोकॉल का उपयोग कर एक ईईपीरोम चिप पढ़ने में समस्या

मैं एक ईईपीरोम चिप पढ़ने की कोशिश कर रहा हूं जो I2C प्रोटोकॉल का समर्थन करता है (आईसी मॉडल संख्या को मुद्रित नहीं कर सकता क्योंकि यह मुद्रित नहीं है)। निश्चित रूप से यह I2C प्रोटोकॉल का समर्थन करता है, क्योंकि मैंने I2C लाइब्रेरी का उपयोग करके इसका पता लगाने के लिए एक कोड लिखा था और डिवाइस पता मुझे वापस मिला 0x51 है। अब मैं एक कोड लिखने की कोशिश कर रहा हूं जो इस आईसी चिप से डेटा पढ़ता है। कोड निम्नानुसार है:

#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 संचार को डीबग करने का भी प्रयास किया। एक स्क्रीनशॉट नीचे दिखाया गया है।

enter image description here

स्क्रीनशॉट एक एकल पते (0x78) से एक पठन ऑपरेशन के लिए तर्क दिखाता है, लेकिन कहानी प्रत्येक पते के लिए रखती है यानी मैं पते से डेटा के बजाय पता वापस लेता हूं।

उपर्युक्त कोड का आउटपुट निम्नानुसार है:

<�पी> 0 1 2 3 4 5 6 7 8 9 ए बी सी डी ई एफ
  10 11 12 13 14 15 16 17 18 1 1 ए 1 बी 1 सी 1 डी 1 ई 1 एफ
  20 21 22 23 24 25 26 27 28 2 2 ए 2 बी 2 सी 2 डी 2 ई 2 एफ
  30 31 32 33 34 35 36 37 38 39 3 ए 3 बी 3 सी 3 डी 3 ई 3 एफ
  40 41 42 43 44 45 46 47 48 49 4 ए 4 बी 4 सी 4 डी 4 ई 4 एफ
  50 51 52 53 54 55 56 57 58 59 5 ए 5 बी 5 सी 5 डी 5 ई 5 एफ
  60 61 62 63 64 65 66 67 68 69 6 ए 6 बी 6 सी 6 डी 6 ई 6 एफ
  70 71 72 73 74 75 76 77 78 79 7 ए 7 बी 7 सी 7 डी 7 ई 7 एफ
  दौर पूर्ण

क्या आप मुझे यह पहचानने में मदद कर सकते हैं कि मैं यहां क्या गलत कर रहा हूं?

धन्यवाद।

1
@MikaelPatel: मैं 16-बिट पते के साथ प्रयास करूंगा और आपको बताऊंगा कि परिणाम क्या हैं।
जोड़ा लेखक mcrumley, स्रोत
@ निकगैमॉन: बस यह सुनिश्चित करने के लिए कि सामग्री 0x00, 0x01, आदि नहीं है। मैंने चिप पर एक लेखन ऑपरेशन करने की कोशिश की। लेकिन लिखने के बाद पढ़ने का नतीजा वही रहता है। हो सकता है कि आपको 16-बिट पते का उपयोग करने का प्रयास करना पड़े जैसा आपने सुझाव दिया था।
जोड़ा लेखक mcrumley, स्रोत
@ निकगैमॉन: मैंने 16 बिट पते का उपयोग करने की कोशिश की, लेकिन कोई सफलता नहीं मिली। बदले में जो डेटा मिला वह सब शून्य है। शायद क्योंकि अब मैं पहली 8 बिट्स लिख रहा हूं जो मैं लिख रहा हूं, यानी 0x00। मैं आई 2 सी लाइब्रेरी को भी देख रहा था जिसे आपने अपने ब्लॉग में सुझाया था। dsscircuits.com/articles/arduino-i2c-master-library । क्या आप समझने में मेरी मदद कर सकते हैं, रजिस्टर वास्तव में क्या है? इसका उपयोग इस पुस्तकालय के कई कार्यों में किया जाता है, for.e.g.I2c.write (पता, रजिस्टर एड्रेस, * डेटा, संख्याबाइट्स)। धन्यवाद!
जोड़ा लेखक mcrumley, स्रोत
अच्छा ठीक है। मैं एक रिवर्स इंजीनियरिंग प्रोजेक्ट कर रहा था और चिप वास्तव में एक सीओबी है। मुझे इसे किसी भी तरह से डीकैप करना होगा और नीचे देखेंगे। फिर भी धन्यवाद।
जोड़ा लेखक 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

मैं 1 एमबी संस्करण का उपयोग कर रहा हूं और यह 0x51 और 0x50 का उपयोग करता है क्योंकि इसके दो पृष्ठ हैं। मुझे संदेह है कि आपके द्वारा सूचीबद्ध I2C पते के कारण आपको कम से कम अपनी चिप मिल जाएगी। आपके पास एक ही चिप का एक छोटा संस्करण हो सकता है जो केवल एक पते का उपयोग करता है।

1
जोड़ा

विशिष्ट चिप जानकारी के बिना यह मुश्किल होगा।

हालांकि, ईईपीरोम और आई 2 सी के साथ मेरा अनुभव यह है कि पहली कार्रवाई एक कमांड लिखना है, फिर उस कमांड के लिए पैरामीटर लिखें, फिर प्रतिक्रिया पढ़ें।

अक्सर, ईईपीरोम में एक स्टेटस रजिस्टर होता है जिसे निर्धारित करने की आवश्यकता होती है कि यह निर्धारित करने के लिए कि ईईपीरोम एक अलग कमांड प्राप्त करने के लिए तैयार है या नहीं, जैसे पढ़ने के लिए पता सेट करने के लिए लिखने के लिए ईईपीरोम एक कमांड प्राप्त करने के लिए तैयार है या नहीं)/लिखें, फिर वास्तविक पढ़ने कमांड।

0
जोड़ा