📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

79行目: 79行目:


== サンプルコード ==
== サンプルコード ==
==== FM24CL04B, FM24CL16B, FM24CL64B ====
==== FM24CL04B, FM24CL16B, FM24CL64B (I2C) ====
以下の例では、MSP430G2553マイコンとFM24CL16BまたはFM24CL64B (FRAM) を使用してデータを読み書きしている。<br>
以下の例では、MSP430G2553マイコンとFM24CL16BまたはFM24CL64B (FRAM) を使用してデータを読み書きしている。<br>
<br>
<br>
198行目: 198行目:
* 実務で使用する場合は、エラー処理やタイムアウト処理を追加することを推奨する。
* 実務で使用する場合は、エラー処理やタイムアウト処理を追加することを推奨する。
* FRAMの容量に応じて、アドレス指定の方法を調整する必要がある。
* FRAMの容量に応じて、アドレス指定の方法を調整する必要がある。
<br>
==== MB85RC256V, MB85RC512T (I2C) ====
以下の例では、MSP430G2553マイコンとMB85RC256VまたはMB85RC512T (FRAM) を使用してデータを読み書きしている。<br>
このデバイスもI2Cインターフェースを使用するが、アドレス指定方法が少し異なる。<br>
<br>
* アドレス指定
*: MB85RC256V, MB85RC512Tは、16ビットのアドレス指定を使用する。
*: I2C_write関数およびI2C_read関数において、アドレスを2バイトに分けて送信している。
* デバイスアドレス
*: FRAM_ADDRを0x50としているが、実際のアドレスは製品とピン接続により異なる場合がある。
* 待機時間
*: FRAMは高速であるため、書き込み後の待機時間を1[mS]にしている。
*: 実際には、この待機も不要な場合がある。
* エラー処理
*: 以下の例では、エラー処理が記述されていない。
*: 実務では、通信エラーの検出と処理を追加することを推奨する。
* クロック周波数
*: I2C通信のクロック周波数は約100[kHz]に設定している。
*: FRAMはより高速な通信も可能であるが、MSP430G2553マイコンの制限を考慮している。
<br>
<syntaxhighlight lang="c">
#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);      // ストップコンディションが送信されるまで待機
}
</syntaxhighlight>
<br>
<u>※注意</u><br>
* 実際のデバイスアドレスを確認して、必要に応じてFRAM_ADDRマクロを調整すること。
* MB85RC256V, MB85RC512Tでは、最大アドレス範囲が異なるため、使用するデバイスの容量に注意する必要がある。
* 電源電圧やI2Cプルアップ抵抗等、ハードウェア設定も適切に行うこと。
<br><br>
<br><br>