(2017.8.30 作成)
(2017.10.21 修正)
(2018.7.19 修正)
EEPROMの概要についてはこちらに記載していますが、ここではAliexpressで安価に購入できるAT24C256について書きたいと思います。
本記事執筆時点では写真のモジュールが1個60円ぐらいで売っていますので、一つ買ってみるのが良いと思います。DIPタイプのEEPROMであればこのモジュールに他社のものにも付け替えられますので、何かと便利に使えるかと思います。
設定ですが写真の通りジャンパを右にすることで0(GND)になります。
WP(Write protect)ピンは1の場合書き込み禁止となります。通常は0固定で任意のタイミングで読み書きできるようにすればよいと思います。このモジュールの場合ジャンパを外し、中央のピンがWPピンになっています。
また、A0,A1ピンはI2Cアドレスを指定するために使用します。具体的にはI2Cアドレスの下位2ビットをこの両ピンで指定します。AT24C256の場合A2ピンは使用しません。
読み書きともコントロールバイトなどの指定はなく、上記で設定したI2Cアドレスに続いて2バイトのメモリアドレスを指定した後データを転送します。
読み込みと1バイト単位の書きこみについては特筆すべき点はなく、I2Cの規格に則ったアクセスで問題ないと思います。
一方連続したバイト列を書き込む際にはページの境界について考慮する必要があります。
ページは64バイト単位で区切られているのですがページを超えて連続データを書き込むことはできません。64バイト境界を越えて書き込もうとすると、低位アドレスに折り返して書き込まれてしまいます。
ちょっとわかりにくいのですが例えばアドレス62から5バイト連続して書こうとすると、アドレス62, 63, 0, 1, 2に書かれてしまいます。
これが起こらないように注意してプログラムを作成する必要があります。
以上のような点に注意して作成したEEPROM操作プログラムをこちらからダウンロードしていただけます。一つのクラスとしてまとまっており、連続した値を書こうとすると64バイト境界を意識して分割して書き込み動作を行います。
その他としてはスタンバイモードに入れるようにコマンドだけは作成してみました。ただ数mAの電流を検出できる環境がないので動作確認はしていないです。
少し長いですが、サンプルプログラムを以下に載せます。同様のコードでSTM32F103C8T6基板とArduinoUNOで動作することを確認しています。
Arduinoはダウンロードした中にサンプルプログラムが入っています。
使用しているBaseクラスなどはこちらからダウンロードできます。またSTM32やArduinoでの使い方はこちらに記載していますので、参考にして下さい。
ポイントとしては書き込み後、状況に応じて完了待ちを行う必要があります。以下のサンプルプログラムではWaitTillDeviceReadyコマンドにて完了待ちを行っています。
#include "DKS_Common_F103xB.h" #include "DKS_F103C8T6.h" #include "DKS_I2C_F103xB.h" #include "DKS_EEPROM.h" DKS::I2C::I2C *i2c; DKS::AT24C256 *eeprom; int main(void) { DKS::InitSystem(); DKS::STM32F103C8T6 board(DKS::BluePill); i2c = new DKS::I2C::I2C(I2C1); //SCL: PB6, SDA:PB7 eeprom = new DKS::AT24C256(i2c, 0b00); // A1=0, A0=0 // Write single byte uint8_t wByte = 0x12; uint8_t rByte(0); eeprom->write(0x01, &wByte, 1); eeprom->WaitTillDeviceReady(); eeprom->read(0x01, &rByte, 1); if (wByte != rByte) { board.led->write(1); while (true); } // sequential write const uint16_t length = 100; const uint32_t address = 60; uint16_t i; uint8_t *wBytes = new uint8_t[length]; uint8_t *rBytes = new uint8_t[length]; for (i = 0; i < length; i++) { wBytes[i] = i; rBytes[i] = 0; } eeprom->write(address, wBytes, length); eeprom->WaitTillDeviceReady(); eeprom->read(address, rBytes, length); for (i = 0; i < length; i++) { if (wBytes[i] != rBytes[i]) { board.led->write(1); while (true); } } DKS::Delay(3000); eeprom->Standby(); while (true) { board.led->toggle(); DKS::Delay(500); } }
日本のAmazonやパーツショップで通販購入するのに対して、Aliexperssで購入したほうが数分の一の価格で購入できます。