/**************************************************************************************/ /* */ /* I2C−BUS EEPROM Read/Write */ /* */ /**************************************************************************************/ #include <3048_52.H> #define SCL_H (*PBDDR = PB_DDR = PB_DDR &= ~4) #define SCL_L (*PBDDR = PB_DDR = PB_DDR |= 4) #define SDA_H (*PBDDR = PB_DDR = PB_DDR &= ~8) #define SDA_L (*PBDDR = PB_DDR = PB_DDR |= 8) #define WR_CYC 3000 /* ページ書き込み後の待ち時間 5mS以上 */ #define CYCLE 0 /* [SCL]パルス幅(約10uS) */ extern uchar PB_DDR; /* PBDDR値 変数 */ /************************************************************************** WAIT **************************************************************************/ void wait(uint count) /* 少し待つ */ { while (count){ count--; } } /************************************************************************** 1バイト書き込み **************************************************************************/ static void writeb(uchar dat) { uchar i; wait(CYCLE); for (i=0; i<=7; i++) { if (dat & 0x80) SDA_H; else SDA_L; dat <<= 1; wait(CYCLE); SCL_H; wait(CYCLE); while ((*PBDR & 4) == 0){} SCL_L; } SDA_H; /* Hi−Imp */ wait(CYCLE); SCL_H; /* ACK受信 */ wait(CYCLE); SDA_L; /* ストップコンディションとなるのを防止 */ SCL_L; } /************************************************************************** 1バイト読み出し **************************************************************************/ static void readb(uchar *dat, uchar f) { uchar i; SDA_H; /* Hi−Imp */ wait(CYCLE); for (i=0; i<=7; i++) { SCL_H; *dat <<= 1; if (*PBDR & 8) *dat |= 0x01; wait(CYCLE); while ((*PBDR & 4) == 0){} SCL_L; } if (f) SDA_H; else SDA_L; /* ACK 最終は、”H”で終了 */ wait(CYCLE); SCL_H; wait(CYCLE); SCL_L; } /************************************************************************** スタートコンディション 〜 デバイスアドレス設定 **************************************************************************/ // rw : 0=write, 1=read static void eepstart(uchar rw) { uchar c; SCL_H; SDA_H; wait(CYCLE); SDA_L; /* スタート */ wait(CYCLE); SCL_L; writeb((rw & 1) | 0xA0); /* 1010***スレーブと、R/W */ } /************************************************************************** ストップコンディション **************************************************************************/ void eepstop(void) { SCL_L; SDA_L; wait(CYCLE); SCL_H; wait(CYCLE); SDA_H; wait(CYCLE); } /************************************************************************** EEP-ROM 読み出し **************************************************************************/ /* Entry uchar page : EEP-ROM ページ番号(0〜3FFh) uchar *buf : 読み込みデータバッファ(32bytes)へのポインタ */ void eepread(uint page, uchar *buf) { uchar i; *PBDR &= ~0x0C; /* データレジスタは、出力時に絶対条件として、”L” */ eepstart(0); writeb((uchar)(page>>9)); /* 下位へ移動と、A14迄に規制する。 */ writeb((uchar)(page<<5)); /* 1ページ32バイトの為、32倍する */ wait(WR_CYC); eepstart(1); for (i=0; i<=30; i++) { readb(buf++, 0); } readb(buf, 1); /* 最後は、ACKを ”H”で終了 */ eepstop(); } /************************************************************************** EEP-ROM 書き込み **************************************************************************/ /* Entry uchar page : EEP-ROM ページ番号(0〜3FFh) uchar *buf : 書き込みデータバッファ(32bytes)へのポインタ */ void eepwrite(uint page, uchar *buf) { uchar i; *PBDR &= ~0x0C; /* データレジスタは、出力時に絶対条件として、”L” */ eepstart(0); writeb((uchar)(page>>9)); /* 下位へ移動と、A14迄に規制する。 */ writeb((uchar)(page<<5)); /* 1ページ32バイトの為、32倍する */ for (i=0; i<=31; i++) { writeb(*buf++); } eepstop(); wait(WR_CYC); } /************************************************************************** EEP-ROM ソフト・リセット **************************************************************************/ void eepreset() { uchar i; for (i=0; i<9; i++){ SDA_L; wait(CYCLE); SCL_L; wait(CYCLE); SDA_H; wait(CYCLE); SCL_H; wait(CYCLE); } }