I2Cプロトコルを使用してEEPROMチップを読み取る際の問題

I2C プロトコルをサポートするEEPROMチップを読み取ろうとしています(印刷されていないため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
}

私が直面している問題は、データ(例えば、read(0)が0を返し、read(1)が1を返すなど)として、データを読みたいアドレスを返すことです。私はロジックアナライザ(この場合はSaleaeロジック)を使ってI2C通信をデバッグしようとしました。スクリーンショットを以下に示します。

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
追加された 編集された
ビュー: 4
@MikaelPatel:私は16ビットのアドレスで試してみて、結果が何であるかを知らせます。
追加された 著者 mcrumley,
@NickGammon:内容が0x00、0x01などでないことを確認するだけで、私はチップへの書き込み操作を実行しようとしました。しかし、書き込み後の読み込み結果は同じです。たぶん、あなたも同様に16ビットアドレスを使用してみる必要があります。
追加された 著者 mcrumley,
@NickGammon:私は16ビットアドレスを使用してみましたが、成功しませんでした。私が得たデータはすべてゼロです。おそらく、私が書いている最初の8ビット、つまり0x00を取り戻しているからです。あなたのブログで提案したI2cライブラリも見ていました。 dsscircuits.com/articles/arduino-i2c-master-library 。理解してもらえますか?正確にここではregisterAddressは何ですか?このライブラリの多くの関数で使用されています。たとえば、.I2c.write(address、registerAddress、* data、numberBytes)です。ありがとう!
追加された 著者 mcrumley,
ああ。私はリバースエンジニアリングプロジェクトを行い、チップは実際にCOBです。私はそれを何とか解読し、下を見なければなりません。とにかく、ありがとう。
追加された 著者 mcrumley,
チップにはいくつの足(ピン)がありますか?
追加された 著者 Nick Gammon,
私もMikaelに同意します。あなたは16ビットのアドレスを送信することができます。たとえば、最初に0を、次にアドレスを送信します。いずれにしても、そのチップの内部に0x00、0x01などが存在しないことを確かめることができますか?
追加された 著者 Nick Gammon,
それはデバイスに依存しますが、いくつかはレジスタを持っていて、何かを書き込むと内部ビットがセットされます。正直なところ、未知のデバイスへの書き込み/読み出しを手助けしようとすることはほとんど不可能です。 $ 5のためにあなたは部品番号を知っていて、データシートを入手できるチップを購入することができます。
追加された 著者 Nick Gammon,
16ビットアドレスの使用はどうですか?ここに私がCosaのために書いたドライバへのリンクがあります。 github.com/mikaelpatel/Cosa/blob/master/libraries/ AT24CXX /…
追加された 著者 Mikael Patel,

3 答え

アドレスを1バイトずつ2バイトとして渡す必要があります。

するな:

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バージョンを使用しており、2ページあるので0x51と0x50を使用します。私はあなたがリストアップしたI2Cアドレスのためにあなたのチップが少なくとも似ていると思うでしょう。 1つのアドレスだけを使用する同じチップのより小さなバージョンを使用することができます。

1
追加された

特定のチップ情報がなければ、これは難しいでしょう。

しかし、EEPROMとI2Cでの私の経験は、最初のアクションはコマンドを書いてから、そのコマンドのパラメータを書いてからレスポンスを読むことです。

多くの場合、EEPROMには、EEPROMが別のコマンドを受け取る準備ができているかどうかを判断するために(コマンドを書き込んだ後に応答を読み取る)読み取りが必要なステータスレジスタがあります。/write、実際の読み取りコマンド。

0
追加された