EEPROM(24LC256/1024)と接続して読み書きを行って見ます

〔Arduinoの動かせ方入門に戻る〕


 前回の記事でArduinoとPICを接続してI2C通信を行いました、I2Cの概要等はそちらを参考にして下さい。 この頁ではArduinoとEEPROM(24LC256)をI2Cで接続してデータを読書きして見たいと思います。
尚、24LC256は秋月電子のこちらから購入しています。
また、24LC256のマニュアルはこちらを参照下さい。

 ここでは24LC256を利用しましたが24xx32〜24xx512までは利用可能です。
(たぶん、ATMELのAT24C256もいけると思いま〜す。)
念の為に、256は256Kバイトではなく256Kビットです、間違えの内容に!。
でぇ、256Kビットって事は32Kバイトの容量って事です。
また、このEEPROMは最大8個まで接続する事が可能なようです。

PS. *2)
 24FC1025(24xx1025)のEEPROMを手に入れたのでこのデバイスについても追記を行って置きます。
1024Kビット(128Kバイト)ですが、このデバイスには512Kビット(64Kバイト)が2個入ってます
なので、1ブロック512Kビットで2ブロック有り何方にアクセスするのかを指定する必要が有ります。
また、このEEPROMは最大4個まで接続する事が可能なようです。
尚、24FC1025は通信速度1MHzまで対応の様ですが、ここでは100KHzで行っています。
24FC1025のマニュアルは、秋月電子の販売HPからダウンロードしましょう。 *4)

[配線図]
配線図
ArduinoのI2C/TWI端子はSCL(アナログ5番ピン)・SDA(アナログ4番ピン)となっています。
(Arduino UNO R3ならSCL/SDA端子が別に有るのでそこに配線しても良いでしょう)
24xx1024も同じ配線です(但し、A2のみVDDに配線します)。

抵抗について
I2Cのプルアップ抵抗用として1KΩを2個取り付けていますが、
抵抗値に付いては電子工作室さんのこちらのサイトによれば、抵抗値の決め方が 書いて有りますが、私の手持ちから1KΩを使いました。
(データシートには通常は通信速度が100KHzで10KΩ、400KHz/1MHzで2KΩと書いて有ります)

WPピンについて
24LC256/1024の7番ピン(WP:上配線図のオレンジ線)は、書き込み防止用のライトプロテクトピンです。
+5V(VDD)に配線すると書き込みが禁止です、読み込みはできます。
GND(VSS)に配線すると書き込みが可能になります、このピンは必ずどちらかに配線を行います

A0/A1/A2ピンについて

24xx32〜24xx512
24LC256の1番ピン(A0)・2番ピン(A1)・3番ピン(A2)は、複数のEEPROMを使った場合に識別をする為の
チップ選択ビットピンです。
それぞれのピンを+5V(VDD)かGND(VSS)に配線しそのパターンで識別します、
+5V(VDD)に接続するとHigh(1)でGND(VSS)に接続でLow(0)です、3ビットなので8個までOKですね。
なので、スレーブアドレス(EEPROMのデバイスアドレス)は下記の様になります。
A2 A1 A0 R/W
今回の実験では全てGNDに配線(上配線図の黄色線)しています、だから"1010000"です。

24xx1024 *2)
24FC1025の1番ピン(A0)・2番ピン(A1)は、複数のEEPROMを使った場合に識別をする為のチップ選択
ビットピンです、2ビットなので4個までOKですね。尚、A2ピンはVDDに配線しないと動作しません
スレーブアドレス(EEPROMのデバイスアドレス)は下記の様になります。
B0 A1 A0 R/W
B0が"512Kビットのブロック"選択ビットです。

AT24C1024B(ATMEL) *2)
ATMEL製の場合はA0ピンがNCとなっています、
P0が最上位アドレスビット"A16"となっています。(B0と同じ意味です)
A2 A1 P0 R/W
これ用にソフトは対応していないのでこれを使用する場合は自分で変更して下さい。

《ダウンロードスケッチについて》

↓ここからArduino用サンプルスケッチファイルをダウンロードして下さい。
skMC24xxx.lzh(Ver 1.00:2012.01.26)

ArduinoIDE 1.0.1でArduinoのI2Cライブラリ名やインクルード名が変更になっています、
その対応でスケッチを変更しました、↓をダウンロードして下さい。
skMC24xxx.lzh(2012.09.14)  IDE1.0.1対応  *1)
ですので、IDEは1.0.1以降を利用ください。

skMC24xxx.lzh(2014.09.19)  24xx1024対応  *2)
skMC24xxx.lzh(2014.11.01)  Write2/Read2のバグを修正  *3)

解凍すると下の様に展開されます。
[skMC24xxx]─┬─[examples]───[MC24]---- MC24.pde
       ├ skMC24xxx.cpp     └- MC24_1024.ino(IDE 1.0.5-r2)
       ├ skMC24xxx.h
       └ keywords.txt
ArduinoIDE0022がインストールされているフォルダー、インストール先を変更していないなら
[C:\Program Files\arduino-0022\libraries]です。
この場所に上記解凍ファイルを[skMC24xxx]ディレクトリ丸ごと移動します。
また、こちらの[ライブラリ登録]を参考すればより理解が深まるかもぉ?いや、こんがらがるかもぉ。

MC24.pde ・・・・・・・・・本体のサンプルスケッチ
MC24_1024.ino ・・・・・本体のサンプルスケッチ(24xx1024用) *2)
skMC24xxx.cpp ・・・・・Microchip I2C EEPROM(24xxxファミリ)関数ライブラリソース
skMC24xxx.h ・・・・・・・ヘッダファイル
keywords.txt ・・・・・・・キーワードファイル

MC24.pde

MC24.pdeを開くには、
IDEを起動して、メニューバーの「File」→「Examples」→「skMC24xxx」→[MC24]
をクリック操作すればファイルが開かれます。
次に、IDEツールバーの「Upload」ボタンをクリックしてコンパイルとarduinoボードに書込みを行います。

COM画面1  IDEのシリアルモニターCOM画面を表示させましょう。
 起動が成功すると左図の様に表示されます。
 "Error"表示された場合は、配線等をよ〜くぅ見直して下さい。
 EEPROMの0番地から3バイト[1][2][3]を書き込み、
 その後に3バイト読み込んでHEXで表示しているだけです。

 24LC256は256Kbit(32Kbyte)なので0番地から32767番地までアクセス
 出来ます。

 尚、書き込んだ後にすぐ読み出すとエラーが出る場合が有ると言う話が有ります、その場合は
 書き込みと読み込みの間に遅延(delay(100))を入れればOKです。
 データシートに"Write cycle time (byte or page) 5ms"と有るので最低delay(5)は必要でしょう。

MC24_1024.ino *2)

MC24_1024.inoを開くには、
IDEを起動して、メニューバーの「File」→「Examples」→「skMC24xxx」→[MC24_1024]
をクリック操作すればファイルが開かれます。
このファイルが"24xx1024"対応のサンプルスケッチです。
ブロックをまたがっての読み書きは出来ません、これが出来る様に新たに[Read2][Write2]関数を
追加しています。
例えば、下の様に65533番地から6バイト読み取る事は出来ません。
ans = MEM.Read(65533,dt1,6) ;
ブロック0で3バイト読み、ブロック1にして3バイト読みと分けないとダメです。
ans = MEM.Read(65533,dt1,3) ; // B0=0に設定してから読込む
ans = MEM.Read(0,dt1,3) ;   // B0=1に設定してから読込む
これを今回追加した関数を使えば読み取れます。
ans = MEM.Read2(65533,dt1,6) ;
(書き込みも同様です)
ですので、"24xx1024"を読み書きする場合は、[Read2][Write2]関数を使います。

動作としては、65533番地から6バイト[a][b][c][d][e][f]を書込みと読込みを行っているだけです。

skMC24xxx.h

Microchip I2C EEPROM(24xxxファミリ)関数のインクルードファイルです。
このライブラリを利用する場合は、メニューバーの「Sketch」→「ImportLibray...」→「skMC24xxx」を
クリック操作すれば、"#include <skMC24xxx.h>"がスケッチに追加されます。
まぁ、手動でキー入力しても良いんですけどね。

skMC24xxx.cpp

このライブラリは24LC256(24xx32〜24xx512/1024)とデータのやり取りを行う為の関数集です。

まず利用する場合は下記2行を記述します。
#include <Wire.h>
#include <skMC24xxx.h>

Microchip I2C EEPROM(24xxxファミリ)関数ライブラリの使い方を説明します。

skMC24xxx
 EEPROM関数ライブラリを使用する為に必要な宣言(初期化)を行います。
 24xx1024でA2=0ならブロック0、A2=1ならブロック1が使用されますが、[Read2][Write2]関数を
 使用する場合は0/1は関係ないです。
 skMC24xxx MEM(A0,A1,A2) ;
  A0 :チップ選択ビットA0ピンの情報を設定します。(1=High 0=Low)
  A1 :チップ選択ビットA1ピンの情報を設定します。(1=High 0=Low)
  A2 :チップ選択ビットA2ピンの情報を設定します。(1=High 0=Low)
 MEMの名前は任意に変更可能です。
 例)上記配線図の黄色線の場合での設定例です
     skMC24xxx MEM(0,0,0) ;        // EEPROM関数の生成を行う
 skMC24xxx MEM(0,0,0) ; 以下はこの宣言例で記述します。

ans = MEM.Read(adrs,*data,num)
ans = MEM.Read2(adrs,*data,num) *2)
 EEPROMの指定番地から指定した個数だけデータを読み出す処理です。
  adrs  :読み出し開始のデータアドレス位置を指定します。(24LC256なら0〜32767番地)
  *data:読み出したデータを保存する為の配列変数を指定します。
  num  :読み出すデータの個数を指定します。(この個数分だけ配列変数は確保します)
  ans   :戻り値    0=正常終了、それ以外はI2C通信エラーです
             1=送ろうとしたデータが送信バッファのサイズを超えた
             2=スレーブ・アドレスを送信し、NACKを受信した
             3=データ・バイトを送信し、NACKを受信した
             4=その他のエラー
             5=データ受信エラー
 例)0番地から2バイト読み込み、シリアルモニターに表示する
     int ans ;
     char dt[4] ;

     ans = MEM.Read(0x00,dt,2) ;
     if (ans == 0) {
          Serial.print(dt[0],HEX) ;
          Serial.print(' ') ;
          Serial.print(dt[1],HEX) ;
     } else {
          Serial.print("EEPROM Read Error ans=") ;
          Serial.println(ans) ;
     }
 ※ 32766番地から4バイト読み出した場合は、[32766][32767][0][1]番地と言った感じに0番地に
   戻って読み出されます。
 ※ 24xx1024なら0〜131071番地までアクセス可能です、但し[Read2][Write2]を使った場合です。 *2)

ans = MEM.Write(adrs,*data,num)
ans = MEM.Write2(adrs,*data,num) *2)
 EEPROMの指定番地へ指定した個数だけデータを書き込む処理です。
  adrs  :書き込み開始のデータアドレス位置を指定します。(24LC256なら0〜32767番地)
  *data:書き込むデータを保存した配列変数を指定します。
  num  :書き込むデータの個数を指定します。
  ans   :戻り値    0=正常終了、それ以外はI2C通信エラーです
             1=送ろうとしたデータが送信バッファのサイズを超えた
             2=スレーブ・アドレスを送信し、NACKを受信した
             3=データ・バイトを送信し、NACKを受信した
             4=その他のエラー
             5=データ受信エラー

  注意)書き込む個数(num)はデバイスのページサイズ以上は連続書き込みは出来ません。
     (24xx32/64は32byte 24xx128/256は64byte 24xx512/1024は128byte)
 例)0番地から2バイト書き込む
     int ans ;
     char dt[4] ;

     dt[0] = 1 ;
     dt[1] = 2 ;
     ans = MEM.Write(0x00,dt,2) ;
     if (ans == 0) {
          Serial.println("EEPROM Write Success") ;
     } else {
          Serial.print("EEPROM Write Error ans=") ;
          Serial.println(ans) ;
     }
 ※ 32767番地を超えた場合は捨てられます、また、送信データは一旦ページバッファに保存され、
   ストップコンディション発行で実際にメモリに書き込まれます、だから、ページサイズ以上のデータ
   を送信したらバッファの先頭から上書きされその内容がメモリに書き込まれます。
   (書き込みには"Write cycle time (byte or page) 5ms"かかります。)
 ※ WPピンの書き込み禁止状態で書き込んだ場合、メモリには書き込まれませんが、
   書き込み通信は正常に終了するので注意が必要かもね。

 注意 ArduinoのWireライブラリの送受信バッファが32バイトしか有りません、
     だからEEPROMに読み書きするサイズはページサイズに関係なく32バイトMAXです。


整数型(int)で読み書きする技
 上のMEM.Read/MEM.Writeはバイト単位(char)で読み書きを行いますが、
 この関数で整数型(int)でも読み書き出来ます。
下の例はint型で書き込んでint型で読み込んでいます、int型は2バイトですね、だから

     int dt ;

     dt = 123 ;
     ans = MEM.Write(0x00,&dt,2) ;   // 書き込み
     ans = MEM.Read(0x00,&dt,2) ;    // 読み込み

ってやればOKです、当然int型で書き込んだらint型で読み込まないとだめですよ。

《その他》

ここの記事では"複数のデバイスに対する連続アドレッシング"には対応していません、
単品デバイスに対するアクセスのみです。

24FC1025を24FC1024と思って記事が24xx1024となっていますが変更するのがメンドイので、
ここのサイトではこのまま行きます。m(_ _)m

・ EEPROM(AT93C86)とArduinoを接続した記事はこちらを参照下さい。
・ 24LC256/1024とPIC(16F1827)を接続した記事はこちらを参照下さい。



リンク切れ見直し(*4) 2017/01/10
Write2/Read2のバグを修正(*3) 2014/11/01
24xx1024を追記(*2) 2014/09/19
追記(*1) 2012/09/14


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2017 Shigehiro Kimura All Rights Reserved.