ホーム > カテゴリ > ロボット・電子工作・マイコン >

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モードとなります。

裏技で「8bitモード」に設定できます。6ピンのNC(未接続)をGNDに接続するだけです。サンプルスケッチはengboustaniさんのArduino-AT93C46-EEPROMにあるのでそれをコピペして先頭の「#define SS 53」を削除すると動作します。

スケッチ(プログラム)

アドレス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・ラズパイ等)でユーザー同士で情報を共有して下さい。

関連記事



公開日:2017年07月23日
記事NO:02490