概要

EEPROM (Electrically Erasable Programmable Read-Only Memory) は、電気的に消去、書き込み可能な不揮発性メモリの1種である。

EEPROMの主な特徴を以下に示す。

  • 不揮発性
    電源を切ってもデータを保持できる。
  • 書き換え可能
    データの消去と書き込みを電気的に行うことができる。
  • バイト単位のアクセス
    バイト単位でデータの読み書きが可能である。
  • 書き換え回数の制限
    一般的に、100万回程度の書き換えが可能である。
  • 低速
    フラッシュメモリ等と比較して、読み書きの速度が遅い。
  • シリアル通信
    I2CやSPI等のシリアル通信インターフェースを使用して、マイクロコントローラと通信する。
  • 容量
    数[Kbit]〜数[Mbit]までの容量のデバイスが存在する。
  • 用途
    設定情報や較正データの保存、データロガー、小容量のデータ保存等に使用される。


EEPROMは、マイコンのシステムで、不揮発性のデータ保存が必要な場合に広く使用されている。
フラッシュメモリと比較して書き換え回数が多く、バイト単位のアクセスが可能な点が特徴である。

ただし、書き換え速度が遅く、大容量のデータ保存には向かない。
また、書き換え回数にも制限があるため、頻繁に更新されるデータの保存には適していない。

したがって、用途に応じて、EEPROM、フラッシュメモリ、SRAM等の他のメモリデバイスを使い分ける必要がある。
マイコンの内蔵メモリでデータ保存が可能な場合は、外付けのEEPROMを使用しないこともある。

EEPROMは、マイコンのシステムにおいて、小容量の不揮発性データ保存が必要な場合に重要な役割を果たすデバイスである。


EEPROMの種類

一般的に、外付けのEEPROMとして使用されているデバイスには、以下に示すようなものがある。

以下に示すEEPROMは、MSPM0G3519マイコンのI2CまたはSPIインターフェースに直接接続して使用することができる。
容量や速度、インターフェースの種類などの要件に応じて選択する。

特に、24LC256は、比較的大容量でI2Cインターフェースを備えているため、MSPM0G3519マイコンの組み合わせで広く使用されている人気の高いEEPROMの1つである。

24LC256 (256Kbit I2C EEPROM)

  • Microchip社製の不揮発性メモリ
  • I2Cインターフェースを使用
  • 32[KB] (256[Kbit]) の容量
  • 低消費電力で動作


25LC640A (64Kbit SPI EEPROM)

  • Microchip社製の不揮発性メモリ
  • SPIインターフェースを使用
  • 8[KB] (64[Kbit]) の容量
  • 高速動作が可能


AT24C32 (32Kbit I2C EEPROM)

  • Atmel (現Microchip) 社製の不揮発性メモリ
  • I2Cインターフェースを使用
  • 4[KB] (32[Kbit]) の容量
  • industryグレードの信頼性



MSPM0G3519とEEPROMの接続

MSPM0G3519マイコンは、ARM Cortex-M0+コアを搭載し、最大80[MHz]で動作する32ビットマイコンである。
専用のI2C0、I2C1、SPI0、SPI1ペリフェラルを使用してI2CまたはSPI通信を行うことができる。

I2C接続

MSPM0G3519のI2Cペリフェラルを使用する場合、以下のようなピン配置が可能である。

I2C0を使用する例
ピン名 機能
PA0 I2C0_SDA (I2Cデータライン)
PA1 I2C0_SCL (I2Cクロックライン)


I2C1を使用する例
ピン名 機能
PA28 I2C1_SDA (I2Cデータライン)
PA31 I2C1_SCL (I2Cクロックライン)
または
PA30 - I2C1_SCL


MSPM0G3519では、ピンの機能はIOMMUX (I/O Multiplexer) により設定される。
SysConfigツールを使用することで、グラフィカルなインターフェースでピンの設定を行うことができる。

※注意
I2C通信では、SDAとSCLの両方のラインに外部プルアップ抵抗 (通常4.7[kΩ]~10[kΩ]) が必要である。
複数のデバイスをI2Cバスに接続する場合は、それぞれのデバイスに異なるアドレスを設定する。

SPI接続

MSPM0G3519のSPIペリフェラルを使用する場合、以下のようなピン配置が可能である。

SPI0を使用する例
ピン名 機能
PA5 SPI0_PICO (Controller Out Target In)
PA4 SPI0_POCI (Controller In Target Out)
PA6 SPI0_SCK (SPIクロック)
PA3 SPI0_CS0 (チップセレクト)


SPI1を使用する例
ピン名 機能
PA17 SPI1_SCK (SPIクロック)
PA16 SPI1_POCI (Controller In Target Out)
PA15 SPI1_CS2 (チップセレクト)


SPI通信では、チップセレクト (CS) 信号は通常のGPIOピンを使用して制御することも可能である。
複数のSPIデバイスを接続する場合は、それぞれに異なるCSピンを割り当てる。

MSPM0G3519では、ピンの機能はIOMMUX (I/O Multiplexer) によって設定される。
SysConfigツールを使用することで、グラフィカルなインターフェースでピンの設定を行うことができる。


サンプルコード

24LC256 (256Kbit I2C EEPROM)

以下の例では、I2C通信を使用してEEPROMとの通信を行っている。
MSPM0 SDKのDriverLibを使用してI2C通信を実装している。

  1. ti_msp_dl_config.h (SysConfigで生成)をインクルードすることで、ペリフェラルの設定が自動的に行われる。
    SysConfigツールでI2Cペリフェラルの設定を行うことで、初期化コードが自動生成される。

  2. I2C_writeData関数を使用して、指定したアドレスにデータを書き込む。
    (DriverLibのDL_I2C関数群を使用)

  3. I2C_readData関数を使用して、指定したアドレスからデータを読み出す。
    (DriverLibのDL_I2C関数群を使用)


実際に動作させる場合は、回路の接続や電源の供給等にも注意が必要である。
特に、I2C通信では、SDAとSCLのラインに4.7[kΩ]~10[kΩ]のプルアップ抵抗を接続する必要がある。

このサンプルコードでは、SysConfigツールで以下の設定を行うことを前提としている:

  • I2C0ペリフェラルを有効化
  • PA0をI2C0_SDA、PA1をI2C0_SCLに設定
  • I2Cクロック周波数を100[kHz] (標準モード) または400[kHz] (高速モード) に設定
  • I2Cコントローラモードを有効化


 #include "ti_msp_dl_config.h"
 
 // 24LC256のI2Cアドレス
 // 24LC256のA0, A1, A2ピンがGNDに接続されている場合
 #define EEPROM_ADDRESS 0x50
 
 // グローバル変数
 uint8_t gTxData[3];  // アドレス(2バイト) + データ(1バイト)
 uint8_t gRxData[1];
 
 // 関数プロトタイプ
 void I2C_writeData(uint16_t address, uint8_t data);
 uint8_t I2C_readData(uint16_t address);
 
 int main(void)
 {
     // SysConfigで生成された初期化関数を呼び出す
     SYSCFG_DL_init();
 
     uint8_t data = 0xAA;          // 書き込むデータ
     uint16_t address = 0x0010;    // EEPROMのメモリアドレス
 
     // EEPROMにデータを書き込み
     I2C_writeData(address, data);
 
     // 書き込み完了待機 (約5[ms])
     delay_cycles(400000);  // 80[MHz]動作時、約5[ms]
 
     // EEPROMからデータを読み出し
     uint8_t read_data = I2C_readData(address);
 
     while(1)
     {
         // メインループ
     }
 }
 
 void I2C_writeData(uint16_t address, uint8_t data)
 {
     // 送信データの準備
     gTxData[0] = (address >> 8) & 0xFF;  // アドレス上位バイト
     gTxData[1] = address & 0xFF;         // アドレス下位バイト
     gTxData[2] = data;                   // データ
 
     // I2Cコントローラのアドレスとデータ長を設定
     DL_I2C_fillControllerTXFIFO(I2C_0_INST, &gTxData[0], 3);
 
     // 書き込み開始 (スタートコンディション + アドレス + データ)
     while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
 
     DL_I2C_startControllerTransfer(I2C_0_INST, EEPROM_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_TX, 3);
 
     // 転送完了待機
     while (DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
 
     // ストップコンディションの確認
     while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
 }
 
 uint8_t I2C_readData(uint16_t address)
 {
     // アドレス送信用データの準備
     gTxData[0] = (address >> 8) & 0xFF;  // アドレス上位バイト
     gTxData[1] = address & 0xFF;         // アドレス下位バイト
 
     // アドレスを書き込み
     DL_I2C_fillControllerTXFIFO(I2C_0_INST, &gTxData[0], 2);
 
     while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
 
     // アドレス送信 (ストップコンディションなし)
     DL_I2C_startControllerTransfer(I2C_0_INST, EEPROM_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_TX, 2);
 
     // 転送完了待機
     while (DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
 
     // 再スタートコンディションでデータ読み出し
     while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
 
     DL_I2C_startControllerTransfer(I2C_0_INST, EEPROM_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_RX, 1);
 
     // データ受信完了待機
     while (DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
 
     // 受信データの読み出し
     gRxData[0] = DL_I2C_receiveControllerData(I2C_0_INST);
 
     return gRxData[0];
 }


25LC640A (64Kbit SPI EEPROM)

以下の例では、SPI通信を使用してEEPROMとの通信を行っている。
MSPM0 SDKのDriverLibを使用してSPI通信を実装している。

  1. ti_msp_dl_config.h (SysConfigで生成)をインクルードすることで、ペリフェラルの設定が自動的に行われる。
    SysConfigツールでSPIペリフェラルの設定を行うことで、初期化コードが自動生成される。

  2. EEPROM_writeData関数を使用して、指定したアドレスにデータを書き込む。
    WRENコマンドで書き込み有効化して、WRITEコマンドでアドレスとデータを送信する。

  3. EEPROM_readData関数を使用して、指定したアドレスからデータを読み出す。
    READコマンドでアドレスを送信して、データを受信する。


実際に動作させる場合は、回路の接続や電源の供給等にも注意が必要である。
特に、25LC640AのCS (チップセレクト) ピンは、適切なポートピンに接続して、ソースコード内で設定する必要がある。

以下の例では、SysConfigツールで以下の設定を行うことを前提としている。

  • SPI0ペリフェラルを有効化
  • PA5をSPI0_PICO、PA4をSPI0_POCI、PA6をSPI0_SCKに設定
  • SPIクロック周波数を適切に設定 (例 : 4[MHz])
  • SPIコントローラモードを有効化
  • クロック極性 (CPOL) と位相 (CPHA) を設定 (通常、CPOL=0, CPHA=0)
  • PA3をGPIO出力として設定 (チップセレクト用)


 #include "ti_msp_dl_config.h"
 
 // CSピンの定義
 #define EEPROM_CS_PORT     GPIOA
 #define EEPROM_CS_PIN      DL_GPIO_PIN_3
 
 #define CS_LOW()    DL_GPIO_clearPins(EEPROM_CS_PORT, EEPROM_CS_PIN)
 #define CS_HIGH()   DL_GPIO_setPins(EEPROM_CS_PORT, EEPROM_CS_PIN)
 
 // SPI EEPROM命令コード
 #define EEPROM_CMD_READ     0x03
 #define EEPROM_CMD_WRITE    0x02
 #define EEPROM_CMD_WREN     0x06
 #define EEPROM_CMD_RDSR     0x05
 
 // 関数プロトタイプ
 uint8_t SPI_transfer(uint8_t data);
 void EEPROM_writeData(uint16_t address, uint8_t data);
 uint8_t EEPROM_readData(uint16_t address);
 uint8_t EEPROM_readStatus(void);
 void EEPROM_waitReady(void);
 
 int main(void)
 {
     // SysConfigで生成された初期化関数を呼び出す
     SYSCFG_DL_init();
 
     // CSピンを初期状態 (HIGH) に設定
     CS_HIGH();
 
     uint8_t data = 0xAA;          // 書き込むデータ
     uint16_t address = 0x1000;    // EEPROMのメモリアドレス
 
     // EEPROMにデータを書き込み
     EEPROM_writeData(address, data);
 
     // EEPROMからデータを読み出し
     uint8_t read_data = EEPROM_readData(address);
 
     while(1)
     {
        // メインループ
     }
 }
 
 uint8_t SPI_transfer(uint8_t data)
 {
     // 送信データをTXバッファに書き込み
     DL_SPI_transmitData8(SPI_0_INST, data);
 
     // 送信完了待機
     while (DL_SPI_isBusy(SPI_0_INST));
 
     // 受信データを読み出し
     return DL_SPI_receiveData8(SPI_0_INST);
 }
 
 uint8_t EEPROM_readStatus(void)
 {
     uint8_t status;
 
     CS_LOW();                               // EEPROM選択
     SPI_transfer(EEPROM_CMD_RDSR);          // ステータス読み込みコマンド送信
     status = SPI_transfer(0xFF);            // ステータス値受信
     CS_HIGH();                              // EEPROM非選択
 
     return status;
 }
 
 void EEPROM_waitReady(void)
 {
     // WIPビット (Write In Progress) が0になるまで待機
     while (EEPROM_readStatus() & 0x01)
     {
        delay_cycles(8000);  // 約100[μs]待機 (80[MHz]動作時)
     }
 }
 
 void EEPROM_writeData(uint16_t address, uint8_t data)
 {
     // 前回の書き込み完了待機
     EEPROM_waitReady();
 
     // 書き込み有効化コマンド送信
     CS_LOW();
     SPI_transfer(EEPROM_CMD_WREN);
     CS_HIGH();
 
     delay_cycles(800);  // 短い待機 (約10[μs])
 
     // 書き込みコマンド送信
     CS_LOW();
     SPI_transfer(EEPROM_CMD_WRITE);        // 書き込みコマンド
     SPI_transfer((address >> 8) & 0xFF);   // アドレス上位バイト
     SPI_transfer(address & 0xFF);          // アドレス下位バイト
     SPI_transfer(data);                    // データ
     CS_HIGH();
 
     // 書き込み完了待機
     EEPROM_waitReady();
 }
 
 uint8_t EEPROM_readData(uint16_t address)
 {
     uint8_t data;
 
     // 書き込み完了待機
     EEPROM_waitReady();
 
     // 読み出しコマンド送信
     CS_LOW();
     SPI_transfer(EEPROM_CMD_READ);         // 読み出しコマンド
     SPI_transfer((address >> 8) & 0xFF);   // アドレス上位バイト
     SPI_transfer(address & 0xFF);          // アドレス下位バイト
     data = SPI_transfer(0xFF);             // データ受信
     CS_HIGH();
 
     return data;
 }


AT24C32 (32Kbit I2C EEPROM)

AT24C32 EEPROMを使用してI2C通信する場合は、上記の24LC256のサンプルプログラムとほぼ同じとなる。
これは、AT24C32と24LC256がどちらもI2Cインターフェースを使用しており、通信プロトコルが同一だからである。

主な違いは、EEPROMの容量とアドレッシングである。

  • 24LC256は、256[Kbit] (32[KB]) の容量を持ち、16ビットのアドレス (0x0000~0x7FFF) を使用する。
  • AT24C32は、32[Kbit] (4[KB]) の容量を持ち、12ビットのアドレス (0x000~0xFFF) を使用する。


AT24C32のアドレッシングは2バイトで行われるが、有効なアドレス範囲は0x000~0xFFFであり、上位4ビットは無視される。
したがって、24LC256向けのサンプルコードをそのままAT24C32で使用することができる。

ただし、EEPROMの容量が異なるため、アドレスの範囲に注意が必要である。
AT24C32の有効なアドレス範囲は、0x000~0xFFFであり、それ以外のアドレスを指定した場合の動作は未定義となることに注意する。

また、EEPROMのI2Cアドレスを確認して、必要に応じて、EEPROM_ADDRESSの定義を変更する必要がある。
AT24C32のデフォルトのI2Cアドレスは0x50 (A0、A1、A2がGNDに接続されている場合) だが、実装により異なる場合がある。


SysConfigツールの使用

MSPM0G3519の開発では、TI社が提供するSysConfigツールを使用することで、ペリフェラルの設定を簡単に行うことができる。

SysConfigツールの主な機能を以下に示す。

  • グラフィカルなインターフェースでペリフェラルを設定できる。
  • ピンの機能 (I2C、SPI、GPIO等) をドラッグ&ドロップで割り当てられる。
  • クロック周波数、通信速度などのパラメータを設定できる。
  • 設定に基づいて初期化コード (ti_msp_dl_config.h、ti_msp_dl_config.c) を自動生成する。
  • ピンの競合を自動的にチェックし、エラーを表示する。


SysConfigツールの使用方法を以下に示す。

  1. Code Composer Studio (CCS) でプロジェクトを作成する。
  2. プロジェクト内の .syscfg ファイルを開く。
  3. 必要なペリフェラル (I2C0、SPI0等) を追加する。
  4. ピン配置とパラメータを設定する。
  5. 保存すると、自動的に初期化コードが生成される。


上記の例では、SysConfigで生成されたSYSCFG_DL_init関数を呼び出すことにより、全てのペリフェラルが初期化される。
これにより、手動でレジスタを設定する必要がなくなり、開発効率が大幅に向上する。


注意事項

MSPM0G3519マイコンを使用してEEPROMと通信する場合には、以下に示す事柄に注意する。

共通

  • 電源電圧
    EEPROMの動作電圧範囲を確認し、MSPM0G3519の電源電圧と一致していることを確認する。MSPM0G3519の動作電圧は1.62V~3.6Vである。
  • デカップリングコンデンサ
    EEPROMの電源ピンの近くに、0.1[μF]のデカップリングコンデンサを配置する。
  • 配線長
    I2CおよびSPIの信号線は、できるだけ短く、かつノイズの影響を受けにくいように配線する。
  • エラー処理
    実際のアプリケーションでは、通信エラーや書き込みエラーに対する適切なエラー処理を実装する必要がある。
  • SysConfigツールの使用
    SysConfigツールを使用することで、ピンの設定やペリフェラルの初期化を簡単に行うことができる。特に複雑な設定が必要な場合に有用である。


I2C通信

  • プルアップ抵抗
    I2CのSDAとSCLのラインには、必ず外部プルアップ抵抗 (4.7[kΩ]~10[kΩ]) を接続する必要がある。MSPM0G3519の内部プルアップ抵抗を使用することもできるが、外部プルアップ抵抗の使用が推奨される。
  • クロック周波数
    I2C通信のクロック周波数は、標準モードで100[kHz]、高速モードで400[kHz]、FM+モードで1[MHz]までサポートされている。
  • 書き込み完了時間
    EEPROMへの書き込み後、内部書き込みサイクルが完了するまで約5[ms]の待機時間が必要である。
  • アドレッシング
    16ビットアドレスのEEPROMでは、アドレスを2バイトで送信する必要がある。
  • DMAの使用
    大量のデータを転送する場合は、DMAを使用することでCPU負荷を削減できる。


SPI通信

  • チップセレクト制御
    SPI通信では、通信前にCS信号をLOWに、通信後にHIGHにする必要がある。
  • クロック極性と位相
    SPIのクロック極性 (CPOL) と位相 (CPHA) は、EEPROMのデータシートに従って設定する必要がある。一般的に、CPOL=0、CPHA=0が使用される。
  • 書き込み有効化
    EEPROMへの書き込み前に、必ずWRENコマンドで書き込みを有効化する必要がある。
  • ステータス確認
    書き込み操作後、ステータスレジスタを読み取り、WIPビットが0になるまで待機する必要がある。
  • クロック周波数
    SPIのクロック周波数は、EEPROMのデータシートで指定された最大周波数を超えないように設定する。



MSPM0 SDKとDriverLib

MSPM0G3519の開発では、TI社が提供するMSPM0 SDKを使用することが推奨される。

MSPM0 SDKには以下に示すコンポーネントが含まれている。

  • DriverLib
    ペリフェラルを制御するための低レベルAPI
  • TI-Drivers
    より高レベルの抽象化を提供するドライバ (開発中)
  • サンプルコード
    各ペリフェラルの使用例を示すコード
  • ドキュメント
    データシート、ユーザガイド、APIリファレンス


DriverLibの主な特徴を以下に示す。

  • ARM CMSIS (Cortex Microcontroller Software Interface Standard) に準拠
  • 各ペリフェラルに対して直感的なAPIを提供
  • 最適化されたコードサイズとパフォーマンス
  • SysConfigツールと統合されている


DriverLibの関数名は、以下のような命名規則に従っている。

  • DL_[ペリフェラル名]_[機能名]
    例: DL_I2C_startControllerTransfer、DL_SPI_transmitData8


MSPM0 SDKは、Code Composer Studio (CCS) に統合されており、CCS経由でインストールできる。
また、TIのWebサイトからスタンドアロン版をダウンロードすることもできる。


開発環境

MSPM0G3519の開発には、以下に示すツールが使用できる。

統合開発環境 (IDE)

  • Code Composer Studio (CCS)
    TI社が提供する無償のIDE。SysConfigツールやデバッガが統合されている。
  • IAR Embedded Workbench
    高度な最適化機能を持つ。
  • Keil MDK
    ARM社のIDEで、CMSIS準拠のツールチェーン。


デバッグツール

  • XDS110
    低コストのデバッグプローブ
  • J-Link
    Segger社の高性能デバッグプローブ


その他のツール

  • SysConfig
    ペリフェラルの設定を行うグラフィカルツール
  • MSPM0 SDK
    DriverLib、サンプルコード、ドキュメントを含むソフトウェア開発キット
  • TI Resource Explorer
    CCS内でSDKのサンプルコードやドキュメントにアクセスできるツール。


開発フロー例

  1. Code Composer Studioをインストールする。
  2. MSPM0 SDKをインストールする。
  3. マイコン応用回路、または、LaunchPad開発キットを準備する。
  4. SysConfigでペリフェラルを設定する。
  5. アプリケーションを開発する。
  6. デバッガを使用してデバッグする。