目次
前
次
EEPROMハンドリング
EEPROMをアクセスするスケッチは、新規に開発しました。
8kバイトのEEPROMを扱うスケッチは、以下。
/*
romtstx.ino
PORTB
PB5 (output) LED
PB4 (output) --
PB3 (output) --
PB2 (output) --
PB1 (output) --
PB0 (output) --
PORTC
PC5 (output) SCL
PC4 (output) SDA
PC3 (output) --
PC2 (output) --
PC1 (output) --
PC0 (output) --
*/
#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];
void update_trigger();
void show_help();
void rs_putchar(char x);
void rs_puts(char *ptr);
void crlf();
void get_page_eeprom(word xadr);
void loadEEPROM();
void put_eeprom(word xadr,byte xdat);
void fillEEPROM();
char getHex(byte x);
void setup()
{
Serial.begin(115200);
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(); }
/* load data from EEPROM */
if ( cmd == 'L' ) { loadEEPROM(); }
/* fill data EEPROM */
if ( cmd == 'F' ) { fillEEPROM(); }
/* new line */
crlf() ;
}
}
void show_help()
{
rs_puts("? help") ; crlf();
rs_puts("F fill FF") ; crlf();
rs_puts("L load 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 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(); }
}
/* wait */
delay(100);
}
void loadEEPROM()
{
word i ;
byte j ;
word xad ;
for ( i = 0 ; i < 256 ; i++ ) {
xad = (i << 5) ;
get_page_eeprom( xad ) ;
}
}
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);
}
void fillEEPROM()
{
word i ;
for ( i = 0 ; i < 8000 ; i++ ) {
put_eeprom( i , 0xff ) ;
rs_putchar('.');
if ( (i % 32) == 31 ) { 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 ;
}
}
}
使う機能は、EEPROMの8kバイトをすべてリードするか
8kバイトに16進数で'FF'をライトするかに限定。
Arduinoスケッチは、データの入出力だけを担当し
変換やグラフ描画は、OSを持ったPCでと考えました。
データリードでは、32バイトのバッファを用意して
一気に32バイトを読み込んでから表示。
このページリードで、読込時間を短縮しています。
ページリードを担当する関数は、次のように定義。
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(); }
}
/* wait */
delay(100);
}
32バイトを1ページとするので、8kバイトは
8192/32=256となり、256回ページリードすれば
全部のバイトをリードできます。
全部のバイトをリードし、表示する関数は以下。
void loadEEPROM()
{
word i ;
byte j ;
word xad ;
for ( i = 0 ; i < 256 ; i++ ) {
xad = (i << 5) ;
get_page_eeprom( xad ) ;
}
}
TeraTermを利用して、8kバイト分のデータを
リードすると、次のようになります。
データをすべて吸い上げたなら、次回利用のため
16進数で'FF'を書き込むコマンドで初期化できる
ようにしています。
'FF'で初期化する関数は、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);
}
void fillEEPROM()
{
word i ;
for ( i = 0 ; i < 8000 ; i++ ) {
put_eeprom( i , 0xff ) ;
rs_putchar('.');
if ( (i % 32) == 31 ) { crlf(); }
}
}
8kバイトのEEPROMでは、2分ごとの計測で
35時間まで温度を取得できます。
5日ほどの温度変化を見たいので、EEPROMの
容量を64kバイトに増やしました。
使ったEEPROMは、以下。
このEEPROMを扱うスケッチは、次のように定義しました。
/*
romtsty.ino
PORTB
PB5 (output) LED
PB4 (output) --
PB3 (output) --
PB2 (output) --
PB1 (output) --
PB0 (output) --
PORTC
PC5 (output) SCL
PC4 (output) SDA
PC3 (output) --
PC2 (output) --
PC1 (output) --
PC0 (output) --
*/
#include <Wire.h>
#define OFF 0
#define ON OFF+1
#define ROM_ADRS 0x50
#define LED_BIT 5
boolean uflag ;
/* variables */
char sbuf[4] ;
byte sindex ;
byte cmd ;
byte ydat[32];
void update_trigger();
void show_help();
void rs_putchar(char x);
void rs_puts(char *ptr);
void crlf();
void get_page_eeprom(word xadr);
void loadEEPROM();
void put_eeprom(word xadr,byte xdat);
void fillEEPROM();
char getHex(byte x);
void setup()
{
Serial.begin(115200);
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(); }
/* load data from EEPROM */
if ( cmd == 'L' ) { loadEEPROM(); }
/* fill data EEPROM */
if ( cmd == 'F' ) { fillEEPROM(); }
/* new line */
crlf() ;
}
}
void show_help()
{
rs_puts("? help") ; crlf();
rs_puts("F fill FF") ; crlf();
rs_puts("L load 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 get_page_eeprom(word xadr)
{
byte adh ;
byte adl ;
/* separate address */
adl = xadr & 0xff ;
adh = (xadr >> 8) & 0xff ;
/* 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(); }
}
/* wait */
delay(100);
}
void loadEEPROM()
{
word i ;
byte j ;
word xad ;
for ( i = 0 ; i < 2048 ; i++ ) {
xad = (i << 5) ;
get_page_eeprom( xad ) ;
}
}
void put_eeprom(word xadr,byte xdat)
{
byte adh ;
byte adl ;
byte xx ;
xx = xdat ;
/* separate address */
adl = xadr & 0xff ;
adh = (xadr >> 8) & 0xff ;
/* 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 fillEEPROM()
{
long i ;
byte tmp ;
tmp = 0xff ;
for ( i = 0 ; i < 0xffff ; i++ ) {
put_eeprom( i , tmp ) ;
rs_putchar('.');
if ( (i % 32) == 31 ) { 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 ;
}
}
}
ページリードは、そのままにしたいので
ページリードを扱う関数だけを最大容量
を扱えるように変更しています。
ページリードのため、変更した関数の内容は以下。
void loadEEPROM()
{
word i ;
byte j ;
word xad ;
for ( i = 0 ; i < 2048 ; i++ ) {
xad = (i << 5) ;
get_page_eeprom( xad ) ;
}
}
'FF'で初期化する関数も、変更しています。
void fillEEPROM()
{
long i ;
byte tmp ;
tmp = 0xff ;
for ( i = 0 ; i < 0xffff ; i++ ) {
put_eeprom( i , tmp ) ;
rs_putchar('.');
if ( (i % 32) == 31 ) { crlf(); }
}
}
2つのスケッチは、PC内に保存しているので
場面に応じて、Arduinoにダウンロードして
使えます。
目次
前
次