I2C protokoli yordamida EEPROM chipini o'qish muammosi

I2C protokolini qo'llab-quvvatlaydigan EEPROM chipini o'qishga harakat qilaman (IC model raqamini chop etilmaydi). I2C kutubxonasi yordamida uni aniqlash uchun kod yozganimdan va uni qaytarib olgan qurilmaning manzilini 0x51 yozganligi uchun I2C protokolini qo'llab-quvvatlaydi. Keling, ushbu IC chipidagi ma'lumotlarni o'qigan kod yozmoqchiman. Kod quyidagicha:

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

Men oldida turgan muammom, ma'lumotning o'zi (masalan, o'qiladi (0) 0 qaytarsa, (1) 1 va shunga o'xshashlarni qaytaradi) kabi manzilni qaytarib olaman. Hatto I2C xabarlarini mantiqiy analizator yordamida (masalan, Saleae mantiqi) disk raskadrovka qilishga urindim. Ekran tasvirlari quyida ko'rsatilgan.

enter image description here

Skrinshot bitta o'qish manzilidan (0x78) bitta o'qish jarayoni mantig'ini ko'rsatadi, biroq har bir manzil uchun hikoya tutiladi, ya'ni manzildan ma'lumot o'rniga manzilni qaytarib olaman.

Yuqoridagi kodning chiqishi quyidagicha:

0 1 2 3 4 5 6 7 8 9 A B C D E F Foydalanuvchining profili   10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F Foydalanuvchining profili   20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F Foydalanuvchining profili   30 31 32 33 34 35 36 37 38 39 3A 3-D 3C 3D 3E 3F Foydalanuvchining profili   40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F Asosiy   50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F Foydalanuvchining profili   60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F Foydalanuvchining profili   70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F Foydalanuvchining profili   

to'ldirildi

Men bu erda noto'g'ri ish qilayotganimni aniqlashga yordam bera olasizmi?

Rahmat.

1
@MikelPatel: 16-bitli manzil bilan sinab ko'rsata olaman va natijalar nima ekanini bilaman.
qo'shib qo'ydi muallif mcrumley, manba
@NickGammon: Mundarija 0x00, 0x01, va hokazo. Emasligidan amin bo'lish uchun jipga yozish operatsiyasini bajarishga harakat qildim. Ammo yozishdan keyin o'qish natijasi bir xil bo'ladi. Ehtimol, siz taklif qilganingizdek, 16-bitli manzillardan foydalanishga harakat qilishim kerak.
qo'shib qo'ydi muallif mcrumley, manba
@NickGammon: 16 bitli manzillarni ishlatishga harakat qildim, lekin muvaffaqiyatga erishmadim. Qabul qilingan ma'lumotlarning hammasi noldir. Ehtimol, hozir men yozayotgan dastlabki 8 bitni, ya'ni 0x00ni qaytarib olaman. Bundan tashqari sizning blogingizda taklif qilgan I2c kutubxonasiga ham qarardim. dsscircuits.com/articles/arduino-i2c-master-library . Menga tushunishimga yordam bera olasizmi, bu erda aniq nima? Ushbu kutubxonaning ko'p funktsiyalarida ishlatilgan, for.e.g.I2c.write (manzil, registerAddress, * ma'lumotlar, numberBytes). Rahmat!
qo'shib qo'ydi muallif mcrumley, manba
Ohh OK. Men teskari muhandislik loyihasini qildim va chip aslida bir COB. Undan keyin biroz tushirib, ostidan ko'rishim kerak. Baribir rahmat.
qo'shib qo'ydi muallif mcrumley, manba
Chipning qancha oyog'i (pin) bor?
qo'shib qo'ydi muallif Nick Gammon, manba
Mikael bilan ham roziman, siz 16-bitli manzilni jo'natishga harakat qilishingiz mumkin. Masalan, birinchi bo'lib nolni, keyin manzilini yuboring. Qanday bo'lmasin, chipning xotirasida 0x00, 0x01, va hokazo bo'lishi mumkinligiga ishonchingiz komilmi?
qo'shib qo'ydi muallif Nick Gammon, manba
Qurilmaga bog'liq, ammo ba'zi bir narsalarni yozadigan ichki registrda yozuvlar mavjud. Rostini aytganda, noma'lum qurilmadan yozish/o'qish uchun yordam berishga harakat qilish deyarli mumkin emas. 5 dollar uchun sizga chipni sotib olishingiz mumkin, siz uning qismini bilasiz va ma'lumot sahifasini olishingiz mumkin.
qo'shib qo'ydi muallif Nick Gammon, manba
16-bitlik manzilni qanday ishlatish kerak? Men Cosa uchun yozgan haydovchiga havola bu; github.com/mikaelpatel/Cosa/blob/master/libraries/ AT24CXX/& hellip;
qo'shib qo'ydi muallif Mikael Patel, manba

3 javoblar

Manzilni ikki bayt, birma-bir qabul qilishingiz kerak.

Qilmang:

Wire.write(address);

Aksincha:

Wire.write((uint8_t)(address >> 8));//MSB
Wire.write((uint8_t)(address & 0xFF));//LSB
2
qo'shib qo'ydi

Muxtasar qilib aytganda, siz split bo'lishingiz kerak

Wire.write(address);

ichiga

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

Men 1Mb versiyasini ishlatmoqdaman va u 0x51 va 0x50 dan foydalanadi, chunki u ikki sahifaga ega. Men sizning chipingizni hech bo'lmaganda o'xshash bo'lganingizni bilib olishingiz mumkin, chunki siz ro'yxatdagi I2C manzili. Bitta manzilni ishlatadigan bir xil chipning kichik versiyasi bo'lishi mumkin.

1
qo'shib qo'ydi

Muayyan chip ma'lumotisiz bu qiyin bo'ladi.

Biroq, EEPROM va I2C bilan bo'lgan tajribam shundan iboratki, birinchi harakat buyruqni yozish, so'ngra ushbu buyruq uchun parametr (lar) ni yozib, keyin javobni o'qish.

Ko'pincha, EEPROMda o'qish uchun/yoki o'qish uchun manzilni belgilash uchun turli xil buyruqni olishga tayyor yoki yo'qligini aniqlash uchun EEPROMda o'qish kerak bo'lgan buyruq registri (buyruq yozish, keyin javobni o'qish) mavjud./Yozish, keyin haqiqiy o'qish buyrug'i.

0
qo'shib qo'ydi