I2C EEPROM 24xx256用ユーティリティ for H8-300h

 概要
H8内臓ROMのメモリ空間ではデータが入りきらない、電源をOFFしてもデータが消えないようにしたい、 というときに便利なI2CインタフェースのEEPROM 24256をH8のソフトウェアI2Cで読み書きするための ユーティティです。 こちらも合わせてご覧ください。

 キーワード
H8-300h, H8tiny, I2C, IIC, EEPROM, 24256

 注記
きっちりとしたライブラリ化はあえてしていません。
動作実績のある1コード片として参考にしていただけたら幸いです。
著者への質問・つっこみはこちらまで。

 ソールファイル
eeprom24256.h
eeprom24256.c

 コンパイル・動作確認済み環境
ハードウェア:AKI−H8/3664F(QFP) タイニーマイコンキット(秋月電子)
シリアルI2C EEPROM AT24C256(ATMEL製)
開発環境: windows XP + cygwin + gcc3.3 + hosv4
動作実績:第11回川崎ロボット競技大会 リミットカズラ でプロポ信号から各モータの制御信号へのマッピングテーブルの 格納に使用。

 周辺回路
周辺回路
図はAT24C256とH83664Fとの組み合わせです。 24xx256のA0, A1, A2端子はI2Cスレーブアドレスの下位3ビットを設定する端子です。 I2C規格ではスレーブアドレスは基本的に7ビット(10ビットアドレッシングを除く)です。 ここで24xx256のスレーブアドレスは次のように決まります。

A0, A1, A2端子に加わる電圧がLならば対応するビットは0, Hならば1です。 スレーブアドレスを個別に割り振ることで、最大2^3=8個の24xx256を同一のバスラインに接続することができます。 この意味ではA0, A1, A2端子はメモリ空間の最上位の3ビットと見ることもできます。 これらの端子は基本的にGndか電源に直結しますが、マイコンによって動的に切り替えることも可能です。 どこにも接続しなかった場合は内部的にGndに接続されます。 図では念のためGndに直結しているのでスレーブアドレスは[1010000]=0x50となります。
また、図では省略していますがWP(ライトプロテクト)端子は開放状態とします。 この場合内部的にGndに接続され常に書き込み許可となります。

 使い方
	#include <macro.h>
	#include <i2c.h>
	#include <eeprom24256.h>

	#define I2C_ADDR_EEPROM 0x50	/* EEPROMのI2Cスレーブアドレス */
	#define ADDR_PARAM	0x00

	static unsigned char g_i2cbuff[64];
	
	int main(void){
		/* I2C初期化 */
		i2c_init();
		
		/* EEPROMから読み込む */
		eeprom_read(I2C_ADDR_EEPROM, HIBYTE(ADDR_PARAM), LOBYTE(ADDR_PARAM), g_i2cbuff, sizeof(g_i2cbuff));

		/* EEPROMへ書き込む */
		if(eeprom_write(I2C_ADDR_EEPROM, HIBYTE(ADDR_PARAM), LOBYTE(ADDR_PARAM), g_i2cbuff, sizeof(g_i2cbuff))){
			/* 焼きこみ完了を待つ */
			eeprom_poll(I2C_ADDR_EEPROM);
		}
	}
			
マクロHIBYTEとLOBYTEはこちらを参照。

 リファレンス
 BOOL eeprom_write(unsigned char i2c_addr, unsigned char addr_hi, unsigned char addr_lo, unsigned char* data, size_t nbytes)
 i2c_addr  EEPROMのI2Cスレーブアドレス
 addr_hi  書き込むアドレスの上位バイト
 addr_lo  書き込むアドレスの下位バイト
 data  書き込むデータを格納した変数へのポインタ
 nbytes  書き込むデータ長。単位はバイト
 戻り値  送信に成功したかどうか
i2c_addrで指定されたスレーブアドレスのEEPROMへのアドレス[addr_hi : addr_lo]へ dataに格納されたデータを書き込みます。 送信処理中にNACKが返された場合、送信を中断してfalseが返されます。 送信に成功した場合、EEPROMは書き込みループに入ります。 書き込み処理が完了したかどうかをチェックするにはeeprom_pollを呼び出してください。
*注意*一度に書き込めるデータ長は64バイトです。これよりも大きなデータが 一度に送信された場合、64バイトごとに内部のページバッファがロールオーバして先頭から上書きされます。 さらに、書き込むメモリ領域はページ境界をまたぐことはできません。ページとは、 メモリ空間の0番地から64バイトごとに区分けされた区間のことです。 要するに64の倍数番地をまたいではならないということです。

 void eeprom_poll(unsigned char i2c_addr);
 i2c_addr  I2Cスレーブアドレス
i2c_addrで指定されたスレーブアドレスのEEPROMに対して書き込み処理が終了するまでウェイトをかけます。 具体的には、EEPROMがACKを返すまでコントロールバイトを送信しつづけます(ACKポーリング)。 無限ループに陥る可能性があるので注意してください。

 BOOL eeprom_read(unsigned char i2c_addr, unsigned char addr_hi, unsigned char addr_lo, unsigned char* data, size_t nbytes)
 i2c_addr  EEPROMのI2Cスレーブアドレス
 addr_hi  読み出すアドレスの上位バイト
 addr_lo  読み出すアドレスの下位バイト
 data  読み出したデータを格納する変数へのポインタ
 nbytes  読み出すデータ長。単位はバイト
 戻り値  読み出しに成功したかどうか
i2c_addrで指定されたスレーブアドレスのEEPROMのアドレス[addr_hi : addr_lo]から nbytesのデータを読み出しdataへ格納します。 受信処理中にNACKが返された場合、送信を中断してfalseが返されます。 読み出しに関しては書き込みの場合のような最大長やページ境界制限はありません。