I2C通信にてSDAラインがLowに固定されてしまいストップコンディションが生成できない

koheiと申します。

現在RL78/G13マイコンとEEPROM間でI2C通信を実施していますが、上手くいかない点がありましたので質問します。

【問題点】

EEPROMから8bitのデータをReadできたら、マイコン側はACKを出力時、その後ストップコンディションを生成することで通信が終了します。

しかしマイコン側はSDAラインにACKを出力(Low)にすると、そのままSDAラインがLowに固定されてしまいます。

結果、ストップコンディション(SDAラインをLow⇒High)が生成されず通信を正常に終了させることができません。

【プログラムの流れ】

       ACKE0 = 1; //アクノリッジを許可する。

       IICA0 = 00; //クロックを出力する

      ウェイト

      SPT0 = 1; //ストップコンディションを生成する。

【質問事項】

①I2C通信でスレーブ側(EEPROM)がデータを送信する場合、マイコン側はクロックのみを出力しなくてはなりません。

 この場合、IICA0=00でクロックを出力していますが、このやり方は正しいですか?

②ACKをCPU側が生成する場合、ACKEnを1に設定する必要はありますか?

③CPUがACKを出力後、SDAラインがLow固定になってしまうのを解除する方法はありますか?

大変恐縮ですが、ご回答頂けると幸いです。

  • チョコです。

    この現象は、EEPROMがSDAをLowに引っ張っているものです。

    SCLラインをポートとしてダミークロックを出してください。

    ハードウェアマニュアルの「図13-28 シングルマスタ・システムでのマスタ動作」の「注」に書かれている状態だと思います。

    これから出かけるので、詳細は後ほど。

  • チョコです。

    先ほど戻ってきたので、コメントします。

    >EEPROMから8bitのデータをReadできたら、マイコン側はACKを出力時、その後ストップコンディションを生成することで通信が終了します。

    これはIICの規定に違反した処理です。マスタ受信では、マスタは受信した最後のデータに対してACK応答しないことでスレーブに通信終了を通知します。

    マスタは通信を終了したつもりでもスレーブは通信が継続していると判断して次のデータを出力します。この時のデータが0だったのでSDAがLowに引かれている状態と考えられます。以下に示すI2Cバスの仕様を見てください。

    UM10204 I2C バス仕様およびユーザーマニュアル (nxp.com)

    >①I2C通信でスレーブ側(EEPROM)がデータを送信する場合、マイコン側はクロックのみを出力しなくてはなりません。

    >この場合、IICA0=00でクロックを出力していますが、このやり方は正しいですか?

    ハードウェアマニュアルの「図13-33 スレーブ→マスタ通信例(マスタ:8クロック,スレーブ:9クロックでウエイト選択)(1/3)」の下に「注1. マスタ側での受信時のウエイト解除は,IICAn←FFHまたはWRELnビットのセットのどちらかで行
    ってください。」き記載されています。

    >②ACKをCPU側が生成する場合、ACKEnを1に設定する必要はありますか?

    マスタ(MCU)は受信を継続する場合には、ACKEnを1に、それ以上の受信を行わない場合には、ACKEnを0に設定する必要があります。

    >③CPUがACKを出力後、SDAラインがLow固定になってしまうのを解除する方法はありますか?

    基本的に、この処理が仕様に違反しているので、これはやってはいけません。何らかの原因でスレーブがSDAをLowに引いて止まってしまったら、IICAでは対応できません。この場合には、前回コメントしたように、端子をポート機能に変更して、SDA端子の兼用ポートは入力に設定し、SCL端子の兼用ポートは出力に設定して、通信条件に合ったCL信号をポートを制御すること出力します。これを9クロック出力していると、そのうちにSDAがHigh になるはずです。そこでIICA機能に戻してストップコンディションを発行してください。

    以上

  • チョコです。

    少し情報を追加しておきます。

    >以下に示すI2Cバスの仕様を見てください。

    該当部分の画面キャプチャしたものを以下に示します。

    I2Cバスの動きについては、RL78/G13のハードウェアマニュアルの「13. 6 タイミング・チャート」にかなり詳しく解説されています。問題の処理に該当するのは「図13-33 スレーブ→マスタ通信例(マスタ:8→9クロック,スレーブ:9クロックでウエイト選択)(3/3)」になるかと思います。ここは、スレーブからデータを受信して通信を終了しているところです。

    マスタは8クロック目でウェイトして割り込みを発生するようになっています。⑬のSCLの8クロック目でINTIICAnが発生し、その割り込み処理の中で、⑭でACKEnをクリアしています。(さらに、WTIMnをセットして9クロック目でのウェイトと割り込みに変更しています。)その結果、⑮でWRELnをセットして8クロック目でのウェイトを解除すると、NACK応答がスレーブに送られます。⑯で9クロック目の割り込みが発生するので、⑰で、SPTnをトリガしてストップ・コンディションを発行して受信を完了させています。これらの動きは次のページに説明が記載されています。

    RL78のマニュアルには使用するうえで有益な情報が記載されているので、目を通しておくことを推奨します。

    以上

  • チョコさん

    ご丁寧にありがとうございます。

    記載いただいた内容をもう一度確認し、引き続き動作確認を進めていきます。

    結果は別途報告させてください。