Я пытаюсь прочитать чип EEPROM, поддерживающий протокол I2C (не могу указать номер модели IC, поскольку он не печатается). Конечно, он поддерживает протокол 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
}
Проблема, с которой я столкнулся, - это вернуть адрес (из которого я хочу прочитать данные), поскольку сами данные (например, read (0) возвращает 0, read (1) возвращает 1 и т. Д.). Я даже пытался отлаживать связь I2C с помощью логического анализатора (в данном случае логика Saleae). Снимок экрана показан ниже.
На скриншоте показана логика операции чтения с одного адреса (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
раунд завершен
Можете ли вы помочь мне определить, что, возможно, я делаю неправильно здесь?
Благодарю.
Короче говоря, вы должны разделить
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, который вы указали. У вас может быть меньшая версия того же чипа, который использует только один адрес.
Без конкретной информации об микросхеме это будет сложно.
Однако мой опыт работы с EEPROM и I2C заключается в том, что первым действием является запись команды, а затем запись параметров для этой команды, а затем чтение ответа.
Часто в EEPROM есть регистр состояния, который необходимо прочитать (путем написания команды, затем чтения ответа), чтобы определить, готова ли EEPROM к приему другой команды, например записи, чтобы задать адрес для чтения/или/write, а затем фактическую команду чтения.