I2C接続のEEPROMについて調べた

    電子工作
    06 /14 2015
    PICAXEでI2Cデバイスからの読み取りはやっていないので、部品取り基板からI2CのEEPROM(M24C32RP STM社)を外して繋いでみようと思いました。
    I2C_EEPROM_01.jpg I2C_EEPROM_03.png
    ただ、その前にこれについて調べる必要があった。
    その為にI2C接続のEEPROMについて調べた個人的な資料です。

    ・EEPROMのアドレッシング(バイト/ワード、ブロック(バンク))はどうなっているか
    ・EEPROMのA2-0ピンは有効か
    ・EEPROMの書き込み周期の最大時間
    ・EEPROMの連続アクセスのページサイズ
    ・I2Cの周波数400kHz動作でのプルアップ抵抗値

    24C32だけ調べればよいのだが個人的な興味で一通りのEEPROMを調べたのが下の一覧表。(PICAXEのhi2csetupコマンドの解説にもあるが情報不足)
    PICAXE推奨?のMicrochip Technology社の24LCタイプで調べた。
    I2C_EEPROM_02.png
    ・アドレッシング
    バイトアドレス8bitだと256アドレスまでであり 256 x 8bit = 2kbit が限界。
    そこでControl Byteの中にB2~0のブロック(バンク)という考えを持ち込んだ。
    ここは元々I2Cバス上のデバイスアドレス(番号)なので、ここを使うということは2kbit(256 x8bit)のデバイスがバス上に何個も繋がっていると解釈できるので規格を変える必要はない。
    それにワードアドレスにするのに比べて1アドレス分多く送る必要がなく高速なのが利点。
    だだ、それでも限界があるのでワードアドレスになった。(32kbit以上)
    さらにワードアドレスも一杯になったらまたバンクを使う(1Mbit以上)というようになっている。

    注:まれに変則的なアドレッシングをするものがあったような気がするので、必ずデータシートで確認すること。 (上の表は大体の目安です。)
    例えば4k~16kbitはバンク+バイトアドレスでなくワードアドレスにすることもできる。
    1アドレス多く送る分遅くなるが32kbit以上のものと同じアドレッシングにできる。

    A2-0ピンの処理
    I2Cバス上でのデバイスアドレス(番号)を変えられるので複数のEEPROMを繋げられる。
    このピンが有効なのと無効なものがある
    16kbit以下のものにはこの機能はないようである。
    面倒なのはパッケージのピンの説明にはA2-0とあるのだが端子の説明でNot Connectedとなっていること。 最初からNCと書いて欲しい。
    ただ、普通はより容量の多いものを1個繋げばよいのでこの機能は使わないと思う。
    他にI2Cデバイスがない場合、全てGNDに繋いでおけば良いだろう。

    ・書き込み周期の最大値(5V時)
    書き込んだ後この時間分待つ必要がある。
    今回調べた限りでは5msでいいようだが10msとか長いものもあるようなので必ずデータシートで確認すること。
     
    ・連続アクセスのページサイズ
     プログラムを作るときに必要な情報。
    EEPROMにアドレスを与えたあと何バイト連続してデータをアクセスできるか。
    アドレスを与える回数を減らせ高速にアクセスできる。
    これも、ものよってページサイズが異なるので確認が必要。
    ただ、24xx00以外は必ず8バイト連続はできる。
    16バイト連続以上は確かに多少高速になるのだがソフト処理が面倒になることを考えると特別な理由が無ければ8バイト連続固定でも十分高速だし汎用性があります。
    しかし現在大手メーカーでも低用量のEEPROM入手できないようなので32kbit以上と指定して2バイトアドレスで32バイト連続としてプログラムを考えるのが現実的だと思います。
    なお、無理に32バイト連続にする必要はなく8バイト連続とかに抑えてもよい。

    ・WP(ライトプロテクト)ピン
    24xx00以外には付いている。
    Hだとプロテクトされるので書き込むためにはLにしなくてはならない。

    →今回使おうとしているM24C32RPは24LC32Aと同じ動作なので表の通りである。
    ワードアドレス品で最小容量のものであることが分かった。
    WPピンは内部でLにプルダウンされているのでオープンでも良い。
    A2-0ピンもLにプルダウンされているのでオープンでも良い。


    ・I2C 400kHzでのプルアップ抵抗値
    今回Microchipのデータシートを調べたのだがSDA(データ)のプルアップ抵抗は動作速度400kHzで10kΩ、400kHzで2kΩとされている。
     (何故かSCL(クロック)について書かれていないが普通はSDAと同じはず。)
    100kHzで10kΩは良いのだが、400kHzで2kΩはかなり低い。

    以前、概算で400kHzは4.7kΩで良いと判断したが今回厳密に計算してみた。
    I2C バス仕様およびユーザーマニュアル(NXP 1.52MB)のP.55にバス容量(Cb)に対するプルアップ抵抗値(Rp)の最大値の計算の仕方が書いてある。

     Rp(max)=tr/(0.8473*Cb)
      tr立ち上がり時間 100kHz時1000ns 400kHz時300ns

    これは単純にCRの時定数で計算するよりも1.180倍大きな抵抗値(時定数)でよいということ。
    それはtrは0.3→0.7Vccの遷移時間で規定しているのでこの間の時間を満足すれば良いからである。 (納得するのに時間が掛かったが問題ないようである。 当たり前。)

    よくCRの時定数で計算するがこれだとRp(max)より18%のマージンがある。
    これから抵抗の誤差5%分を除くと実質12.4%のマージンがあることになる。
    従ってCRの時定数の時定数で計算しても問題はない。

    今回は上記のRp(max)の式で 抵抗器の誤差を5%、マージン5%として計算してみた。
        30pF 40pF 50pF 100pF
    100kHz 1000ns/1.1025 35.7kΩ 26.8kΩ 21.4kΩ 10.7kΩ
    400kHz 300ns/1.1025 10.7k 8.03kΩ 6.42kΩ 3.21kΩ
    なお、I2Cのデバイスのピンの最大容量は10pFである。
    パターンの容量は10cmで10pF位。(層構成、隣のパターンによって変わり半分~2倍位)
    つまり、マスター、スレーブ、パターン10cmで30pF位になる。

    個人的な経験からノイズが乗り易いので10kΩより大きくしたくない。
    できれば数kΩまでがよい。
    大雑把にいえばノイズ源のインピーダンスとプルアップ抵抗値の比でノイズが分圧されるので低い方がノイズ電圧が下がる。
    実際I2Cではバスに外来ノイズで高い電圧が載ることを想定しておりデバイス保護の為にSCL、SDAピンに直列(シリーズ)抵抗Rsを入れることを認めている。
    この値はRp、電源電圧に左右されるので一概には言えないが3.3V以上では100Ω以下ならノイズ抑制効果は別としても通信には問題なさそう。
    詳しくは仕様書の「7.3 直列保護抵抗」を参照。

    なお、回路を金属ケースに入れるということは外来ノイズには強くなるが、自分自身(回路)が発したノイズはケース内にこもる(反射し続ける)ということなので自身が発したノイズで誤動作する場合があります。

    プルアップ抵抗の最小値は規格でVol=3mAなのでVcc5.25Vで概算1.75kΩである。
    2.2kΩ以上がよい。 (1.8kではLレベルのノイズマージンが少なくなる)
    但し、抵抗値が低いとLレベルが上がってノイズマージンが減るデメリットがある。

    I2Cの仕様ではバスは400pFまでだが現実的には30~50pF位を考慮すれば十分と思われる。→オープンドレイン・コレクタなので配線長ではなく配線容量が重要。
    それでの抵抗器の範囲は
    100kHzは33k~20kΩ以下
     22kΩで充分だが外来ノイズを考慮すると10kΩ以下がよい。
     10kΩだと107.0pFまでOKである。

    400kHzは10k~6.2kΩ以下
     10kΩでもマスター、スレーブ1個で配線パターン12cm位までなら動く。
      ジャンパ線だと線間容量が少ないのでもう少し長くても動くと思われる。
     表にはないが6.8kΩだと47pFまでなのでマスター、スレーブ2個で配線17cmまでOK。
     4.7kΩだと68pFまでなのでマスター、スレーブ2個で配線38cm、またはマスター、スレーブ3個で配線28cmまでOKなので大概の場合でOK。

    →従ってMicrochipのデータシートあるように400kHzで2kΩまで低くする必要はない。
    100kHz動作で10kΩ、400kHz動作で4.7kΩで良いだろう。

    なお、
    ・3.3Vとかでも抵抗値を変える必要はない。
    5V以下でも動くデバイスはCMOSなので論理レベルは電源電圧Vccに応じて0.3Vcc、0.7Vccと変わるため。
    ・I2Cバスの電圧レベルの変換(5V<->3.3V等)用の素子を使った場合は完全にON(導通)せず電圧が上がり/下がり切らないでトラブルがあることがあるようなのでご注意下さい。その場合、抵抗値の調整が必要です。

    追記
    秋月電子通商の小型キャラクタLCDモジュール AQM0802A-RN-GBW は論理レベルがデータシートで 0.2Vdd、0.8Vdd となっておりI2Cの規格から外れている。
    一方、trは300nsのままなので高速に遷移しなくてならない。

    これでのRp(max)の計算式は
     0.8Vdd 1.6095*CR
     0.2Vdd 0.2232*CR
    →1.6095-0.2232=1.3863

    Rp(max)=tr/(1.3863*Cb)
    となり正規のI2Cよりプルアップ抵抗値かバス容量を0.61120倍にしなくてならない。

    400kHzで10kΩプルアップ、抵抗誤差5%、マージン0%でバス容量は20.6pFまでである。
    デバイスの入力容量がマスター、スレーブで各10pFだとすると配線長0.6cm位で無理。
    マスター、スレーブで各5pFだとしても配線長10.6cm位である。
    →10kΩは危険だと思うので4.7kΩがよいだろう。
      これで計算すると抵抗誤差5%、マージン5%で41.8pFまで。
       マスター、スレーブ1個で配線長21.8cm位までOK。
       マスター、スレーブ2個で配線長11.8cm位までOK。
     4.7kΩで動作確認済みです。
      ただ、AQM0802A-RN-GBWはLoレベルに引っ張る力が弱いようで(これも規格割れ?)SDAのプルアップ抵抗をもう少し高く(5.6kΩとかに)しないとACKがうまく返らず動作 しない場合があるかもしれません。 (あくまで可能性です。)

    100kHzで10kΩプルアップ、抵抗誤差5%、マージン5%で計算すると65.4pFまで。
       マスター、スレーブ1個で配線長45.4cm位までOK。
       マスター、スレーブ2個で配線長35.4cm位までOK。

    400kHzでうまく動作しない場合、100kHzにすれば動くならばプログラムではなくプルアップ抵抗値の問題の可能性が高いです。 (I2Cで共通の話)
    追記終わり

    追記2
    ノイズによる誤動作対策 (理論的な話です。)
    自作ではあまり関係ないと思うが工業的に長距離、高ノイズの環境とこかで使う場合の話です。
    ・放射ノイズを受けにくいようにプルアップ抵抗を2.2kΩに下げる。
    ただ、ここまで抵抗値を下げるなら100kHzの方がより安全。
     特にメートル単位で伸ばす場合は。
    放射ノイズの信号源、そして空間にインピーダンスがあるので受け側=I2Cのプルアップ抵抗値が低い方がノイズ電圧が分圧されて受けるノイズ電圧が低くなる。
    短距離ならばプルアップ抵抗を下げた上でさらに意図的にバスに数十pFのセラコンを入れてさらにインピーダンスを下げ方法も考えられる。

    ・電源ノイズを減らす
    I2Cバスは電源にプルアップされているということは電源ノイズが信号に載るということ。
    リップルやACから電源を突き抜けてきたノイズが信号に載るということである。
    つまり、綺麗な充放電波形をイメージするが実際にはそれにはリップルやノイズが載ってギザギザしているということでスレッショルド電圧付近で誤動作する可能性がある。
    単純にはプルアップ抵抗の電源にパスコンを足すことだが、モーターを使う機器など電源ノイズがひどい場合はフィルターを通した電源にプルアップ抵抗とI2Cデバイスを繋いだ方がよいと思う。 上記の、バスに数十pFのセラコンを入れる方法も効果があると思われる。

    AC電源からDCに載るノイズなんて想像できないかもしれませんが、恥ずかしながら電源ノイズ試験(kVオーダーのノイズ)で組み込み用のCPUボード(10万円位)を壊したことがあります。 (勿論ACに電源フィルターは入れてあった。)
    AC/DC電源を突き抜けて5Vラインに15V位のパルスが抜けており壊してしまいました。
    専門的な話になりますが、ノーマルモードのノイズは電源フィルターで理論通りカットできるのですがコモンモードのノイズは2本の電源の線(H,N)の長さに差(=時間差)があると高速(0.数ns)のノーマルモードのパルスノイズに変わり電源を簡単に突き抜けてしまうのです。 (電源自体はこの試験にパスしているので壊れない。)
    これの対策としてはAC側の線長を揃えるのが基本ですが、DC側にLCフィルターを入れる手のが効果的です。 (AC側の配線(ハーネス)は人手が入るのでどうしても線長にバラつきがでます。)

    ここまで極端な高電圧な例は家庭ではあまりないと思いますが、実は家のパナソニックの空気清浄機(空気の汚れで風量が変わる)は電源ノイズを出すので簡単なACフィルターを入れてあります。
    追記終わり

    追記3
    高信頼性が要求される用途(車載用等)ではデータ書き込み後にベリファイさせるのはいうまでもない。
    追記終わり

    追記4
    以前の記事でも書いたが、I2CのスレーブにはSCLの立ち上がりをLに削って(抑えて)ウエイトをかけるという技がある。(クロック・ストレッチ) これはI2Cの仕様で認められている。
    具体的には、スレーブが応答できる時間までSCLをオープン・コレクタ/ドレインでLレベルに引っ張っておくということ。 勿論、I2Cの規定内で。
    このため、マスターとスレーブが1対1でも、マスターはオープン・コレクタ(ドレイン)出力にしておく必要がある。
    もしマスターデバイス(CPU/IC等)にクロック・ストレッチを設定する機能がある場合はONする必要がある。 (普通はデフォルトでONだと思うが)普通はクロック1パルス毎というよりアドレスの後のデータサイクルとの間に行われるようである。
    追記終わり

    以上
    関連記事

    コメント

    非公開コメント

    Friendship 7

    浅く広くのハード屋です。
    コメントへの返信には過大な期待をしないで下さい。 非公開コメントは停止しております。 不適切なコメントはFC2で自動的にはじかれます。
    リンクフリーですが盗作は禁止です。
    本ブログの内容を参考にされる場合はあくまで自己責任でお願い致します。