I2C EEPROMビットバンギング:正常に書き込みますが、最初のビットが設定されていない場合のみ


9

現在、ビットバンギングを使用してSDAおよびSCLラインを駆動するI2C EEPROMプロジェクトに取り組んでいます。

私の読み取り機能は正常に動作しますが、先頭に「1」が付いたバイトを書き込むときはいつでも、常にFFを読み取ります。バイトが以前に何か他のものでプログラムされていても。先頭の「0」は完璧です。これは私の読み取りルーチンではありません。スコープで確認できるように、FFを返します。

これがなぜであるかについての提案を探しています。問題を引き起こす可能性のある明らかなミスはありますか?[コードを投稿できません-会社の機密情報... :(]

私が見るすべての波形は、仕様を正確に満たしています。EEPROMを分離しています。私のプルアップは2.2kなので、仕様の範囲内です。このプロトタイプでは、約500 Hzでクロッキングしています。チップは各バイトにACKを送信しているため、それらを認識します。しかし、それはうまくいきません...

Microchip 24LC256を使用しています。

1バイトの簡略化された書き込みアルゴリズム:

wait
SDA low
SCL low
wait
for each bit
    if bit is set:   SDA high
    if bit is unset: SDA low
    wait
    SCL high
    wait
    wait
    SCL low
    wait
wait
SDA high 
SCL high
wait
wait
check ACK status
SDA low
SCL low
wait
return ACK status

1バイトの簡略化された読み取りアルゴリズム:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high
    wait
    wait
    SCL low
    wait
    check and store received bit
    wait
do a NACK or ACK depending on if it is the last byte

1
@ジャスティン-彼は値0x7Fを任意のアドレスに書き込むことは機能するが、0x80を任意のアドレスに書き込むことは機能しないと言っていると思います。
Rocketmagnet

1
I2Cが嫌いになるのはこのようなものです。
Rocketmagnet

1
私はクレイジーな予感を持っています。for eachビットコードで、誤って右シフト演算で符号拡張していますか?あなたがしている場合、あなたの指導者は最終的に7シフト操作後に0xFFを残します。
vicatcu 2012

3
ここで皮肉なのは、「会社の機密」コードです。それは彼らにとって貴重です。ここにいる他の全員が機能するコードを共有しています。この会社のコードを他のコードと区別しているのは、機能しないことです。
gbarry

2
企業がI2Cビットバンギングコードの機密を保持する必要がある理由を想像するのは困難です。インターネット上にはたくさんあります。
Rocketmagnet

回答:


4

クロックが再び低くなった後、データを読み取っています。クロックを高くしてから低くするまでの間、これを行う必要があります。クロックがローになった後、スレーブはデータラインを変更できますが、ハイの間は変更できません。

ここに画像の説明を入力してください

したがって、読み取りは次のようになります。

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high                      <--------
    wait
    check and store received bit  <--------
    wait
    SCL low                       <--------
    wait
    wait
do a NACK or ACK depending on if it is the last byte

それは良い点です; 直します。ただし、私のデータはまだスコープ上ですべて1(FF)として表示されるため、読み取りが問題になることはありません... :(
Thomas O

3

結局のところ問題は、タイミングが壊れているために、いくつかの状況下で誤ってSTOP条件を送信していたことがわかりました。私はスコープの使用をあきらめて、ロジックアナライザーを取り出し、15分以内に問題を修正することができました。最も役立つ回答に基づいて、賞金を誰に贈るかを選択します。すべての解決策をありがとう。


「書き込みタイミングを確認する」ことで解決してくれてうれしい

3
これは波形を見れば解決できると言った。
Rocketmagnet

@Rocketmagnet私はいつも波形を見ていましたが、以前はそれに気づいていませんでした。
Thomas O

ええ、でも私たちが繰り返しそれを求めてきたにもかかわらず、あなたは私たちに波形を見せなかった。この問題は数日前に解決できたはずです。
Rocketmagnet 2012

@ロケット-同意する。当時はカメラがあったらいいのに。私が使用していたTek DPOにはフロッピードライブがありましたが、フロッピーがありませんでした。できれば写真を投稿しました。
Thomas O

2

スコープは、PICに送信される最初のバイトが不良であることを証明しているため、PIC読み取り関数ではありません。

受信側で書き込みタイミングに問題がないことを確認しましたか?

これは以下の両方のモードで失敗しますか?

- Byte mode sequential
- Page mode Sequential

仕様は、「最上位ビット(MSB) 'b7'が最初に送信される」を示しています。これは、バイト全体がFFとして読み戻されるb7 = 1の場合にも一致します。したがって、b7 = 1の場合は書き込まれずに消去されるだけで(フォルト状態)、または以前の内容に関係なくFFとして不良が読み取られます。すべての書き込みは書き込み前のバイト幅消去であるため、それでも書き込み不良または読み取り不良であるか、または最初のバイトのタイミングが異なる可能性があります。

提案: 正常な動作を保証するために、書き込み/読み取り中にPTC信号を確認してください。 ここに画像の説明を入力してください

PTCを使用してE / Wサイクルの長さを計るために外部クロックを使用するオプションがあります。 これを使ってみましたか?

tE / Wサイクルタイム

  • 内部発振器7ms typ
  • 外部クロック4〜10 ms min〜max

この基準を満たしていますか?


1

それはいくつかのことのように聞こえるかもしれません:

  1. バスには他に何がありますか?リセットまたは初期化されていない状態で保持されている別のデバイスとのバス競合が発生する可能性はありますか?
  2. I / Oピンの方向を正しく変更していますか?出力のケースで正常に機能している場合は、ピンの方向を入力に変更するのを忘れてしまった可能性があり、常に読み取ります0xFF。ピンは、バスからの読み取り時にバスを駆動する出力として残すことができます。
  3. ピン自体やI / Oラインに内部プルアップがありますか?マイクロコントローラは通常、一定の範囲ではなく一定の抵抗値を提供します。ディスクリートコンポーネントからより正確なプルアップ抵抗を得ることができるので、マイクロのプルアップを無効にして、バスでディスクリートのプルアップを使用することができます。
  4. クロック極性-クロック/データ間の右端/位相で測定しているか?スコープで見栄えの良いものを計時している可能性がありますが、フェーズがずれている場合、EEPROMはすべて0xFFsであると認識します(おそらく無効なコマンド/条件であるため、同じ結果を返す可能性があります)。

1. EEPROMとMCUのみ。2.はい、EEPROMはSDA / SCLをLowに保持できるため、私はそう思います。3. EEPROMに隣接するボードには2.2kの5%プルアップがあります。
Thomas O

#2の場合、EEPROMがバスをLowに保持しているものであると確信していますか。EEPROMのデータシートには、すべて0xFFのを返す条件がありますか?上記の私の編集も参照してください。
Joel B

#4。EEPROMは私の要求に "ACK"し、一部の単語では機能しますが、すべてでは機能しません。
Thomas O

0

上のコメントとしてこれを提出しましたが、心の奥底で静かに答えへの自信が高まっているので、答えにすすめています。

これはほぼ確実に、いくつかの変数の符号性に関連する低レベルのソフトウェアバグであるという奇妙な予感があります。for eachビットコードで、誤って右シフト演算で符号拡張していますか?あなたがしている場合、あなたの指導者は最終的に7シフト操作後に0xFFを残します。

スティーブンはコメントでこれについてほのめかしましたが、オシロスコープでの書き込み操作の神聖さを目撃しましたか、それとも、リードバックの半分が見栄えが良いことに基づいて機能しているだけだと思いますか?値0xAAの書き込み操作を試していない場合は、試してみるとよいでしょう。

内部ループの実際のコードと関連する変数宣言を提供できれば、バグを発見できる可能性があります。


私の書き込みは良好です。これはスコープで確認できます。別の奇妙な点:MSBが先頭にあるアドレスは問題ありません。データのみが問題の原因です!すぐにコードを投稿することを考えています。
Thomas O

1
この回答をサポートするために、これがCコードである場合は、すべての「char」宣言を「unsigned char」に変更して、再試行してください。
Wouter van Ooijen 2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.