MSP430G2553 - FRAM (FeRAM)
概要
FRAM / FeRAM (Ferroelectric Random Access Memory)は、強誘電体材料を使用して情報を記憶して、電界の向きによって分極状態を変化させてデータを保存するメモリである。
多くのFRAM製品は、SPIやI2Cインターフェースを採用している。
FRAMは、高速性、低消費電力、高い信頼性が求められる用途で特に有用である。
ただし、大容量のストレージが必要な場合は他の選択肢も検討する必要がある。
この技術は継続的に発展しており、将来的にはさらに広い分野での採用が期待されている。
FRAMには、以下に示すような特徴がある。
- 不揮発性
- 電源を切ってもデータが保持される。
- 高速書き込み
- EEPROMやフラッシュROMより大幅に高速である。
- 低消費電力
- 書き込み時のエネルギー消費が少ない。
- 高い書き換え回数
- 10^12〜10^15回 (1兆〜1000兆回) 程度の書き換えが可能である。
他のメモリとの比較して、FRAMは以下に示すようなメリットがある
- SRAMより低速であるが、不揮発性がある。
- EEPROMより高速で、書き換え回数が多い。
- フラッシュROMより高速で、バイト単位のアクセスが可能である。
FRAMが採用されている用途を、以下に示す。
- 組み込みシステム
- スマートメーター
- 自動車用電子機器
- 産業用機器
FRAMのメリットを以下に示す。
- 信頼性が高い。
- 放射線耐性がある。
- 広い動作温度範囲
FRAMのデメリットを以下に示す。
- 容量あたりのコストが比較的高い。
- 大容量化が難しい。
FRAMの種類
一般的に、外付けのFRAMとして使用されているデバイスには、以下のようなものがある。
MSP430G2553マイコンで使用できるFRAMについては、いくつかの選択肢がある。
- I2C対応のFRAMの例
- Cypress (現Infineon)
- FM24シリーズ
- FM24CL04B, FM24CL16B, FM24CL64B
- Fujitsu (現Lapis)
- MB85RCシリーズ
- MB85RC256V, MB85RC512T
- Cypress (現Infineon)
- SPI対応のFRAMの例
- Cypress (現Infineon)
- FM25シリーズ
- FM25V05 (512Kbit, 64K x 8), FM25V10 (1Mbit, 128K x 8), FM25W256: 256Kbit (32K x 8)
- Fujitsu (現Lapis)
- MB85RSシリーズ
- MB85RS1MT (1Mbit, 128K x 8), MB85RS2MT (2Mbit, 256K x 8), MB85RS4MT (4Mbit, 512K x 8)
- Rohm
- MR45V100A (1Mbit, 128K x 8), MR48V256A (256Kbit, 32K x 8)
- Cypress (現Infineon)
これらのFRAMは、一般的に、I2CインターフェースまたはSPIインターフェースでMSP430G2553マイコンに接続できる。
MSP430G2553マイコンはI2C通信およびSPI通信をサポートしているため、これらのFRAMとの通信が可能である。
FRAMを選択する時の主な考慮点を、以下に示す。
- 容量
- 必要なストレージ容量に応じて選択する。
- 動作電圧
- MSP430G2553マイコンの動作電圧範囲と合致するもの。
- 通信速度
- I2Cの速度に対応しているかどうか。
- パッケージ
- 基板設計に適したものかどうか。
具体的な製品を選択する場合は、データシートを確認して、MSP430G2553マイコンとの互換性を確認することが重要である。
SPI通信が可能なFRAMの特徴を、以下に示す。
- 高速通信
- 多くのSPI通信が可能なFRAMは、20[MHz]以上のクロック周波数をサポートしている。
- 簡単な接続
- 通常4本の信号線 (SCLK, MOSI, MISO, CS) で接続できる。
- フルデュプレックス通信
- 同時に送受信が可能である。
- 複数デバイスの接続
- チップセレクト (CS) 線を使用して、複数のデバイスを制御できる。
- 低消費電力
- 特に待機時の消費電力が非常に低い。
- 高い信頼性
- EEPROMやフラッシュROMと比較して、書き換え回数が非常に多い。
SPI通信が可能なFRAMを選択するメリットを、以下に示す。
- I2Cと比較して高速な通信が可能。
- ノイズに強い。 (ただし、短距離通信の場合)
- プロトコルがシンプル。
- 多くのマイコンがハードウェアSPIをサポートしている。
SPI通信が可能なFRAMを使用する場合は、使用するマイコンのSPIインターフェースの仕様と、選択するFRAMのデータシートを確認して、適切な通信設定を行うことが重要である。
また、SPIモードの設定 (クロックのポラリティとフェーズ) にも注意が必要である。
MSP430G2553マイコンでSPI通信が可能なFRAMを使用する場合、USIモジュールを使用して、SPI通信を実装することができる。
FM24CL04B, FM24CL16B, FM24CL64B (I2C FRAM)
- Microchip社製の不揮発性メモリ
- I2Cインターフェースを使用
- 32[KB] (256[Kbit]) の容量
- 低消費電力で動作
MB85RC256V, MB85RC512T (I2C FRAM)
- 富士通の不揮発性メモリ
- I2Cインターフェースを使用
- 8[KB] (64[Kbit]) の容量
- 高速動作が可能
サンプルコード
FM24CL04B, FM24CL16B, FM24CL64B (I2C)
以下の例では、MSP430G2553マイコンとFM24CL16BまたはFM24CL64B (FRAM) を使用してデータを読み書きしている。
- I2C通信を初期化する。
- FRAMのアドレス0x00から4バイトのデータを書き込む。
- 100[mS]待機する。
- FRAMのアドレス0x00から4バイトのデータを読み出す。
#include <msp430g2553.h>
#define FRAM_ADDR 0x50 // FRAMのI2Cアドレス
void initI2C(void);
void I2C_write(unsigned char addr, unsigned char *data, unsigned int len);
void I2C_read(unsigned char addr, unsigned char *data, unsigned int len);
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // ウォッチドッグタイマを停止
initI2C(); // I2Cの初期化
// 書き込むデータ
unsigned char writeData[] = {0x12, 0x34, 0x56, 0x78};
// 読み出し用バッファ
unsigned char readData[4];
// FRAMに4バイトのデータを書き込む (アドレス0x00から)
I2C_write(0x00, writeData, 4);
// 100[mS]待機
__delay_cycles(100000);
// FRAMから4バイトのデータを読み出す (アドレス0x00から)
I2C_read(0x00, readData, 4);
while(1);
}
void initI2C(void)
{
P1SEL |= BIT6 + BIT7; // P1.6 = SCL, P1.7 = SDA
P1SEL2 |= BIT6 + BIT7;
UCB0CTL1 |= UCSWRST; // UCB0をリセット状態に
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2Cマスターモード
UCB0CTL1 = UCSSEL_2 + UCSWRST; // SMCLKを選択
UCB0BR0 = 12; // fSCL = SMCLK / 12 = 100[kHz]
UCB0BR1 = 0;
UCB0I2CSA = FRAM_ADDR; // スレーブアドレスをセット
UCB0CTL1 &= ~UCSWRST; // UCB0のリセットを解除
}
void I2C_write(unsigned char addr, unsigned char *data, unsigned int len)
{
while (UCB0CTL1 & UCTXSTP); // 前の通信が終了するまで待機
UCB0CTL1 |= UCTR + UCTXSTT; // 送信モード、スタートコンディション
while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機
UCB0TXBUF = addr; // メモリアドレスを送信
while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機
while (len--) {
UCB0TXBUF = *data++; // データを送信
while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機
}
UCB0CTL1 |= UCTXSTP; // ストップコンディション
while (UCB0CTL1 & UCTXSTP); // ストップコンディションが送信されるまで待機
}
void I2C_read(unsigned char addr, unsigned char *data, unsigned int len)
{
while (UCB0CTL1 & UCTXSTP); // 前の通信が終了するまで待機
UCB0CTL1 |= UCTR + UCTXSTT; // 送信モード、スタートコンディション
while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機
UCB0TXBUF = addr; // メモリアドレスを送信
while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機
UCB0CTL1 &= ~UCTR; // 受信モードに切り替え
UCB0CTL1 |= UCTXSTT; // リスタートコンディション
while (UCB0CTL1 & UCTXSTT); // スタートコンディションが送信されるまで待機
while (len--) {
while (!(IFG2 & UCB0RXIFG)); // RXバッファにデータが来るまで待機
*data++ = UCB0RXBUF; // データを読み出し
if (len == 0)
UCB0CTL1 |= UCTXSTP; // 最後のバイトを読み出す前にストップコンディションを送信
}
while (UCB0CTL1 & UCTXSTP); // ストップコンディションが送信されるまで待機
}
100[mS]の遅延を入れている理由を、以下に示す。
- 書き込み完了の保証
- F-RAMは非常に高速であるが、書き込み操作が完全に終了するまでに短い時間が必要な場合がある。
- デバッグや動作確認
- プログラムの動作を人間のタイムスケールで確認しやすくする。
- 電気的な安定性
- 書き込み後にシステムが電気的に安定するための時間を確保する。
- 連続アクセスの回避
- FRAMへの連続的なアクセスを避けて、デバイスに「休憩」を与える。
ただし、実際の設計では、この長い遅延は必ずしも必要ではない。
FRAMは、一般的に、マイクロ秒オーダーで書き込みを完了するため、実運用では以下のような方法を検討できる。
- 遅延時間の短縮
- 例えば、1[mS]の遅延に短縮する。
- ポーリングによる完了確認
- FRAMの状態レジスタを読み取り、書き込み完了を確認する。
- 遅延の除去
- 多くの場合、FRAMは遅延なしで連続アクセスが可能である。
- 割り込みの使用
- I2C通信完了の割り込みを使用して、効率的に次の操作に移行する。
※注意
- FRAMのI2Cアドレス (FRAM_ADDR) は、使用するデバイスによって異なる場合があるため、データシートで確認すること。
- 実務で使用する場合は、エラー処理やタイムアウト処理を追加することを推奨する。
- FRAMの容量に応じて、アドレス指定の方法を調整する必要がある。
MB85RC256V, MB85RC512T (I2C)
以下の例では、MSP430G2553マイコンとMB85RC256VまたはMB85RC512T (FRAM) を使用してデータを読み書きしている。
このデバイスもI2Cインターフェースを使用するが、アドレス指定方法が少し異なる。
- アドレス指定
- MB85RC256V, MB85RC512Tは、16ビットのアドレス指定を使用する。
- I2C_write関数およびI2C_read関数において、アドレスを2バイトに分けて送信している。
- デバイスアドレス
- FRAM_ADDRを0x50としているが、実際のアドレスは製品とピン接続により異なる場合がある。
- 待機時間
- FRAMは高速であるため、書き込み後の待機時間を1[mS]にしている。
- 実際には、この待機も不要な場合がある。
- エラー処理
- 以下の例では、エラー処理が記述されていない。
- 実務では、通信エラーの検出と処理を追加することを推奨する。
- クロック周波数
- I2C通信のクロック周波数は約100[kHz]に設定している。
- FRAMはより高速な通信も可能であるが、MSP430G2553マイコンの制限を考慮している。
#include <msp430g2553.h>
#define FRAM_ADDR 0x50 // FRAMのI2Cアドレス (下位3ビットは可変)
void initI2C(void);
void I2C_write(unsigned int addr, unsigned char *data, unsigned int len);
void I2C_read(unsigned int addr, unsigned char *data, unsigned int len);
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // ウォッチドッグタイマを停止
initI2C(); // I2Cの初期化
// 書き込むデータ
unsigned char writeData[] = {0x12, 0x34, 0x56, 0x78};
// 読み出し用バッファ
unsigned char readData[4];
// FRAMにデータを書き込む (アドレス0x0100から)
I2C_write(0x0100, writeData, 4);
// 1[mS]待機 (FRAMは高速であるため、長い待機時間は不要)
__delay_cycles(1000);
// FRAMからデータを読み出す (アドレス0x0100から)
I2C_read(0x0100, readData, 4);
while(1);
}
void initI2C(void)
{
P1SEL |= BIT6 + BIT7; // P1.6 = SCL, P1.7 = SDA
P1SEL2 |= BIT6 + BIT7;
UCB0CTL1 |= UCSWRST; // UCB0をリセット状態に
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2Cマスターモード
UCB0CTL1 = UCSSEL_2 + UCSWRST; // SMCLKを選択
UCB0BR0 = 12; // fSCL = SMCLK / 12 = ~100kHz (SMCLKが1[MHz]の場合)
UCB0BR1 = 0;
UCB0I2CSA = FRAM_ADDR; // スレーブアドレスをセット
UCB0CTL1 &= ~UCSWRST; // UCB0のリセットを解除
}
void I2C_write(unsigned int addr, unsigned char *data, unsigned int len)
{
while (UCB0CTL1 & UCTXSTP); // 前の通信が終了するまで待機
UCB0CTL1 |= UCTR + UCTXSTT; // 送信モード、スタートコンディション
while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機
UCB0TXBUF = (addr >> 8) & 0xFF; // アドレス上位バイトを送信
while (!(IFG2 & UCB0TXIFG));
UCB0TXBUF = addr & 0xFF; // アドレス下位バイトを送信
while (!(IFG2 & UCB0TXIFG));
while (len--) {
UCB0TXBUF = *data++; // データを送信
while (!(IFG2 & UCB0TXIFG));
}
UCB0CTL1 |= UCTXSTP; // ストップコンディション
while (UCB0CTL1 & UCTXSTP); // ストップコンディションが送信されるまで待機
}
void I2C_read(unsigned int addr, unsigned char *data, unsigned int len)
{
while (UCB0CTL1 & UCTXSTP); // 前の通信が終了するまで待機
UCB0CTL1 |= UCTR + UCTXSTT; // 送信モード, スタートコンディション
while (!(IFG2 & UCB0TXIFG));
UCB0TXBUF = (addr >> 8) & 0xFF; // アドレス上位バイトを送信
while (!(IFG2 & UCB0TXIFG));
UCB0TXBUF = addr & 0xFF; // アドレス下位バイトを送信
while (!(IFG2 & UCB0TXIFG));
UCB0CTL1 &= ~UCTR; // 受信モードに切り替え
UCB0CTL1 |= UCTXSTT; // リスタートコンディション
while (UCB0CTL1 & UCTXSTT); // スタートコンディションが送信されるまで待機
while (len--) {
while (!(IFG2 & UCB0RXIFG)); // RXバッファにデータが来るまで待機
*data++ = UCB0RXBUF; // データを読み出し
if (len == 0)
UCB0CTL1 |= UCTXSTP; // 最後のバイトを読み出す前にストップコンディションを送信
}
while (UCB0CTL1 & UCTXSTP); // ストップコンディションが送信されるまで待機
}
※注意
- 実際のデバイスアドレスを確認して、必要に応じてFRAM_ADDRマクロを調整すること。
- MB85RC256V, MB85RC512Tでは、最大アドレス範囲が異なるため、使用するデバイスの容量に注意する必要がある。
- 電源電圧やI2Cプルアップ抵抗等、ハードウェア設定も適切に行うこと。