EEPROM(Microwire版)の使い方 [Arduino]
EEPROMは電源をオフにしてもデータが消えない半導体メモリです。

Arduino UNOでは標準で1024byteのEEPROMがありますが、今回は外部のEEPROM(Microwire接続)を使用します。
Microwire(マイクロワイヤ)
Microwire接続はArduinoのSPIで接続可能です。
但し、通常のSPI接続だとSS(Slave Select pin)をLOWにしている間にデバイス間の処理を行い。処理が完了したらHIGHに戻します。本来はこの一連の作業ですが、MicrowireはLOWとHIGHが逆になっています。
その他に今回の「AT93C46A」は相性が悪い為かビット操作が必要です。
使用部品・材料
総額で約300円です。(Arduino本体の値段を除く)
部品/材料 | 値段 | 備考 |
---|---|---|
ブレッドボード | ¥270 | 秋月電子の通販コード(P-00315) |
3線式シリアルEEPROM AT93C46 ATMEL製 AT93C46(A)-10PI-2.7 | ¥30 | 秋月電子の通販コード(I-00694) |
配線図
通常のSPI接続のように4本を配線します。

次は秋月にある公式データシートより引用(AT93C46A.pdf)


6:NCはNot Connectionで未接続です。7:DCは説明が一切ありません。マルツのデータシートによると7:DUで「Don't Use」(使うな!)と強めに書いてあります。(恐らく、DC = Don't Conectかも!?)
AtmelのAT93C46A、AT93C46D、AT93C86、AT93C56は同じシリーズですので大体一緒です。また、秋月にあるデータシートと併せてマルツにあるデータシートの方も確認するとわかりやすいです。
モードとアドレスについて
今回の「AT93C46A」はデータシート(秋月)に記載されているモードは「16bitモード」のみです。このモードは2byte毎にデータを書き込み、読み込むモードとなります。アドレスは0番地から63番地までで最大128byte(64×2)の領域があります。
※今回ご紹介するスケッチは16bitモードとなります。
スケッチ(プログラム)
アドレス0番地から5番地までに「数値」を書き込みます。次にその番地から値を取得してシリアルモニターへ表示します。(2byte毎)
#include <SPI.h> // SCK : pin 13 (Serial ClocK) // MISO : pin 12 (Master In Slave Out) // MOSI : pin 11 (Master Out Slave In) // SS : pin 10 (Slave Select pin) void setup() { Serial.begin(9600); // SPIの初期化 // ※自動的に「SCK、MOSI、SSのピンの動作はOUTPUT」となり「SSはHIGH」となる SPI.begin(); // SPI転送モード // クロック位相(CPOL) = 0 クロック極性(CPHA) = 0 SPI.setDataMode(SPI_MODE0); // SPI送受信用のビットオーダー(MSBFIRST) SPI.setBitOrder(MSBFIRST); // SPIクロック分周器 2MHz = 16MHz/8 SPI.setClockDivider(SPI_CLOCK_DIV8); // 書き込みモードの設定 // ※Instruction Set(命令セット)は2byteで「ビットは右寄せ」です。 digitalWrite(SS, HIGH); // EWEN命令(書き込みの有効) SPI.transfer(0b00000001); SPI.transfer(0b00110000); // EWDS命令(書き込みの無効→読み込み専用) //SPI.transfer(0b00000001); //SPI.transfer(0b00000000); digitalWrite(SS, LOW); delay(10); // アドレス0番地から5番地までデータを書き込む uint8_t count =1; for (int i=0; i< 6; i++){ digitalWrite(SS, HIGH); // WRITE命令 + アドレス SPI.transfer(0b00000001); SPI.transfer(0b01000000 | i); // 2byte書き込む SPI.transfer(count++); SPI.transfer(count++); digitalWrite(SS, LOW); delay(10); } // アドレス0番地から5番地までデータを読み込む for (int i=0; i< 6; i++){ digitalWrite(SS, HIGH); // READ命令 + アドレス SPI.transfer(0b00000001); SPI.transfer(0b10000000 | i); delay(5); // ビットがずれているので3byteを取得する uint8_t b1 = SPI.transfer(0x00); uint8_t b2 = SPI.transfer(0x00); uint8_t b3 = SPI.transfer(0x00); // ビットを修正後、シリアルモニタへ出力 Serial.print(i); Serial.print("番地(H) = "); Serial.println((b1 << 1) | (b2 >> 7)); Serial.print(i); Serial.print("番地(L) = "); Serial.println(((b2 & 0b01111111) << 1) | (b3 >> 7)); digitalWrite(SS, LOW); } } void loop() { }
実行結果

掲示板
ArduinoやRaspberry Piなどの電子工作の掲示板を作成しました。質問やわからない事は電子工作 (Arduino・ラズパイ等)でユーザー同士で情報を共有して下さい。