MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
MSP430F2013 - EEPROMのソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
MSP430F2013 - EEPROM
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == EEPROM (Electrically Erasable Programmable Read-Only Memory) は、電気的に消去、書き込み可能な不揮発性メモリの1種である。<br> <br> EEPROMは、マイコンのシステムで、不揮発性のデータ保存が必要な場合に広く使用されている。<br> フラッシュメモリと比較して書き換え回数が多く、バイト単位のアクセスが可能な点が特徴である。<br> <br> ただし、書き換え速度が遅く、大容量のデータ保存には向かない。<br> また、書き換え回数にも制限があるため、頻繁に更新されるデータの保存には適していない。<br> <br> したがって、用途に応じて、EEPROM、フラッシュメモリ、SRAM等の他のメモリデバイスを使い分ける必要がある。<br> マイコンの内蔵メモリでデータ保存が可能な場合は、外付けのEEPROMを使用しないこともある。<br> <br> <center> {| class="wikitable" |+ EEPROMの特徴 ! 項目 !! 特徴 !! 説明 |- | データ保持 | 不揮発性 | 電源を切ってもデータを保持できる。 |- | 書き込み方式 | 書き換え可能 | データの消去と書き込みを電気的に行うことができる。 |- | アクセス単位 | バイト単位アクセス | バイト単位でデータの読み書きが可能である。 |- | 耐久性 | 書き換え回数制限あり | 一般的に、100万回程度の書き換えが可能である。 |- | 動作速度 | 低速 | フラッシュメモリ等と比較して、読み書きの速度が遅い。 |- | 通信方式 | シリアル通信 | I2CやSPI等のシリアル通信インターフェースを使用して、マイクロコントローラと通信する。 |- | 記憶容量 | 小容量 | 数Kbit〜数Mbitまでの容量のデバイスが存在する。 |- | 主な用途 | 設定・データ保存向け | 設定情報や較正データの保存、データロガー、小容量のデータ保存等に使用される。 |} </center> <br> EEPROMは、マイコンのシステムにおいて、小容量の不揮発性データ保存が必要な場合に重要な役割を果たすデバイスである。<br> <br><br> == EEPROMの種類 == 一般的に、外付けのEEPROMとして使用されているデバイスには、以下に示すようなものがある。<br> <br> 以下に示すEEPROMは、MSP430F2013マイコンのI2CまたはSPIインターフェースに直接接続して使用することができる。<br> 容量や速度、インターフェースの種類などの要件に応じて選択する。<br> <br> 特に、24LC256は、比較的大容量でI2Cインターフェースを備えているため、MSP430F2013マイコンの組み合わせで広く使用されている人気の高いEEPROMの1つである。<br> <br> ==== 24LC256 (256Kbit I2C EEPROM) ==== * Microchip社製の不揮発性メモリ * I2Cインターフェースを使用 * 32[KB] (256[Kbit]) の容量 * 低消費電力で動作 <br> ==== 25LC640A (64Kbit SPI EEPROM) ==== * Microchip社製の不揮発性メモリ * SPIインターフェースを使用 * 8[KB] (64[Kbit]) の容量 * 高速動作が可能 <br> ==== AT24C32 (32Kbit I2C EEPROM) ==== * Atmel (現Microchip) 社製の不揮発性メモリ * I2Cインターフェースを使用 * 4[KB] (32[Kbit]) の容量 * industryグレードの信頼性 <br><br> == MSP430F2013とEEPROMの接続 == MSP430F2013マイコンは、USI (Universal Serial Interface) モジュールを使用してI2CまたはSPI通信を行うことができる。<br> <br> ==== I2C接続 ==== MSP430F2013のUSIモジュールをI2Cモードで使用する場合、以下のピンを使用する。<br> * P1.7 - SDA (I2Cデータライン) * P1.6 - SCL (I2Cクロックライン) <br> I2C通信では、SDAとSCLの両方のラインに外部プルアップ抵抗 (通常4.7[kΩ]~10[kΩ]) が必要である。<br> 複数のデバイスをI2Cバスに接続する場合は、それぞれのデバイスに異なるアドレスを設定する。<br> <br> USIモジュールのピン機能を有効化するには、USICTL0レジスタでUSIPE7とUSIPE6ビットをセットする。<br> また、USIPE5ビットはSPI等と共用している場合があるため、セットしてもよい。<br> <br> ==== SPI接続 ==== MSP430F2013のUSIモジュールをSPIモードで使用する場合、以下のピンを使用する。<br> * P1.6 - SDO/SIMO (マスタ出力、スレーブ入力) * P1.7 - SDI/SOMI (マスタ入力、スレーブ出力) * P1.5 - SCLK (SPIクロック) * P1.x - CS (チップセレクト、GPIO制御、任意のポート) <br> SPI通信では、チップセレクト (CS) 信号は通常のGPIOピンを使用して制御する。<br> 複数のSPIデバイスを接続する場合は、それぞれに異なるCSピンを割り当てる。<br> <br> USIモジュールのピン機能を有効化するには、USICTL0レジスタでUSIPE7、USIPE6、USIPE5ビットをセットする。<br> <br><br> == サンプルコード == ==== 24LC256 (256Kbit I2C EEPROM) ==== 以下の例では、I2C通信を使用してEEPROMとの通信を行っている。<br> I2C通信を初期化した後、i2c_write_byte関数を使用してEEPROMにデータを書き込み、i2c_read_byte関数を使用して書き込んだデータを読み出している。<br> <br> # usi_i2c_init関数でI2Cの初期化を行う。<br>ピンの設定、I2Cの設定、クロック周波数の設定等を行う。<br><br>MSP430F2013マイコンのP1.7をSDA、P1.5をSCLに指定している。 #: <br> # i2c_write_byte関数を使用して、指定したアドレスにデータを書き込む。<br>スタートコンディション、アドレスの送信、データの送信、ストップコンディションの順に処理を行う。 #: <br> # i2c_read_byte関数を使用して、指定したアドレスからデータを読み出す。<br>スタートコンディション、アドレスの送信、再スタートコンディション、データの受信、ストップコンディションの順に処理を行う。 <br> 実際に動作させる場合は、回路の接続や電源の供給等にも注意が必要である。<br> 特に、I2C通信では、SDAとSCLのラインに2.2[kΩ]~10[kΩ]のプルアップ抵抗を接続する必要がある。<br> <br> MSP430F2013では、USIのI2C機能はPort 1の以下に示すピンに固定されている。<br> * P1.6 *: USI SCL * P1.7 *: USI SDA <br> 下図に、MSP430F2013と24LC256のシーケンス図を示す。<br> [[ファイル:MSP430F2013 I2C Sequence 1.png|フレームなし|中央|265x1257px]] <br> <syntaxhighlight lang="c"> #include <msp430f2013.h> // 24LC256のI2Cアドレス // 24LC256のA0, A1, A2ピンがGNDに接続されている場合 #define EEPROM_ADDRESS 0x50 void usi_i2c_init(); void i2c_start(); void i2c_stop(); void i2c_write_byte_data(unsigned char data); unsigned char i2c_read_byte_ack(); unsigned char i2c_read_byte_nack(); void eeprom_write_byte(unsigned int address, unsigned char data); unsigned char eeprom_read_byte(unsigned int address); int main(void) { WDTCTL = WDTPW + WDTHOLD; // ウォッチドッグタイマを停止 // DCOクロック設定 (1MHz) BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; usi_i2c_init(); // I2Cの初期化 unsigned char data = 0xAA; // 書き込むデータ unsigned int address = 0x0010; // EEPROMのメモリアドレス eeprom_write_byte(address, data); // EEPROMにデータを書き込み __delay_cycles(50000); // 書き込み完了待機 (約50ms) unsigned char read_data = eeprom_read_byte(address); // EEPROMからデータを読み出し while(1); } void usi_i2c_init() { USICTL0 = USIPE7 + USIPE6 + USIPE5 + USIMST + USISWRST; // ポート有効、マスタ、SW Reset // USIPE7 : P1.7をUSI機能 (SDA) として有効 // USIPE6 : P1.6をUSI機能 (SCL) として有効 // USIPE5 : I2Cでは通常未使用であるが、SPI等との共用ビットのため含まれていることがある // USIMST : マスターモード // USISWRST : USIソフトウェアリセット USICTL1 = USII2C + USIIE; // I2Cモード、割り込み有効 USICKCTL = USIDIV_7 + USISSEL_2 + USICKPL; // SMCLK/128、クロック極性 USICNT |= USIIFGCC; // USICNTで自動クリア無効 USICTL0 &= ~USISWRST; // SW Resetを解除 USICTL1 &= ~USIIFG; // 割り込みフラグクリア } void i2c_start() { USISRL = 0x00; // SDAをLowに USICTL0 |= USIGE + USIOE; // 出力有効 USICTL0 &= ~USIGE; USISRL = 0xFF; // SDAをHighに USICNT = 1; // SCLを1クロック (Start Condition) while(!(USICTL1 & USIIFG)); // 完了待ち USICTL0 |= USIGE; // 透過ラッチ有効 USISRL = 0xFF; USICTL0 &= ~USIGE; } void i2c_stop() { USICTL0 |= USIOE; // 出力有効 USISRL = 0x00; USICNT = 1; // SDAをLowに while(!(USICTL1 & USIIFG)); USISRL = 0xFF; USICTL0 |= USIGE; // 透過ラッチ有効 USICTL0 &= ~(USIGE + USIOE); // SDAを解放 USICTL1 &= ~USIIFG; // フラグクリア } void i2c_write_byte_data(unsigned char data) { USICTL0 |= USIOE; // 出力有効 USISRL = data; // データをシフトレジスタにセット USICNT = 8; // 8ビット送信 while(!(USICTL1 & USIIFG)); // 送信完了待ち // ACK/NACK受信 USICTL0 &= ~USIOE; // 受信モードに USICNT = 1; // 1ビット受信 (ACK/NACK) while(!(USICTL1 & USIIFG)); USICTL1 &= ~USIIFG; } unsigned char i2c_read_byte_ack() { USICTL0 &= ~USIOE; // 受信モードに USICNT = 8; // 8ビット受信 while(!(USICTL1 & USIIFG)); unsigned char data = USISRL; // ACK送信 USICTL0 |= USIOE; // 送信モードに USISRL = 0x00; // ACK (Low) USICNT = 1; while(!(USICTL1 & USIIFG)); USICTL1 &= ~USIIFG; return data; } unsigned char i2c_read_byte_nack() { USICTL0 &= ~USIOE; // 受信モードに USICNT = 8; // 8ビット受信 while(!(USICTL1 & USIIFG)); unsigned char data = USISRL; // NACK送信 USICTL0 |= USIOE; // 送信モードに USISRL = 0xFF; // NACK (High) USICNT = 1; while(!(USICTL1 & USIIFG)); USICTL1 &= ~USIIFG; return data; } void eeprom_write_byte(unsigned int address, unsigned char data) { i2c_start(); // スタートコンディション i2c_write_byte_data((EEPROM_ADDRESS << 1) | 0); // アドレス + Write i2c_write_byte_data((address >> 8) & 0xFF); // アドレス上位 i2c_write_byte_data(address & 0xFF); // アドレス下位 i2c_write_byte_data(data); // データ i2c_stop(); // ストップコンディション } unsigned char eeprom_read_byte(unsigned int address) { unsigned char data; i2c_start(); // スタートコンディション i2c_write_byte_data((EEPROM_ADDRESS << 1) | 0); // アドレス + Write i2c_write_byte_data((address >> 8) & 0xFF); // アドレス上位 i2c_write_byte_data(address & 0xFF); // アドレス下位 i2c_start(); // リピーテッドスタート i2c_write_byte_data((EEPROM_ADDRESS << 1) | 1); // アドレス + Read data = i2c_read_byte_nack(); // データ受信 + NACK i2c_stop(); // ストップコンディション return data; } </syntaxhighlight> <br> ==== 25LC640A (64Kbit SPI EEPROM) ==== 以下の例では、SPI通信を使用してEEPROMとの通信を行っている。<br> SPIの初期化後、eeprom_write_byte関数を使用してEEPROMにデータを書き込み、eeprom_read_byte関数を使用して書き込んだデータを読み出している。<br> <br> # usi_spi_init関数でSPIの初期化を行う。<br>ピンの設定、SPIの設定、クロック周波数の設定等を行う。<br><br>MSP430F2013マイコンのP1.6をSDO、P1.7をSDI、P1.5をSCLKに指定している。 #: <br> # eeprom_write_byte関数を使用して、指定したアドレスにデータを書き込む。<br><code>WREN</code>コマンドで書き込み有効化して、<code>WRITE</code>コマンドでアドレスとデータを送信する。 #: <br> # eeprom_read_byte関数を使用して、指定したアドレスからデータを読み出す。<br><code>READ</code>コマンドでアドレスを送信して、データを受信する。 <br> 実際に動作させる場合は、回路の接続や電源の供給等にも注意が必要である。<br> 特に、25LC640AのCS (チップセレクト) ピンは、適切なポートピンに接続して、ソースコード内で設定する必要がある。<br> <br> 下図に、MSP430F2013と25LC640Aのシーケンス図を示す。<br> [[ファイル:MSP430F2013 SPI Sequence.png|フレームなし|中央|265x1257px]] <br> <syntaxhighlight lang="c"> #include <msp430f2013.h> // CSピンの設定 (例: P1.0) #define CS_PIN BIT0 #define CS_LOW() P1OUT &= ~CS_PIN #define CS_HIGH() P1OUT |= CS_PIN // SPI EEPROM命令コード #define EEPROM_CMD_READ 0x03 #define EEPROM_CMD_WRITE 0x02 #define EEPROM_CMD_WREN 0x06 #define EEPROM_CMD_RDSR 0x05 void usi_spi_init(); unsigned char spi_transfer(unsigned char data); void eeprom_write_byte(unsigned int address, unsigned char data); unsigned char eeprom_read_byte(unsigned int address); unsigned char eeprom_read_status(); void eeprom_wait_ready(); int main(void) { WDTCTL = WDTPW + WDTHOLD; // ウォッチドッグタイマーを停止 // DCOクロック設定 (1MHz) BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1DIR |= CS_PIN; // CSピンを出力に設定 CS_HIGH(); // CSピンをハイに設定 usi_spi_init(); // SPIの初期化 unsigned char data = 0xAA; // 書き込むデータ unsigned int address = 0x1000; // EEPROMのメモリアドレス eeprom_write_byte(address, data); // EEPROMにデータを書き込み unsigned char read_data = eeprom_read_byte(address); // EEPROMからデータを読み出し while(1); // 無限ループ } void usi_spi_init() { // USIをSPIマスターモードで初期化 USICTL0 = USIPE7 + USIPE6 + USIPE5 + USIMST + USIOE + USISWRST; // ピン有効、マスタ、出力有効 USICTL1 = USICKPH; // クロック位相: データはSCLK立下りでキャプチャ、立上りで変化 USICKCTL = USIDIV_1 + USISSEL_2; // SMCLK/2を使用 (約500kHz) USICNT |= USIIFGCC; // USICNTで自動クリア無効 USICTL0 &= ~USISWRST; // SW Resetを解除 } unsigned char spi_transfer(unsigned char data) { USISRL = data; // 送信データをシフトレジスタにセット USICNT = 8; // 8ビット送信/受信 while(!(USICTL1 & USIIFG)); // 転送完了待ち USICTL1 &= ~USIIFG; // フラグクリア return USISRL; // 受信データを返す } unsigned char eeprom_read_status() { unsigned char status; CS_LOW(); // EEPROM選択 spi_transfer(EEPROM_CMD_RDSR); // ステータス読み込みコマンド送信 status = spi_transfer(0xFF); // ステータス値受信 CS_HIGH(); // EEPROM非選択 return status; } void eeprom_wait_ready() { while (eeprom_read_status() & 0x01) // WIPビットが0になるまで待機 { __delay_cycles(100); } } void eeprom_write_byte(unsigned int address, unsigned char data) { eeprom_wait_ready(); // 前回の書き込み完了待機 CS_LOW(); // EEPROM選択 spi_transfer(EEPROM_CMD_WREN); // 書き込み有効化コマンド CS_HIGH(); // EEPROM非選択 __delay_cycles(100); // 短い待機 CS_LOW(); // EEPROM選択 spi_transfer(EEPROM_CMD_WRITE); // 書き込みコマンド spi_transfer((address >> 8) & 0xFF); // アドレス上位バイト spi_transfer(address & 0xFF); // アドレス下位バイト spi_transfer(data); // データ CS_HIGH(); // EEPROM非選択 eeprom_wait_ready(); // 書き込み完了待機 } unsigned char eeprom_read_byte(unsigned int address) { unsigned char data; eeprom_wait_ready(); // 書き込み完了待機 CS_LOW(); // EEPROM選択 spi_transfer(EEPROM_CMD_READ); // 読み出しコマンド spi_transfer((address >> 8) & 0xFF); // アドレス上位バイト spi_transfer(address & 0xFF); // アドレス下位バイト data = spi_transfer(0xFF); // データ受信 CS_HIGH(); // EEPROM非選択 return data; } </syntaxhighlight> <br> ==== AT24C32 (32Kbit I2C EEPROM) ==== AT24C32 EEPROMを使用してI2C通信する場合は、上記の24LC256のサンプルプログラムとほぼ同じとなる。<br> これは、AT24C32と24LC256がどちらもI2Cインターフェースを使用しており、通信プロトコルが同一だからである。<br> <br> 主な違いは、EEPROMの容量とアドレッシングである。<br> * 24LC256は、256[Kbit] (32[KB]) の容量を持ち、16ビットのアドレス (0x0000~0x7FFF) を使用する。 * AT24C32は、32[Kbit] (4[KB]) の容量を持ち、12ビットのアドレス (0x000~0xFFF) を使用する。 <br> AT24C32のアドレッシングは2バイトで行われるが、有効なアドレス範囲は0x000~0xFFFであり、上位4ビットは無視される。<br> したがって、24LC256向けのサンプルコードをそのままAT24C32で使用することができる。<br> <br> ただし、EEPROMの容量が異なるため、アドレスの範囲に注意が必要である。<br> AT24C32の有効なアドレス範囲は、<u>0x000~0xFFF</u>であり、それ以外のアドレスを指定した場合の動作は未定義となることに注意する。<br> <br> また、EEPROMのI2Cアドレスを確認して、必要に応じて、EEPROM_ADDRESSの定義を変更する必要がある。<br> AT24C32のデフォルトのI2Cアドレスは0x50 (A0、A1、A2がGNDに接続されている場合) だが、実装により異なる場合がある。<br> <br><br> == 注意事項 == MSP430F2013マイコンを使用してEEPROMと通信する場合には、以下に示す事柄に注意する。<br> <br> ==== 共通 ==== * 電源電圧 *: EEPROMの動作電圧範囲を確認し、MSP430F2013の電源電圧と一致していることを確認する。 * デカップリングコンデンサ *: EEPROMの電源ピンの近くに、0.1[μF]のデカップリングコンデンサを配置する。 * 配線長 *: I2CおよびSPIの信号線は、できるだけ短く、かつノイズの影響を受けにくいように配線する。 * エラー処理 *: 実際のアプリケーションでは、通信エラーや書き込みエラーに対する適切なエラー処理を実装する必要がある。 * メモリ容量 *: MSP430F2013は2KB Flashと128B RAMという限られたメモリ容量のため、コードサイズの最適化が重要である。 <br> ==== I2C通信 ==== * プルアップ抵抗 *: I2CのSDAとSCLのラインには、必ず外部プルアップ抵抗 (4.7[kΩ]~10[kΩ]) を接続する必要がある。 * クロック周波数 *: I2C通信のクロック周波数は、標準モードで100[kHz]、高速モードで400[kHz]までサポートされている。 * 書き込み完了時間 *: EEPROMへの書き込み後、内部書き込みサイクルが完了するまで約5[ms]の待機時間が必要である。 * アドレッシング *: 16ビットアドレスのEEPROMでは、アドレスを2バイトで送信する必要がある。 * USIのI2Cスレーブモード制約 (Errata USI2, USI3, USI4) *: MSP430F2013のUSIモジュールには、I2Cスレーブモードに関するいくつかの既知の問題がある。 *: I2Cスレーブモードを使用する場合は、20[kbps]以上の通信速度を推奨。 *: 本サンプルコードでは、マスターモードのみを使用しているため、この問題の影響は受けない。 <br> ==== SPI通信 ==== * チップセレクト制御 *: SPI通信では、通信前にCS信号をLOWに、通信後にHIGHにする必要がある。 * クロック極性と位相 *: SPIのクロック極性と位相は、EEPROMのデータシートに従って設定する必要がある。 * 書き込み有効化 *: EEPROMへの書き込み前に、必ずWRENコマンドで書き込みを有効化する必要がある。 * ステータス確認 *: 書き込み操作後、ステータスレジスタを読み取り、WIPビットが0になるまで待機する必要がある。 * 初回転送時の注意 (Errata USI5) *: USICKPHビットをセットした状態でUSIをSPIマスターモードで初期化すると、リセット後の最初のデータ転送時に1クロック余分に生成される。 *: 回避策として、初期化後にダミー転送を1回実行するか、USICKPHビットをクリアして使用する。 <br> ==== MSP430F2013固有の制約 ==== * USIモジュールの制限 *: USIは、MSP430F149のUSARTモジュールと比較して機能が制限されている。 *: I2CおよびSPIの基本的な通信機能のみをサポートする。 *: ハードウェアによる自動アドレス認識やFIFOバッファは搭載されていない。 * メモリ容量の制限 *: Flash: 2KB、RAM: 128Bと非常に限られているため、大規模なバッファやデータ構造は使用できない。 *: コードサイズの最適化とメモリ使用量の削減が重要である。 * クロック設定 *: DCOキャリブレーションデータ (CALBC1_1MHZ、CALDCO_1MHZ等) を使用して、正確なクロック周波数を設定する。 *: キャリブレーションデータはInfo Memoryセグメントに格納されている。 <br><br> {{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,MSP430F2013,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux |image=/resources/assets/MochiuLogo_Single_Blue.png }} __FORCETOC__ [[カテゴリ:MSP430]]
MSP430F2013 - EEPROM
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse