AVR内蔵のEEPROMを操作するための関数群が <avr/eeprom.h> に用意されています。
AVR Libc 1.6.7 で提供されている関数に基づきます。(1.7.1まで確認済み)
EEPROMの利点と注意点
利点
注意点
- 書き込み消去がSRAMより遅い (SRAM1クロック・EEPROM数ms)
- 書き込み回数に制限がある (10,000回保証だが壊れたという話はあまり聞かない)
- 低圧動作時に誤動作がありえる (CPUと最低動作電圧が異なる)
- 書き込みが非同期動作である
詳細なEEPROMの扱いは、データシートを読んでください。AVR Memory の中にEEPROMの扱いが載っています。
EEPROMアクセス
アクセスの流れ
EEPROMのアクセスは、必ず使用できる状態かを確認してから読み書きをする。
- EEPROMのアクセスが出来る状態を確認
- 読み書き
アクセス可能か確認
確認方法は2種類ある。
- eeprom_is_ready()
- eeprom_busy_wait()
その他の方法として、割込 (EE_READY_vect / EE_RDY_vect / EEPROM_READY_vect ) を使用する方法もある。
eeprom_is_ready()
EEPROMがアクセス可能かを判定する。(並行処理する場合のポーリングに用いる。)
返値
- アクセス可能: 成功 (非ゼロ)
- アクセス不可: 失敗 (ゼロ)
eeprom_busy_wait()
EEPROMがアクセス可能になるまでループして待つ。
EEPROMアドレス
EEPROMのアクセスは、0x0000~E2END (avr/io.hで定義) のアドレスとなります。
各AVR毎に搭載されているEEPROMのサイズが違うため、使う場合はデータシートを確認してください。
EEPROMのアドレス管理方法は、次の2つがあります。
- 各自で管理する方法 (0x0000 , 0x0001 と指定する方法)
- コンパイラで管理・生成する方法 (EEMEMを使用して宣言する方法)
アドレスを各自で管理する方法
各自でアドレスとサイズを把握しておかなければ、予想外に上書きなどをする場合があるため、しっかりと管理しなければならず煩雑となる。
#define EEPROM_V1 0x0000 /* EEPROM uint16_t 0x0000-0x0001 2Byte */
#define EEPROM_V2 0x0002 /* EEPROM uint8_t 0x0002 1Byte */
#define EEPROM_V3 0x0003 /* EEPROM int16_t 0x0003-0x0004 2Byte */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_word((uint16_t *)EEPROM_V1); /* EEPROM_V1の読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_word((uint16_t *)EEPROM_V1, 0xCCAA); /* EEPROM_V1へ2byte書き込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_byte((uint8_t *)EEPROM_V2, 0xAA); /* EEPROM_V2へ1byte書き込み */
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
#define EEPROM_V1 0x0000 /* EEPROM uint16_t 0x0000-0x0001 2Byte */
#define EEPROM_V2 0x0002 /* EEPROM uint8_t 0x0002 1Byte */
#define EEPROM_V3 0x0003 /* EEPROM int16_t 0x0003-0x0004 2Byte */
int main( void )
{
uint16_t value;
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_word((uint16_t *)EEPROM_V1); /* EEPROM_V1の読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_word((uint16_t *)EEPROM_V1, 0xCCAA); /* EEPROM_V1へ2byte書き込み */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_byte((uint8_t *)EEPROM_V2, 0xAA); /* EEPROM_V2へ1byte書き込み */
}
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
#define EEPROM_V1 0x0000 /* EEPROM uint16_t 0x0000-0x0001 2Byte */
#define EEPROM_V2 0x0002 /* EEPROM uint8_t 0x0002 1Byte */
#define EEPROM_V3 0x0003 /* EEPROM int16_t 0x0003-0x0004 2Byte */
int main( void )
{
uint16_t value;
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_word((uint16_t *)EEPROM_V1); /* EEPROM_V1の読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_word((uint16_t *)EEPROM_V1, 0xCCAA); /* EEPROM_V1へ2byte書き込み */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_byte((uint8_t *)EEPROM_V2, 0xAA); /* EEPROM_V2へ1byte書き込み */
}
アドレスをコンパイラで管理・生成する方法
ソースコード上で、EEPROM用の変数として宣言する方法。管理が楽であるが、コードを書き換える(宣言の順番を入れ替える)と、EEPROMのアドレスが変り、昔の情報を読み出せなくなったりするので注意。
宣言方法は次の2種類がありどちらも同じです。初期値の設定も出来きます。
- EEMEM を付ける方法
- __attribute__((section(“.eeprom”))) を付ける方法
static uint16_t EEMEM EEPROM_V1; /* EEPROM_V1を宣言 */
static uint8_t EEPROM_V2 __attribute__((section(".eeprom"))); /* EEPROM_V2を宣言 */
static uint16_t EEMEM EEPROM_V3 = 5; /* EEPROM_V3を宣言と初期値 5 */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_word(&EEPROM_V1); /* EEPROM_V1の読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_word(&EEPROM_V1, 0xCCAA); /* EEPROM_V1へ2byte書き込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_byte(&EEPROM_V2, 0xAA); /* EEPROM_V2へ1byte書き込み */
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
static uint16_t EEMEM EEPROM_V1; /* EEPROM_V1を宣言 */
static uint8_t EEPROM_V2 __attribute__((section(".eeprom"))); /* EEPROM_V2を宣言 */
static uint16_t EEMEM EEPROM_V3 = 5; /* EEPROM_V3を宣言と初期値 5 */
int main( void )
{
uint16_t value;
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_word(&EEPROM_V1); /* EEPROM_V1の読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_word(&EEPROM_V1, 0xCCAA); /* EEPROM_V1へ2byte書き込み */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_byte(&EEPROM_V2, 0xAA); /* EEPROM_V2へ1byte書き込み */
}
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
static uint16_t EEMEM EEPROM_V1; /* EEPROM_V1を宣言 */
static uint8_t EEPROM_V2 __attribute__((section(".eeprom"))); /* EEPROM_V2を宣言 */
static uint16_t EEMEM EEPROM_V3 = 5; /* EEPROM_V3を宣言と初期値 5 */
int main( void )
{
uint16_t value;
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_word(&EEPROM_V1); /* EEPROM_V1の読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_word(&EEPROM_V1, 0xCCAA); /* EEPROM_V1へ2byte書き込み */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_byte(&EEPROM_V2, 0xAA); /* EEPROM_V2へ1byte書き込み */
}
EEPROMの読み書き更新
AVR libCでは、EEPROMへのアクセスする関数として読出し・書き込み・更新の3種類が提供されている。
読出し(eeprom_read_xxx())・書き込み関数(eeprom_write_xxx())は、指定されたアドレスに対して読み書きを行う関数です。
更新(eeprom_update_xxx())は、一度読出しを行い、書き込み指定値と違うときのみ書き込みを行う関数です。これを用いることで、EEPROMを頻繁に書き換えをすることを防げます。ただし、一度読出しを行うため、動作は単純な書き込みより少し(CPU
6サイクル分)遅くなります。
EEPROMの読出し・書き込み・更新の目安時間 (ATmega88の場合)
関数 | 時間 | |
---|
eeprom_read_byte(0x0000) | 4 CPUサイクル (20MHz時 200ns) | データシート p23 EEREの記述より |
eeprom_write_byte(0x0000, 0x00) | 3.4ms | データシート p22 Table6-1より |
eeprom_update_byte(0x0000, 0x00) | 4 CPUサイクル + 3.4ms(書き換え) | |
読出し関数
関数プロトタイプ | 説明 |
---|
uint8_t eeprom_read_byte (const uint8_t *__p) __ATTR_PURE__ | EEPROM 1Byte(8bit)読出し |
uint16_t eeprom_read_word (const uint16_t *__p) __ATTR_PURE__ | EEPROM 2Byte(16bit)読出し |
uint32_t eeprom_read_dword (const uint32_t *__p) __ATTR_PURE__ | EEPROM 4Byte(32bit)読出し |
float eeprom_read_float (const float *__p) __ATTR_PURE__ | EEPROM float読出し |
void eeprom_read_block (void *__dst, const void *__src, size_t __n) | EEPROM ブロック読出し |
書き込み関数
関数プロトタイプ | 説明 |
---|
void eeprom_write_byte (uint8_t *__p, uint8_t __value) | EEPROM 1Byte(8bit)書き込み |
void eeprom_write_word (uint16_t *__p, uint16_t __value) | EEPROM 2Byte(16bit)書き込み |
void eeprom_write_dword (uint32_t *__p, uint32_t __value) | EEPROM 4Byte(32bit)書き込み |
void eeprom_write_float (float *__p, float __value) | EEPROM float書き込み |
void eeprom_write_block (const void *__src, void *__dst, size_t __n) | EEPROM ブロック書き込み |
更新関数
関数プロトタイプ | 説明 |
---|
void eeprom_update_byte (uint8_t *__p, uint8_t __value) | EEPROM 1Byte(8bit)更新 |
void eeprom_update_word (uint16_t *__p, uint16_t __value) | EEPROM 2Byte(16bit)更新 |
void eeprom_update_dword (uint32_t *__p, uint32_t __value) | EEPROM 4Byte(32bit)更新 |
void eeprom_update_float (float *__p, float __value) | EEPROM float更新 |
void eeprom_update_block (const void *__src, void *__dst, size_t __n) | EEPROM ブロック更新 |
サンプルコード
uint8_t のサンプル
1ByteのEEPROMアクセスのサンプルコードです。
- eeprom_read_byte( address )
- eeprom_write_byte( address , value )
- eeprom_update_byte( address , value )
符号ビットを含めるかの違いのため、int8_t型を入れることも可能
static uint8_t EEMEM EEPROM_V1 = 5; /* EEPROM_V1 を宣言 */
static uint8_t EEMEM EEPROM_V2; /* EEPROM_V2 を宣言 */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_byte(&EEPROM_V1); /* EEPROM_V1の読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_byte(&EEPROM_V1, 0xAA); /* EEPROM_V1へ書き込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_byte(&EEPROM_V2, value); /* EEPROM_V2を更新 */
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
static uint8_t EEMEM EEPROM_V1 = 5; /* EEPROM_V1 を宣言 */
static uint8_t EEMEM EEPROM_V2; /* EEPROM_V2 を宣言 */
int main( void )
{
uint8_t value;
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_byte(&EEPROM_V1); /* EEPROM_V1の読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_byte(&EEPROM_V1, 0xAA); /* EEPROM_V1へ書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_byte(&EEPROM_V2, value); /* EEPROM_V2を更新 */
}
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
static uint8_t EEMEM EEPROM_V1 = 5; /* EEPROM_V1 を宣言 */
static uint8_t EEMEM EEPROM_V2; /* EEPROM_V2 を宣言 */
int main( void )
{
uint8_t value;
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_byte(&EEPROM_V1); /* EEPROM_V1の読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_byte(&EEPROM_V1, 0xAA); /* EEPROM_V1へ書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_byte(&EEPROM_V2, value); /* EEPROM_V2を更新 */
}
uint16_t のサンプル
2Byte(WORD)のEEPROMアクセスのサンプルコードです。
- eeprom_read_word( address )
- eeprom_write_word( address , value )
- eeprom_update_word( address , value )
符号ビットを含めるかの違いのため、int16_t型(int型)を入れることも可能
static uint16_t EEMEM EEPROM_V1 = 5; /* EEPROM_V1 を宣言 */
static uint16_t EEMEM EEPROM_V2; /* EEPROM_V2 を宣言 */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_word(&EEPROM_V1); /* EEPROM_V1の読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_word(&EEPROM_V1, 0xCCAA); /* EEPROM_V1へ書き込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_word(&EEPROM_V2, value); /* EEPROM_V2を更新 */
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
static uint16_t EEMEM EEPROM_V1 = 5; /* EEPROM_V1 を宣言 */
static uint16_t EEMEM EEPROM_V2; /* EEPROM_V2 を宣言 */
int main( void )
{
uint16_t value;
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_word(&EEPROM_V1); /* EEPROM_V1の読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_word(&EEPROM_V1, 0xCCAA); /* EEPROM_V1へ書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_word(&EEPROM_V2, value); /* EEPROM_V2を更新 */
}
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
static uint16_t EEMEM EEPROM_V1 = 5; /* EEPROM_V1 を宣言 */
static uint16_t EEMEM EEPROM_V2; /* EEPROM_V2 を宣言 */
int main( void )
{
uint16_t value;
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_word(&EEPROM_V1); /* EEPROM_V1の読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_word(&EEPROM_V1, 0xCCAA); /* EEPROM_V1へ書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_word(&EEPROM_V2, value); /* EEPROM_V2を更新 */
}
uint32_t のサンプル
4Byte(DWORD)のEEPROMアクセスのサンプルコードです。
- eeprom_read_dword( address )
- eeprom_write_dword( address , value )
- eeprom_update_dword( address , value )
符号ビットを含めるかの違いのため、int32_t型(long int型)を入れることも可能
static uint32_t EEMEM EEPROM_V1 = 5; /* EEPROM_V1 を宣言 */
static uint32_t EEMEM EEPROM_V2; /* EEPROM_V2 を宣言 */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_dword(&EEPROM_V1); /* EEPROM_V1の読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_dword(&EEPROM_V1, 0x55DDCCAA); /* EEPROM_V1へ書き込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_dword(&EEPROM_V2, value); /* EEPROM_V2を更新 */
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
static uint32_t EEMEM EEPROM_V1 = 5; /* EEPROM_V1 を宣言 */
static uint32_t EEMEM EEPROM_V2; /* EEPROM_V2 を宣言 */
int main( void )
{
uint32_t value;
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_dword(&EEPROM_V1); /* EEPROM_V1の読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_dword(&EEPROM_V1, 0x55DDCCAA); /* EEPROM_V1へ書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_dword(&EEPROM_V2, value); /* EEPROM_V2を更新 */
}
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
static uint32_t EEMEM EEPROM_V1 = 5; /* EEPROM_V1 を宣言 */
static uint32_t EEMEM EEPROM_V2; /* EEPROM_V2 を宣言 */
int main( void )
{
uint32_t value;
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_dword(&EEPROM_V1); /* EEPROM_V1の読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_dword(&EEPROM_V1, 0x55DDCCAA); /* EEPROM_V1へ書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_dword(&EEPROM_V2, value); /* EEPROM_V2を更新 */
}
float のサンプル
float型のEEPROMアクセスのサンプルコードです。浮動小数点の変数を取り扱えます。
- eeprom_read_float( address )
- eeprom_write_float( address , value )
- eeprom_update_float( address , value )
static float EEMEM EEPROM_V1 = 10.1; /* EEPROM_V1 を宣言 */
static float EEMEM EEPROM_V2; /* EEPROM_V2 を宣言 */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_float(&EEPROM_V1); /* EEPROM_V1の読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_float(&EEPROM_V1, 20.2); /* EEPROM_V1へ書き込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_float(&EEPROM_V2, value); /* EEPROM_V2を更新 */
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
static float EEMEM EEPROM_V1 = 10.1; /* EEPROM_V1 を宣言 */
static float EEMEM EEPROM_V2; /* EEPROM_V2 を宣言 */
int main( void )
{
float value;
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_float(&EEPROM_V1); /* EEPROM_V1の読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_float(&EEPROM_V1, 20.2); /* EEPROM_V1へ書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_float(&EEPROM_V2, value); /* EEPROM_V2を更新 */
}
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
static float EEMEM EEPROM_V1 = 10.1; /* EEPROM_V1 を宣言 */
static float EEMEM EEPROM_V2; /* EEPROM_V2 を宣言 */
int main( void )
{
float value;
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_float(&EEPROM_V1); /* EEPROM_V1の読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_float(&EEPROM_V1, 20.2); /* EEPROM_V1へ書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_float(&EEPROM_V2, value); /* EEPROM_V2を更新 */
}
配列のサンプル
EEPROM上に配列を宣言して取り扱うことも可能です。
1バイト単位の制御
- eeprom_read_byte( address )
- eeprom_write_byte( address , value )
- eeprom_update_byte( address , value )
ブロック単位(配列全体)の制御
- eeprom_read_block( dist_address , src_address(EEPROM) , size )
- eeprom_write_block( src_address , dist_address(EEPROM) , size )
- eeprom_update_block( src_address , dist_address(EEPROM) , size )
static uint8_t EEMEM EEPROM_V1[10]; /* EEPROM_V1[10] を宣言 */
static uint8_t EEMEM EEPROM_V2[] = { 10, 3, 20, 4}; /* EEPROM_V2[] を宣言・初期値 */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_byte(&EEPROM_V1[0]); /* EEPROM_V1[0]の読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_byte(&EEPROM_V1[1], 0xAA); /* EEPROM_V1[1]へ書き込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_byte(&EEPROM_V1[2], value); /* EEPROM_V1[2]を更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_read_block(vars, EEPROM_V1, sizeof(vars)); /* EEPROM_V1[]をvars[10]のサイズまとめて読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_block(vars, EEPROM_V1, sizeof(vars)); /* EEPROM_V1[]へvars[10]をまとめて書き込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_block(vars, EEPROM_V1, sizeof(vars)); /* EEPROM_V1[]をvars[10]でまとめて更新 */
/* 配列単位(ブロック)のアクセス その2 10Byteを指定する場合で上と同じ動作 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_read_block(&vars[0], &EEPROM_V1[0], 10); /* EEPROM_V1[0]からvars[0]へ10Byteまとめて読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_block(vars, &EEPROM_V1[0], 10); /* EEPROM_V1[]へvars[10]をまとめて書き込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_block(&vars[0], EEPROM_V1, 10); /* EEPROM_V1[]をvars[10]でまとめて更新 */
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
static uint8_t EEMEM EEPROM_V1[10]; /* EEPROM_V1[10] を宣言 */
static uint8_t EEMEM EEPROM_V2[] = { 10, 3, 20, 4}; /* EEPROM_V2[] を宣言・初期値 */
int main( void )
{
uint8_t value;
uint8_t vars[10];
/* EEPROM 読出し */
/* 1Byte単位のアクセス */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_byte(&EEPROM_V1[0]); /* EEPROM_V1[0]の読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_byte(&EEPROM_V1[1], 0xAA); /* EEPROM_V1[1]へ書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_byte(&EEPROM_V1[2], value); /* EEPROM_V1[2]を更新 */
/* 配列単位(ブロック)のアクセス */
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_read_block(vars, EEPROM_V1, sizeof(vars)); /* EEPROM_V1[]をvars[10]のサイズまとめて読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_block(vars, EEPROM_V1, sizeof(vars)); /* EEPROM_V1[]へvars[10]をまとめて書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_block(vars, EEPROM_V1, sizeof(vars)); /* EEPROM_V1[]をvars[10]でまとめて更新 */
/* 配列単位(ブロック)のアクセス その2 10Byteを指定する場合で上と同じ動作 */
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_read_block(&vars[0], &EEPROM_V1[0], 10); /* EEPROM_V1[0]からvars[0]へ10Byteまとめて読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_block(vars, &EEPROM_V1[0], 10); /* EEPROM_V1[]へvars[10]をまとめて書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_block(&vars[0], EEPROM_V1, 10); /* EEPROM_V1[]をvars[10]でまとめて更新 */
}
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
static uint8_t EEMEM EEPROM_V1[10]; /* EEPROM_V1[10] を宣言 */
static uint8_t EEMEM EEPROM_V2[] = { 10, 3, 20, 4}; /* EEPROM_V2[] を宣言・初期値 */
int main( void )
{
uint8_t value;
uint8_t vars[10];
/* EEPROM 読出し */
/* 1Byte単位のアクセス */
eeprom_busy_wait(); /* 読み書き可能までwait */
value = eeprom_read_byte(&EEPROM_V1[0]); /* EEPROM_V1[0]の読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_byte(&EEPROM_V1[1], 0xAA); /* EEPROM_V1[1]へ書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_byte(&EEPROM_V1[2], value); /* EEPROM_V1[2]を更新 */
/* 配列単位(ブロック)のアクセス */
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_read_block(vars, EEPROM_V1, sizeof(vars)); /* EEPROM_V1[]をvars[10]のサイズまとめて読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_block(vars, EEPROM_V1, sizeof(vars)); /* EEPROM_V1[]へvars[10]をまとめて書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_block(vars, EEPROM_V1, sizeof(vars)); /* EEPROM_V1[]をvars[10]でまとめて更新 */
/* 配列単位(ブロック)のアクセス その2 10Byteを指定する場合で上と同じ動作 */
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_read_block(&vars[0], &EEPROM_V1[0], 10); /* EEPROM_V1[0]からvars[0]へ10Byteまとめて読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_block(vars, &EEPROM_V1[0], 10); /* EEPROM_V1[]へvars[10]をまとめて書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_block(&vars[0], EEPROM_V1, 10); /* EEPROM_V1[]をvars[10]でまとめて更新 */
}
文字列のサンプル
EEPROM上に配列を宣言して取り扱うことも可能です。
ブロック単位(配列・文字列全体)の制御
- eeprom_read_block( dist_address , src_address(EEPROM) , size )
- eeprom_write_block( src_address , dist_address(EEPROM) , size )
- eeprom_update_block( src_address , dist_address(EEPROM) , size )
static uint8_t EEMEM EEPROM_V1[12] = "Hello World"; /* EEPROM_V1[12] を宣言 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_read_block(str, EEPROM_V1, sizeof(str)); /* EEPROM_V1[]をstr[]へまとめて読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_block(str, EEPROM_V1, sizeof(str)); /* EEPROM_V1[]へstr[]をまとめて書き込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_block(str, EEPROM_V1, sizeof(str)); /* EEPROM_V1[]をstr[]でまとめて更新 */
#include <stdint.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/eeprom.h>
static uint8_t EEMEM EEPROM_V1[12] = "Hello World"; /* EEPROM_V1[12] を宣言 */
int main( void )
{
char str[12];
/* 配列単位(ブロック)のアクセス */
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_read_block(str, EEPROM_V1, sizeof(str)); /* EEPROM_V1[]をstr[]へまとめて読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_block(str, EEPROM_V1, sizeof(str)); /* EEPROM_V1[]へstr[]をまとめて書き込み */
printf("%s", str);
sprintf(str,"hello2");
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_block(str, EEPROM_V1, sizeof(str)); /* EEPROM_V1[]をstr[]でまとめて更新 */
}
#include <stdint.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/eeprom.h>
static uint8_t EEMEM EEPROM_V1[12] = "Hello World"; /* EEPROM_V1[12] を宣言 */
int main( void )
{
char str[12];
/* 配列単位(ブロック)のアクセス */
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_read_block(str, EEPROM_V1, sizeof(str)); /* EEPROM_V1[]をstr[]へまとめて読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_block(str, EEPROM_V1, sizeof(str)); /* EEPROM_V1[]へstr[]をまとめて書き込み */
printf("%s", str);
sprintf(str,"hello2");
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_block(str, EEPROM_V1, sizeof(str)); /* EEPROM_V1[]をstr[]でまとめて更新 */
}
構造体のサンプル
EEPROM上に構造体を宣言して取り扱うことも可能です。
ブロック単位(構造体)の制御
- eeprom_read_block( dist_address , src_address(EEPROM) , size )
- eeprom_write_block( src_address , dist_address(EEPROM) , size )
- eeprom_update_block( src_address , dist_address(EEPROM) , size )
static st_t EEMEM EEPROM_st = { 1, 3, 579 }; /* 構造体 EEPROM_st を宣言 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_read_block(&st, &EEPROM_st, sizeof(st_t)); /* EEPROM_stをstへ読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_block(&st, &EEPROM_st, sizeof(st_t)); /* EEPROM_stへstを書き込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_block(&st, &EEPROM_st, sizeof(st_t)); /* EEPROM_stをstで更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
val = eeprom_read_byte(&EEPROM_st.x); /* EEPROM_st.xをvalへ1byte読出し */
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
typedef struct {
uint8_t x,y;
uint16_t z;
} st_t;
static st_t EEMEM EEPROM_st = { 1, 3, 579 }; /* 構造体 EEPROM_st を宣言 */
int main( void )
{
st_t st;
uint8_t val;
/* 構造体(ブロック)のアクセス */
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_read_block(&st, &EEPROM_st, sizeof(st_t)); /* EEPROM_stをstへ読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_block(&st, &EEPROM_st, sizeof(st_t)); /* EEPROM_stへstを書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_block(&st, &EEPROM_st, sizeof(st_t)); /* EEPROM_stをstで更新 */
/* 構造体のメンバへアクセス */
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
val = eeprom_read_byte(&EEPROM_st.x); /* EEPROM_st.xをvalへ1byte読出し */
}
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
typedef struct {
uint8_t x,y;
uint16_t z;
} st_t;
static st_t EEMEM EEPROM_st = { 1, 3, 579 }; /* 構造体 EEPROM_st を宣言 */
int main( void )
{
st_t st;
uint8_t val;
/* 構造体(ブロック)のアクセス */
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_read_block(&st, &EEPROM_st, sizeof(st_t)); /* EEPROM_stをstへ読出し */
/* EEPROM 書込み */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_write_block(&st, &EEPROM_st, sizeof(st_t)); /* EEPROM_stへstを書き込み */
/* EEPROM 更新 */
eeprom_busy_wait(); /* 読み書き可能までwait */
eeprom_update_block(&st, &EEPROM_st, sizeof(st_t)); /* EEPROM_stをstで更新 */
/* 構造体のメンバへアクセス */
/* EEPROM 読出し */
eeprom_busy_wait(); /* 読み書き可能までwait */
val = eeprom_read_byte(&EEPROM_st.x); /* EEPROM_st.xをvalへ1byte読出し */
}
参考文献