目次
前
次
外部EEPROMアクセス
Arduinoには、内蔵EEPROMがありますが、256
バイトから1024バイト程度で、大量の情報を
保存するのには、向いていません。
IICバスの8kバイト、32kバイトのEEPROMを
接続して、大量の情報を保存するための基本
実験をします。
利用したEEPROMは、無線サークルの知人から
貰った表面実装タイプで、DIP化基板に半田
づけして利用。
ArduinoのAPIには、IICバスを扱うライブラリが
用意されているので、ライブラリを使って処理
することを考えてます。
1バイトのリード、ライトの関数を定義。
void put_eeprom(word xadr,byte xdat)
{
byte adh ;
byte adl ;
byte xx ;
xx = xdat ;
/* separate address */
adl = xadr & 0xff ;
adh = (xadr >> 8) & 0x1f ;
/* write 1 byte */
Wire.beginTransmission(ROM_ADRS);
Wire.write(adh); /* upper address */
Wire.write(adl); /* lower address */
Wire.write(xx ); /* data */
Wire.endTransmission();
/* wait 6ms */
delay(5);
}
byte get_eeprom(word xadr)
{
byte adh ;
byte adl ;
byte result ;
/* default */
result = BSIZE ;
/* separate address */
adl = xadr & 0xff ;
adh = (xadr >> 8) & 0x1f ;
/* impress address */
Wire.beginTransmission(ROM_ADRS);
Wire.write(adh); /* upper address */
Wire.write(adl); /* lower address */
Wire.endTransmission();
/* read 1 byte */
Wire.requestFrom(ROM_ADRS,1);
if ( Wire.available() ) { result = Wire.read() ; }
return result ;
}
2関数の中で利用しているEEPROMのデバイス
IDは、ROMX_ADRSで0x50としました。
IICバスは、ひとつのバスに最大8デバイスまで
接続できます。デバイスIDに、ハードウエアで
指定するIICバス上でのアドレスを加えて、各々
のデバイスを区別していきます。
今回利用したEEPROMは、24C64でピンアサインは
次のようになっています。
E0からE2で、デバイスのバス上のアドレスを決定。
E0、E1、E2の3ビットは、0Vに接続したので
EEPROMのアドレスは、0x50になります。
IICバス上のアドレスは、3ビットですが
デバイスIDは4ビット。合計7ビットで
ターゲットEEPROMを指定。
ArduinoのWireライブラリでは、7ビットを
扱いますが、8ビットに拡張して与えれば
各関数の動作は、問題になりません。
1バイトのライト、リードは、次のタイミング
チャートを利用して定義しました。
ライトには、WCピンを0Vに接続していなければ
ならず、ICソケットを利用して、基板に実装と
いう場合に、半田付けして対応。
1バイトのライトでも、32バイト(1ページ)の
ライトでも、書き込まれるまでに、5msの時間が
必要とデータシートに記載があります。
リードは、その時点で与えられていたアドレスを
利用するモードを使っています。
アドレスは、デバイスID、IICバス上のアドレスに
続けて、EEPROM内部のデータのアドレスを設定と
なるので、関数内のコードは、次の記述になると
わかります。
/* separate address */
adl = xadr & 0xff ;
adh = (xadr >> 8) & 0x1f ;
/* impress address */
Wire.beginTransmission(ROM_ADRS);
Wire.write(adh); /* upper address */
Wire.write(adl); /* lower address */
Wire.endTransmission();
1バイトのライトとリードの関数を用意したので
実際に使ってみます。
コマンドを用意して対応。
- ? ヘルプ
- L EEPROMから256バイト分のデータ取得
- S EEPROMへ256バイト分のデータ転送
- D EEPROMから取得した256バイトのデータ表示
コマンドを決めたなら、インタプリタを定義します。
if ( uflag == ON ) {
/* clear flag */
uflag = OFF ;
/* get command */
cmd = *(sbuf+0) ;
/* help */
if ( cmd == '?' ) { show_help(); }
/* load data from EEPROM */
if ( cmd == 'L' ) { loadEEPROM(); }
/* test transfer */
if ( cmd == 'S' ) { saveEEPROM(); }
/* show EEPROM context */
if ( cmd == 'D' ) { showEEPROM(); }
/* new line */
crlf() ;
}
コマンド受信をイベント通知フラグuflagのセットで
確認しておき、受信バッファからコマンドを取得して
個々の処理に分岐します。
コマンドは受信割込みを使えばよいので、定番のコード
にて対応しました。
void serialEvent()
{
char ch;
if ( Serial.available() > 0 ) {
/* get 1 character */
ch = Serial.read();
/* store */
*(sbuf+sindex) = ch ;
/* increment */
sindex++ ;
/* judge */
if ( ch == '\r' ) {
sindex = 0 ;
uflag = ON ;
}
}
}
個々の関数と手続きを、定義。
ヘルプ
ヘルプは、1文字コマンドと機能を説明だけにします。
void show_help()
{
rs_puts("? help") ; crlf();
rs_puts("L load 256 data") ; crlf();
rs_puts("S save 256 data") ; crlf();
rs_puts("D display 256 date"); crlf();
}
文字列表示は、自前で定義。
void rs_putchar(char x)
{
Serial.write(x);
}
void rs_puts(char *ptr)
{
while ( *ptr ) {
rs_putchar( *ptr );
ptr++;
}
}
void crlf()
{
rs_putchar('\r');
rs_putchar('\n');
}
データ取得
256バイトと固定しているので、関数get_eepromを
256回利用して、配列に格納します。
void loadEEPROM()
{
word ii ;
for ( ii = 0 ; ii < BSIZE ; ii++ ) {
*(zdat+ii) = get_eeprom( ii ) ;
}
}
配列をzdatとして、256バイト分確保。
#define BSIZE 256
byte zdat[BSIZE] ;
データ転送
関数put_eepromを利用して、1バイトごとのデータを
生成し、全体で256バイトをEEPROMに格納。
同じデータを保存しては、正常に動作しているのか
見分けがつかないので、アドレスにより数値を変動
させます。
void saveEEPROM()
{
word ii ;
for ( ii = 0 ; ii < BSIZE ; ii++ ) {
put_eeprom( (word)ii , 255 - ii ) ;
}
}
データ表示
配列に格納してあるデータを16進数で表示。
一度EEPROMから配列にデータを取り出して
あるので、配列の内容表示で対応。
void showEEPROM()
{
byte tmp ;
word ii ;
char msg[2] ;
for ( ii = 0 ; ii < BSIZE ; ii++ ) {
/* get */
tmp = *(zdat+ii) ;
/* lower */
*(msg+1) = getHex( tmp & 15 );
/* upper */
*(msg+0) = getHex( (tmp >> 4) & 15 );
/* impress */
rs_putchar( *(msg+0) );
rs_putchar( *(msg+1) );
rs_putchar( ' ' );
/* new line */
if ( (ii & 15) == 15 ) { crlf(); }
}
}
数値を16進数の数字に変えるのは、関数を定義して
対応すればよいはず。
char getHex(byte x)
{
char result ;
/* default */
result = '0' ;
/* judge */
if ( 0 <= x && x <= 9 ) { result = x + '0' ; }
if ( x > 9 ) { result = x - 10 + 'A' ; }
return result ;
}
必要な部品が揃ったので、スケッチにまとめます。
#include <Wire.h>
#define OFF 0
#define ON OFF+1
#define BSIZE 256
#define ROM_ADRS 0x50
#define LED_BIT 5
boolean uflag ;
/* variables */
char sbuf[8] ;
byte sindex ;
byte cmd ;
byte zdat[BSIZE] ;
void update_trigger();
void show_help();
void rs_putchar(char x);
void rs_puts(char *ptr);
void crlf();
void put_eeprom(word xadr,byte xdat);
byte get_eeprom(word xadr);
void loadEEPROM();
void saveEEPROM();
void showEEPROM();
char getHex(byte x);
void setup()
{
Serial.begin(9600);
rs_puts("Hello !");
crlf();
/* port value */
PORTB = 0x00 ;
PORTC = 0x00 ;
PORTD = 0x00 ;
/* port direction */
DDRB = 0xff ;
DDRC = 0xf0 ;
DDRD = 0xfe ;
/* flags */
uflag = OFF ;
/* enable IIC bus */
Wire.begin();
/* get 256 bytes from EEPROM */
loadEEPROM();
}
void loop()
{
/* command interpreter */
if ( uflag == ON ) {
/* clear flag */
uflag = OFF ;
/* get command */
cmd = *(sbuf+0) ;
/* help */
if ( cmd == '?' ) { show_help(); }
/* load data from EEPROM */
if ( cmd == 'L' ) { loadEEPROM(); }
/* test transfer */
if ( cmd == 'S' ) { saveEEPROM(); }
/* show EEPROM context */
if ( cmd == 'D' ) { showEEPROM(); }
/* new line */
crlf() ;
}
}
void show_help()
{
rs_puts("? help") ; crlf();
rs_puts("L load 256 data") ; crlf();
rs_puts("S save 256 data") ; crlf();
rs_puts("D display 256 date"); crlf();
}
void rs_putchar(char x)
{
Serial.write(x);
}
void rs_puts(char *ptr)
{
while ( *ptr ) {
rs_putchar( *ptr );
ptr++;
}
}
void crlf()
{
rs_putchar('\r');
rs_putchar('\n');
}
void put_eeprom(word xadr,byte xdat)
{
byte adh ;
byte adl ;
byte xx ;
xx = xdat ;
/* separate address */
adl = xadr & 0xff ;
adh = (xadr >> 8) & 0x1f ;
/* write 1 byte */
Wire.beginTransmission(ROM_ADRS);
Wire.write(adh); /* upper address */
Wire.write(adl); /* lower address */
Wire.write(xx ); /* data */
Wire.endTransmission();
/* wait 6ms */
delay(5);
}
byte get_eeprom(word xadr)
{
byte adh ;
byte adl ;
byte result ;
/* default */
result = BSIZE ;
/* separate address */
adl = xadr & 0xff ;
adh = (xadr >> 8) & 0x1f ;
/* impress address */
Wire.beginTransmission(ROM_ADRS);
Wire.write(adh); /* upper address */
Wire.write(adl); /* lower address */
Wire.endTransmission();
/* read 1 byte */
Wire.requestFrom(ROM_ADRS,1);
if ( Wire.available() ) { result = Wire.read() ; }
return result ;
}
void loadEEPROM()
{
word ii ;
for ( ii = 0 ; ii < BSIZE ; ii++ ) {
*(zdat+ii) = get_eeprom( ii ) ;
}
}
void saveEEPROM()
{
word ii ;
for ( ii = 0 ; ii < BSIZE ; ii++ ) {
put_eeprom( (word)ii , 255 - ii ) ;
}
}
void showEEPROM()
{
byte tmp ;
word ii ;
char msg[2] ;
for ( ii = 0 ; ii < BSIZE ; ii++ ) {
/* get */
tmp = *(zdat+ii) ;
/* lower */
*(msg+1) = getHex( tmp & 15 );
/* upper */
*(msg+0) = getHex( (tmp >> 4) & 15 );
/* impress */
rs_putchar( *(msg+0) );
rs_putchar( *(msg+1) );
rs_putchar( ' ' );
/* new line */
if ( (ii & 15) == 15 ) { crlf(); }
}
}
char getHex(byte x)
{
char result ;
/* default */
result = '0' ;
/* judge */
if ( 0 <= x && x <= 9 ) { result = x + '0' ; }
if ( x > 9 ) { result = x - 10 + 'A' ; }
return result ;
}
/* receive interrupt */
void serialEvent()
{
char ch;
if ( Serial.available() > 0 ) {
/* get 1 character */
ch = Serial.read();
/* store */
*(sbuf+sindex) = ch ;
/* increment */
sindex++ ;
/* judge */
if ( ch == '\r' ) {
sindex = 0 ;
uflag = ON ;
}
}
}
TeraTermを利用して、動作を確認します。
端末ソフトの起動で、オープニングメッセージを表示。
ヘルプコマンドのテスト。
データ転送コマンド実行。
データ取得コマンド実行。
データ表示コマンド実行。
EEPROMへの1バイトライトとEEPROMからの
1バイトリードにラッパー関数を用意して
コマンドインタプリタで処理できていると
わかります。
ページごとのリード、ライトも可能なので
リードに限定し、処理するスケッチを作成。
ページリードの関数は、次のように定義しました。
void get_page_eeprom(word xadr)
{
byte adh ;
byte adl ;
/* separate address */
adl = xadr & 0xff ;
adh = (xadr >> 8) & 0x1f ;
/* write entry address */
Wire.beginTransmission(ROM_ADRS);
Wire.write(adh); /* upper address */
Wire.write(adl); /* lower address */
Wire.endTransmission();
/* get 32 bytes */
Wire.requestFrom(ROM_ADRS,32);
/* copy */
if ( Wire.available() ) {
for ( adl = 0 ; adl < 32 ; adl++ ) {
*(ydat+adl) = Wire.read();
}
}
/* show */
for ( adl = 0 ; adl < 32 ; adl++ ) {
adh = *(ydat+adl) ;
rs_putchar( getHex( (adh >> 4) & 15 ) );
rs_putchar( getHex( adh & 15 ) );
rs_putchar(' ');
if ( (adl % 16) == 15 ) { crlf(); }
}
}
コマンドを増やし、ページリード関係の関数が
使えるようにします。
増やしたコマンドは、以下。
- D show buffer context
- E get 32 bytes(1 page)
- F fill data to buffer
スケッチは、次のようにまとめました。
#include <Wire.h>
#define OFF 0
#define ON OFF+1
#define BSIZE 256
#define ROM_ADRS 0x50
#define LED_BIT 5
boolean uflag ;
/* variables */
char sbuf[4] ;
byte sindex ;
byte cmd ;
byte ydat[32];
byte zdat[BSIZE] ;
void update_trigger();
void show_help();
void rs_putchar(char x);
void rs_puts(char *ptr);
void crlf();
void put_eeprom(word xadr,byte xdat);
void get_page_eeprom(word xadr);
void loadEEPROM();
void saveEEPROM();
void showBuffer();
void generateData();
char getHex(byte x);
byte getVal(char x);
void setup()
{
Serial.begin(9600);
rs_puts("Hello !");
crlf();
/* port value */
PORTB = 0x00 ;
PORTC = 0x00 ;
PORTD = 0x00 ;
/* port direction */
DDRB = 0xff ;
DDRC = 0xf0 ;
DDRD = 0xfe ;
/* flags */
uflag = OFF ;
/* enable IIC bus */
Wire.begin();
}
void loop()
{
/* command interpreter */
if ( uflag == ON ) {
/* clear flag */
uflag = OFF ;
/* get command */
cmd = *(sbuf+0) ;
/* help */
if ( cmd == '?' ) { show_help(); }
/* show EEPROM context */
if ( cmd == 'D' ) { showBuffer(); }
/* get EEPROM with page mode */
if ( cmd == 'E' ) { showPage(); }
/* show EEPROM context */
if ( cmd == 'F' ) { generateData(); }
/* load data from EEPROM */
if ( cmd == 'L' ) { loadEEPROM(); }
/* test transfer */
if ( cmd == 'S' ) { saveEEPROM(); }
/* new line */
crlf() ;
}
}
void show_help()
{
rs_puts("? help") ; crlf();
rs_puts("D display buffer") ; crlf();
rs_puts("E show page context"); crlf();
rs_puts("F fill value") ; crlf();
rs_puts("L load 256 data") ; crlf();
rs_puts("S save 256 data") ; crlf();
}
void rs_putchar(char x)
{
Serial.write(x);
}
void rs_puts(char *ptr)
{
while ( *ptr ) {
rs_putchar( *ptr );
ptr++;
}
}
void crlf()
{
rs_putchar('\r');
rs_putchar('\n');
}
void put_eeprom(word xadr,byte xdat)
{
byte adh ;
byte adl ;
byte xx ;
xx = xdat ;
/* separate address */
adl = xadr & 0xff ;
adh = (xadr >> 8) & 0x1f ;
/* write 1 byte */
Wire.beginTransmission(ROM_ADRS);
Wire.write(adh); /* upper address */
Wire.write(adl); /* lower address */
Wire.write(xx ); /* data */
Wire.endTransmission();
/* wait 5ms */
delay(5);
}
void get_page_eeprom(word xadr)
{
byte adh ;
byte adl ;
/* separate address */
adl = xadr & 0xff ;
adh = (xadr >> 8) & 0x1f ;
/* write entry address */
Wire.beginTransmission(ROM_ADRS);
Wire.write(adh); /* upper address */
Wire.write(adl); /* lower address */
Wire.endTransmission();
/* get 32 bytes */
Wire.requestFrom(ROM_ADRS,32);
/* copy */
if ( Wire.available() ) {
for ( adl = 0 ; adl < 32 ; adl++ ) {
*(ydat+adl) = Wire.read();
}
}
/* show */
for ( adl = 0 ; adl < 32 ; adl++ ) {
adh = *(ydat+adl) ;
rs_putchar( getHex( (adh >> 4) & 15 ) );
rs_putchar( getHex( adh & 15 ) );
rs_putchar(' ');
if ( (adl % 16) == 15 ) { crlf(); }
}
}
void loadEEPROM()
{
byte i ;
byte j ;
word xad ;
for ( i = 0 ; i < 8 ; i++ ) {
xad = (i << 5) ;
get_page_eeprom( xad ) ;
for ( j = 0 ; j < 32 ; j++ ) {
*(zdat + j + xad) = *(ydat + j) ;
}
}
}
void saveEEPROM()
{
word ii ;
for ( ii = 0 ; ii < BSIZE ; ii++ ) {
put_eeprom( ii , *(zdat+ii) ) ;
}
}
void showBuffer()
{
byte tmp ;
word ii ;
char msg[2] ;
for ( ii = 0 ; ii < BSIZE ; ii++ ) {
/* get */
tmp = *(zdat+ii) ;
/* lower */
*(msg+1) = getHex( tmp & 15 );
/* upper */
*(msg+0) = getHex( (tmp >> 4) & 15 );
/* impress */
rs_putchar( *(msg+0) );
rs_putchar( *(msg+1) );
rs_putchar( ' ' );
/* new line */
if ( (ii & 15) == 15 ) { crlf(); }
}
}
void generateData()
{
byte xx ;
/* get data from receive buffer */
xx = getVal( *(sbuf+1) ) ;
xx <<= 4 ;
xx += getVal( *(sbuf+2) ) ;
/* store */
for ( word i = 0 ; i < BSIZE ; i++ ) { *(zdat+i) = xx ; }
}
void showPage()
{
word xx ;
/* get page number */
xx = getVal( *(sbuf+1) );
xx <<= 5 ;
/* */
get_page_eeprom( xx );
}
char getHex(byte x)
{
char result ;
/* default */
result = '0' ;
/* judge */
if ( 0 <= x && x <= 9 ) { result = x + '0' ; }
if ( x > 9 ) { result = x - 10 + 'A' ; }
return result ;
}
byte getVal(char x)
{
byte result ;
/* default */
result = 0 ;
/* judge */
if ( '0' <= x && x <= '9' ) { result = x - '0' ; }
if ( 'A' <= x && x <= 'F' ) { result = x - 'A' + 10 ; }
if ( 'a' <= x && x <= 'f' ) { result = x - 'a' + 10 ; }
return result ;
}
/* receive interrupt */
void serialEvent()
{
char ch;
if ( Serial.available() > 0 ) {
/* get 1 character */
ch = Serial.read();
/* store */
*(sbuf+sindex) = ch ;
/* increment */
sindex++ ;
/* judge */
if ( ch == '\r' ) {
sindex = 0 ;
uflag = ON ;
}
}
}
端末操作で、次のようになりました。
コマンドを確認。
'D'コマンドで、現在のバッファの内容を表示。
'L'コマンドで、EEPROMの256バイトの内容を確認。
バッファにデータを保存後、EEPROMに256バイトを
格納し、'L'コマンドで、EEPROMの256バイトの内容
を確認。
問題なく動作していることがわかります。
'E'コマンドが、正しく動いているのかを確認します。
'L'コマンドで、EEPROMの先頭256バイトの内容を確認。
'E'コマンドで、32バイトごとにデータを取得して
表示されていることを確認できました。
1個のEEPROMをアクセスできるようになったので
2個のEEPROM(2個で、16kバイト)をアクセス
できるように半田付けしました。
スケッチは、次のように定義しました。
#include <Wire.h>
#define OFF 0
#define ON OFF+1
#define BSIZE 256
#define ROM_ADRS 0x50
#define ROM_ADRSX 0x51
#define LED_BIT 5
boolean uflag ;
boolean cflag ;
/* variables */
char sbuf[4] ;
byte sindex ;
byte cmd ;
byte ydat[32];
byte zdat[BSIZE] ;
void update_trigger();
void show_help();
void rs_putchar(char x);
void rs_puts(char *ptr);
void crlf();
void put_eeprom(word xadr,byte xdat);
void get_page_eeprom(word xadr);
void loadEEPROM();
void saveEEPROM();
void putPage();
void showAll();
void showBuffer();
void showPage();
void generateData();
char getHex(byte x);
byte getVal(char x);
void setup()
{
Serial.begin(9600);
rs_puts("Hello !");
crlf();
show_help();
/* port value */
PORTB = 0x00 ;
PORTC = 0x00 ;
PORTD = 0x00 ;
/* port direction */
DDRB = 0xff ;
DDRC = 0xf0 ;
DDRD = 0xfe ;
/* flags */
uflag = OFF ;
/* enable IIC bus */
Wire.begin();
}
void loop()
{
/* command interpreter */
if ( uflag == ON ) {
/* clear flag */
uflag = OFF ;
/* get command */
cmd = *(sbuf+0) ;
/* help */
if ( cmd == '?' ) { show_help(); }
/* show all area */
if ( cmd == 'A' ) { showAll(); }
/* show EEPROM context */
if ( cmd == 'D' ) { showBuffer(); }
/* get EEPROM with page mode */
if ( cmd == 'E' ) { showPage(); }
/* show EEPROM context */
if ( cmd == 'F' ) { generateData(); }
/* load data from EEPROM */
if ( cmd == 'l' ) {
cflag = OFF ;
loadEEPROM();
}
if ( cmd == 'L' ) {
cflag = ON ;
loadEEPROM();
}
/* test transfer */
if ( cmd == 's' ) {
cflag = OFF ;
saveEEPROM();
}
if ( cmd == 'S' ) {
cflag = ON ;
saveEEPROM();
}
/* new line */
crlf() ;
}
}
void show_help()
{
rs_puts("? help") ; crlf();
rs_puts("A show whole area") ; crlf();
rs_puts("D display buffer") ; crlf();
rs_puts("E show page context") ; crlf();
rs_puts("F fill value") ; crlf();
rs_puts("l load 256 data(lower)") ; crlf();
rs_puts("L load 256 data(upper)") ; crlf();
rs_puts("s save 256 data(lower)") ; crlf();
rs_puts("S save 256 data(upper)") ; crlf();
}
void rs_putchar(char x)
{
Serial.write(x);
}
void rs_puts(char *ptr)
{
while ( *ptr ) {
rs_putchar( *ptr );
ptr++;
}
}
void crlf()
{
rs_putchar('\r');
rs_putchar('\n');
}
void put_eeprom(word xadr,byte xdat)
{
byte adh ;
byte adl ;
byte xx ;
xx = xdat ;
/* separate address */
adl = xadr & 0xff ;
adh = (xadr >> 8) & 0x1f ;
/* write 1 byte */
if ( cflag ) { Wire.beginTransmission(ROM_ADRSX); }
else { Wire.beginTransmission(ROM_ADRS ); }
Wire.write(adh); /* upper address */
Wire.write(adl); /* lower address */
Wire.write(xx ); /* data */
Wire.endTransmission();
/* wait 5ms */
delay(5);
}
void get_page_eeprom(word xadr)
{
byte adh ;
byte adl ;
/* separate address */
adl = xadr & 0xff ;
adh = (xadr >> 8) & 0x1f ;
/* write entry address */
if ( cflag ) { Wire.beginTransmission(ROM_ADRSX); }
else { Wire.beginTransmission(ROM_ADRS ); }
Wire.write(adh); /* upper address */
Wire.write(adl); /* lower address */
Wire.endTransmission();
/* get 32 bytes */
if ( cflag ) { Wire.requestFrom(ROM_ADRSX,32); }
else { Wire.requestFrom(ROM_ADRS ,32); }
/* copy */
if ( Wire.available() ) {
for ( adl = 0 ; adl < 32 ; adl++ ) { *(ydat+adl) = Wire.read(); }
}
/* show */
for ( adl = 0 ; adl < 32 ; adl++ ) {
adh = *(ydat+adl) ;
rs_putchar( getHex( (adh >> 4) & 15 ) );
rs_putchar( getHex( adh & 15 ) );
rs_putchar(' ');
if ( (adl % 16) == 15 ) { crlf(); }
}
}
void loadEEPROM()
{
byte i ;
byte j ;
word xad ;
for ( i = 0 ; i < 8 ; i++ ) {
xad = (i << 5) ;
get_page_eeprom( xad ) ;
/* store data to buffer */
for ( j = 0 ; j < 32 ; j++ ) { *(zdat + j + xad) = *(ydat + j) ; }
}
}
void saveEEPROM()
{
word ii ;
rs_puts("Start !");
crlf();
for ( ii = 0 ; ii < BSIZE ; ii++ ) {
put_eeprom( ii , *(zdat+ii) ) ;
rs_putchar('.');
if ( (ii & 15) == 15 ) { crlf(); }
}
rs_puts("Complete !");
crlf();
}
void putPage()
{
word i ;
word xad ;
/* EEPROM contexnt */
for ( i = 0 ; i < 256 ; i++ ) {
xad = (i << 5) ;
get_page_eeprom( xad ) ;
}
}
void showAll()
{
byte i ;
/* loop */
for ( i = 0 ; i < 2 ; i++ ) {
if ( i ) { rs_puts("ROM_1"); cflag = ON ; }
else { rs_puts("ROM_0"); cflag = OFF ; }
crlf();
putPage();
}
}
void showBuffer()
{
byte tmp ;
word ii ;
char msg[2] ;
for ( ii = 0 ; ii < BSIZE ; ii++ ) {
/* get */
tmp = *(zdat+ii) ;
/* lower */
*(msg+1) = getHex( tmp & 15 );
/* upper */
*(msg+0) = getHex( (tmp >> 4) & 15 );
/* impress */
rs_putchar( *(msg+0) );
rs_putchar( *(msg+1) );
rs_putchar( ' ' );
/* new line */
if ( (ii & 15) == 15 ) { crlf(); }
}
}
void generateData()
{
byte xx ;
/* get data from receive buffer */
xx = getVal( *(sbuf+1) ) ;
xx <<= 4 ;
xx += getVal( *(sbuf+2) ) ;
/* store */
for ( word i = 0 ; i < BSIZE ; i++ ) { *(zdat+i) = xx ; }
}
void showPage()
{
word xx ;
/* get page number */
xx = getVal( *(sbuf+1) );
xx <<= 5 ;
/* */
get_page_eeprom( xx );
}
char getHex(byte x)
{
char result ;
/* default */
result = '0' ;
/* judge */
if ( 0 <= x && x <= 9 ) { result = x + '0' ; }
if ( x > 9 ) { result = x - 10 + 'A' ; }
return result ;
}
byte getVal(char x)
{
byte result ;
/* default */
result = 0 ;
/* judge */
if ( '0' <= x && x <= '9' ) { result = x - '0' ; }
if ( 'A' <= x && x <= 'F' ) { result = x - 'A' + 10 ; }
if ( 'a' <= x && x <= 'f' ) { result = x - 'a' + 10 ; }
return result ;
}
/* receive interrupt */
void serialEvent()
{
char ch;
if ( Serial.available() > 0 ) {
/* get 1 character */
ch = Serial.read();
/* store */
*(sbuf+sindex) = ch ;
/* increment */
sindex++ ;
/* judge */
if ( ch == '\r' ) {
sindex = 0 ;
uflag = ON ;
}
}
}
これで、動作することがわかったので、次に4個の
EEPROMを使うための基板を半田付けしました。
スケッチは、以下。
#include <Wire.h>
#define OFF 0
#define ON OFF+1
#define BSIZE 256
#define ROM_ADRS 0x50
#define ROM_ADRS1 0x51
#define ROM_ADRS2 0x52
#define ROM_ADRS3 0x53
#define LED_BIT 5
boolean uflag ;
/* variables */
char sbuf[4] ;
byte sindex ;
byte cmd ;
byte bnum ;
byte ydat[32];
byte zdat[BSIZE] ;
void update_trigger();
void show_help();
void rs_putchar(char x);
void rs_puts(char *ptr);
void crlf();
void put_eeprom(word xadr,byte xdat);
void get_page_eeprom(word xadr);
void loadEEPROM();
void saveEEPROM();
void putPage();
void getBlockNumber();
void showAll();
void showBuffer();
void generateData();
char getHex(byte x);
byte getVal(char x);
void setup()
{
Serial.begin(9600);
rs_puts("Hello !");
crlf();
show_help();
/* port value */
PORTB = 0x00 ;
PORTC = 0x00 ;
PORTD = 0x00 ;
/* port direction */
DDRB = 0xff ;
DDRC = 0xf0 ;
DDRD = 0xfe ;
/* flags */
uflag = OFF ;
/* */
bnum = 0 ;
/* enable IIC bus */
Wire.begin();
}
void loop()
{
/* command interpreter */
if ( uflag == ON ) {
/* clear flag */
uflag = OFF ;
/* get command */
cmd = *(sbuf+0) ;
/* help */
if ( cmd == '?' ) { show_help(); }
/* show all area */
if ( cmd == 'A' ) { showAll(); }
/* set block */
if ( cmd == 'B' ) { getBlockNumber(); }
/* show block number */
if ( cmd == 'b' ) { rs_putchar( bnum + '0' ); crlf(); }
/* show EEPROM context */
if ( cmd == 'D' ) { showBuffer(); }
/* show EEPROM context */
if ( cmd == 'F' ) { generateData(); }
/* load data from EEPROM */
if ( cmd == 'L' ) { loadEEPROM(); }
/* test transfer */
if ( cmd == 'S' ) { saveEEPROM(); }
/* new line */
crlf() ;
}
}
void show_help()
{
rs_puts("? help") ; crlf();
rs_puts("A show whole area") ; crlf();
rs_puts("B put block number") ; crlf();
rs_puts("b get block number") ; crlf();
rs_puts("D display buffer") ; crlf();
rs_puts("F fill value") ; crlf();
rs_puts("L load 256 data") ; crlf();
rs_puts("S save 256 data") ; crlf();
}
void rs_putchar(char x)
{
Serial.write(x);
}
void rs_puts(char *ptr)
{
while ( *ptr ) {
rs_putchar( *ptr );
ptr++;
}
}
void crlf()
{
rs_putchar('\r');
rs_putchar('\n');
}
void put_eeprom(word xadr,byte xdat)
{
byte adh ;
byte adl ;
byte xx ;
/* copy */
xx = xdat ;
/* separate address */
adl = xadr & 0xff ;
adh = (xadr >> 8) & 0x1f ;
/* write 1 byte */
switch ( bnum ) {
case 1 : Wire.beginTransmission(ROM_ADRS1); break;
case 2 : Wire.beginTransmission(ROM_ADRS2); break;
case 3 : Wire.beginTransmission(ROM_ADRS3); break;
default : Wire.beginTransmission(ROM_ADRS ); break;
}
Wire.write(adh); /* upper address */
Wire.write(adl); /* lower address */
Wire.write(xx ); /* data */
Wire.endTransmission();
/* wait 5ms */
delay(5);
}
void get_page_eeprom(word xadr)
{
byte adh ;
byte adl ;
/* separate address */
adl = xadr & 0xff ;
adh = (xadr >> 8) & 0x1f ;
/* write entry address */
switch ( bnum ) {
case 1 : Wire.beginTransmission(ROM_ADRS1); break;
case 2 : Wire.beginTransmission(ROM_ADRS2); break;
case 3 : Wire.beginTransmission(ROM_ADRS3); break;
default : Wire.beginTransmission(ROM_ADRS ); break;
}
Wire.write(adh); /* upper address */
Wire.write(adl); /* lower address */
Wire.endTransmission();
/* get 32 bytes */
switch ( bnum ) {
case 1 : Wire.requestFrom(ROM_ADRS1,32); break;
case 2 : Wire.requestFrom(ROM_ADRS2,32); break;
case 3 : Wire.requestFrom(ROM_ADRS3,32); break;
default : Wire.requestFrom(ROM_ADRS ,32); break;
}
/* copy */
if ( Wire.available() ) {
for ( adl = 0 ; adl < 32 ; adl++ ) { *(ydat+adl) = Wire.read(); }
}
/* show */
for ( adl = 0 ; adl < 32 ; adl++ ) {
adh = *(ydat+adl) ;
rs_putchar( getHex( (adh >> 4) & 15 ) );
rs_putchar( getHex( adh & 15 ) );
rs_putchar(' ');
if ( (adl % 16) == 15 ) { crlf(); }
}
}
void loadEEPROM()
{
byte i ;
byte j ;
word xad ;
for ( i = 0 ; i < 8 ; i++ ) {
xad = (i << 5) ;
get_page_eeprom( xad ) ;
/* store data to buffer */
for ( j = 0 ; j < 32 ; j++ ) { *(zdat + j + xad) = *(ydat + j) ; }
}
}
void saveEEPROM()
{
word ii ;
rs_puts("Start !");
crlf();
for ( ii = 0 ; ii < BSIZE ; ii++ ) {
put_eeprom( ii , *(zdat+ii) ) ;
rs_putchar('.');
if ( (ii & 15) == 15 ) { crlf(); }
}
rs_puts("Complete !");
crlf();
}
void putPage()
{
word i ;
word xad ;
/* EEPROM contexnt */
for ( i = 0 ; i < 256 ; i++ ) {
xad = (i << 5) ;
get_page_eeprom( xad ) ;
}
}
void getBlockNumber()
{
/* get block number */
bnum = getVal( *(sbuf+1) ) ;
/* judge */
if ( bnum > 3 ) { bnum = 0 ; }
/* show block number */
rs_putchar( bnum + '0' );
/* new line */
crlf();
}
void showAll()
{
byte i;
/* show */
for ( i = 0 ; i < 4 ; i++ ) {
/* block number */
if ( i == 0 ) { rs_puts("ROM_0"); }
if ( i == 1 ) { rs_puts("ROM_1"); }
if ( i == 2 ) { rs_puts("ROM_2"); }
if ( i == 3 ) { rs_puts("ROM_3"); }
/* new line */
crlf();
/* update block number */
bnum = i ;
/* show */
putPage();
}
/* default */
bnum = 0 ;
}
void showBuffer()
{
byte tmp ;
word ii ;
char msg[2] ;
for ( ii = 0 ; ii < BSIZE ; ii++ ) {
/* get */
tmp = *(zdat+ii) ;
/* lower */
*(msg+1) = getHex( tmp & 15 );
/* upper */
*(msg+0) = getHex( (tmp >> 4) & 15 );
/* impress */
rs_putchar( *(msg+0) );
rs_putchar( *(msg+1) );
rs_putchar( ' ' );
/* new line */
if ( (ii & 15) == 15 ) { crlf(); }
}
}
void generateData()
{
byte xx ;
word i ;
/* get data from receive buffer */
xx = getVal( *(sbuf+1) ) ;
xx <<= 4 ;
xx += getVal( *(sbuf+2) ) ;
/* store */
for ( i = 0 ; i < BSIZE ; i++ ) { *(zdat+i) = xx ; }
}
char getHex(byte x)
{
char result ;
/* default */
result = '0' ;
/* judge */
if ( 0 <= x && x <= 9 ) { result = x + '0' ; }
if ( x > 9 ) { result = x - 10 + 'A' ; }
return result ;
}
byte getVal(char x)
{
byte result ;
/* default */
result = 0 ;
/* judge */
if ( '0' <= x && x <= '9' ) { result = x - '0' ; }
if ( 'A' <= x && x <= 'F' ) { result = x - 'A' + 10 ; }
if ( 'a' <= x && x <= 'f' ) { result = x - 'a' + 10 ; }
return result ;
}
/* receive interrupt */
void serialEvent()
{
char ch;
if ( Serial.available() > 0 ) {
/* get 1 character */
ch = Serial.read();
/* store */
*(sbuf+sindex) = ch ;
/* increment */
sindex++ ;
/* judge */
if ( ch == '\r' ) {
sindex = 0 ;
uflag = ON ;
}
}
}
目次
前
次