| 64行目: | 64行目: | ||
WDTCTL = WDTPW | WDTHOLD; // ウォッチドッグタイマを停止 | WDTCTL = WDTPW | WDTHOLD; // ウォッチドッグタイマを停止 | ||
initI2C(); | initI2C(); // I2Cの初期化 | ||
// 書き込むデータ | // 書き込むデータ | ||
| 72行目: | 72行目: | ||
unsigned char readData[4]; | unsigned char readData[4]; | ||
// | // FRAMに4バイトのデータを書き込む (アドレス0x00から) | ||
I2C_write(0x00, writeData, 4); | I2C_write(0x00, writeData, 4); | ||
// | // 100[mS]待機 | ||
__delay_cycles(100000); | __delay_cycles(100000); | ||
// | // FRAMから4バイトのデータを読み出す (アドレス0x00から) | ||
I2C_read(0x00, readData, 4); | I2C_read(0x00, readData, 4); | ||
| 86行目: | 86行目: | ||
void initI2C(void) | void initI2C(void) | ||
{ | { | ||
P1SEL |= BIT6 + BIT7; | P1SEL |= BIT6 + BIT7; // P1.6 = SCL, P1.7 = SDA | ||
P1SEL2 |= BIT6 + BIT7; | P1SEL2 |= BIT6 + BIT7; | ||
UCB0CTL1 |= UCSWRST; | UCB0CTL1 |= UCSWRST; // UCB0をリセット状態に | ||
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; | UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2Cマスターモード | ||
UCB0CTL1 = UCSSEL_2 + UCSWRST; | UCB0CTL1 = UCSSEL_2 + UCSWRST; // SMCLKを選択 | ||
UCB0BR0 = 12; | UCB0BR0 = 12; // fSCL = SMCLK / 12 = 100[kHz] | ||
UCB0BR1 = 0; | UCB0BR1 = 0; | ||
UCB0I2CSA = FRAM_ADDR; | UCB0I2CSA = FRAM_ADDR; // スレーブアドレスをセット | ||
UCB0CTL1 &= ~UCSWRST; | UCB0CTL1 &= ~UCSWRST; // UCB0のリセットを解除 | ||
} | } | ||
void I2C_write(unsigned char addr, unsigned char *data, unsigned int len) | void I2C_write(unsigned char addr, unsigned char *data, unsigned int len) | ||
{ | { | ||
while (UCB0CTL1 & UCTXSTP); | while (UCB0CTL1 & UCTXSTP); // 前の通信が終了するまで待機 | ||
UCB0CTL1 |= UCTR + UCTXSTT; // 送信モード、スタートコンディション | UCB0CTL1 |= UCTR + UCTXSTT; // 送信モード、スタートコンディション | ||
while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機 | while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機 | ||
UCB0TXBUF = addr; | UCB0TXBUF = addr; // メモリアドレスを送信 | ||
while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機 | while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機 | ||
while (len--) { | while (len--) { | ||
UCB0TXBUF = *data++; | UCB0TXBUF = *data++; // データを送信 | ||
while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機 | while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機 | ||
} | } | ||
UCB0CTL1 |= UCTXSTP; | UCB0CTL1 |= UCTXSTP; // ストップコンディション | ||
while (UCB0CTL1 & UCTXSTP); | while (UCB0CTL1 & UCTXSTP); // ストップコンディションが送信されるまで待機 | ||
} | } | ||
void I2C_read(unsigned char addr, unsigned char *data, unsigned int len) | void I2C_read(unsigned char addr, unsigned char *data, unsigned int len) | ||
{ | { | ||
while (UCB0CTL1 & UCTXSTP); | while (UCB0CTL1 & UCTXSTP); // 前の通信が終了するまで待機 | ||
UCB0CTL1 |= UCTR + UCTXSTT; // 送信モード、スタートコンディション | UCB0CTL1 |= UCTR + UCTXSTT; // 送信モード、スタートコンディション | ||
while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機 | while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機 | ||
UCB0TXBUF = addr; | UCB0TXBUF = addr; // メモリアドレスを送信 | ||
while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機 | while (!(IFG2 & UCB0TXIFG)); // TXバッファが空になるまで待機 | ||
UCB0CTL1 &= ~UCTR; | UCB0CTL1 &= ~UCTR; // 受信モードに切り替え | ||
UCB0CTL1 |= UCTXSTT; | UCB0CTL1 |= UCTXSTT; // リスタートコンディション | ||
while (UCB0CTL1 & UCTXSTT); | while (UCB0CTL1 & UCTXSTT); // スタートコンディションが送信されるまで待機 | ||
while (len--) { | while (len--) { | ||
while (!(IFG2 & UCB0RXIFG)); // RXバッファにデータが来るまで待機 | while (!(IFG2 & UCB0RXIFG)); // RXバッファにデータが来るまで待機 | ||
*data++ = UCB0RXBUF; | *data++ = UCB0RXBUF; // データを読み出し | ||
if (len == 0) | if (len == 0) | ||
UCB0CTL1 |= UCTXSTP; | UCB0CTL1 |= UCTXSTP; // 最後のバイトを読み出す前にストップコンディションを送信 | ||
} | } | ||
while (UCB0CTL1 & UCTXSTP); | while (UCB0CTL1 & UCTXSTP); // ストップコンディションが送信されるまで待機 | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| 147行目: | 147行目: | ||
*: FRAMへの連続的なアクセスを避けて、デバイスに「休憩」を与える。 | *: FRAMへの連続的なアクセスを避けて、デバイスに「休憩」を与える。 | ||
<br> | <br> | ||
ただし、実際の設計では、この長い遅延は必ずしも必要ではない。< | ただし、実際の設計では、この長い遅延は必ずしも必要ではない。<br> | ||
FRAMは、一般的に、マイクロ秒オーダーで書き込みを完了するため、実運用では以下のような方法を検討できる。<br> | FRAMは、一般的に、マイクロ秒オーダーで書き込みを完了するため、実運用では以下のような方法を検討できる。<br> | ||
* 遅延時間の短縮 | * 遅延時間の短縮 | ||