目次
前
次
ArduinoMega2560RTC処理
ArduinoMega2560はピン数が多いので、Real Time Clockを
2種接続してみることにします。
ビニルハウスの温湿度計測で利用したRTCは、以下。
バックアップ電池を使って、マイコンが電源消失でも
動き続けるRTCは、以下。
電池でバックアップするので、CR2032を使うとして
回路図は、次のように配線。
どちらもIICバスを利用するので、ArduinoMega2560には
使うたびに、交換するとします。
IICバスのピンは、次のように20、21を使います。
D20 SDA <IIC bus>
D21 SCL <IIC bus>
IICバスを利用するため、ライブラリをインクルードするのと
setupの中で開始を宣言しておきます。
#include <Wire.h>
Wire.begin();
電池でのバックアップをしない方のRTCでは
初期化をしておきます。
#define RTC_ADRS 0x32
byte xdatx[6];
void initRtc()
{
/* start condition */
Wire.beginTransmission(RTC_ADRS);
Wire.write(0xE0);
Wire.write(0x20); /* 24hour Mode */
Wire.write(0x00); /* PON Clear */
/* stop condition */
Wire.endTransmission();
/* wait */
delay(1);
/* initialize */
*(xdatx+0) = 0x19 ;
*(xdatx+1) = 0x06 ;
*(xdatx+2) = 0x01 ;
*(xdatx+3) = 0x00 ;
*(xdatx+4) = 0x00 ;
*(xdatx+5) = 0x00 ;
/* store */
putDateTime();
}
初期化では、2019年06月01日00時00分00秒に指定。
また、RTCの方にパラメータを格納する関数を用意
しておきます。
void putDateTime()
{
Wire.beginTransmission(RTC_ADRS);
Wire.write(0x00); /* start register addess */
Wire.write( *(xdatx+5) );
Wire.write( *(xdatx+4) );
Wire.write( *(xdatx+3) );
Wire.write(0x00); /* Sunday */
Wire.write( *(xdatx+2) );
Wire.write( *(xdatx+1) );
Wire.write( *(xdatx+0) );
Wire.endTransmission();
/* wait */
delay(1);
}
RTCは、BCDフォーマットで扱うので、EEPROMへの格納や
LCDでの表示のための関数も定義しておきます。
void setDateTime()
{
byte ptr ;
byte ii ;
byte xdt[6] ;
byte xtmp ;
word yadr ;
/* set base pointer */
ptr = 1 ;
/* generate BCD code */
for ( ii = 0 ; ii < 6 ; ii++ ) {
/* x10 */
xtmp = getHex( *(sbuf+ptr) ) ;
xtmp *= 10 ;
ptr++ ;
/* x1 */
xtmp += getHex( *(sbuf+ptr) );
*(xdt+ii) = convHEX2BCD( xtmp );
ptr++ ;
/* copy */
*(xdatx+ii) = *(xdt+ii) ;
}
/* store RTC */
putDateTime() ;
/* store EEPROM */
yadr = SYS_ADRS ;
for ( ii = 0 ; ii < 6 ; ii++ ) {
put_eeprom(yadr,*(xdatx+ii));
yadr++ ;
}
/* set ROM entry addess */
rom_address = 0 ;
}
RTCにパラメータを出し入れするために
インタプリタを用意しておけばよく、次
のように処理します。
/* adjust real time clock */
if ( cmd == 'A' ) { setDateTime(); }
/* show Months Days hour minute */
if ( cmd == 'a' ) { showRtc(); }
関数showRtcの内容は、以下。
void showRtc()
{
byte ii ;
byte tmp ;
byte tmpH ;
byte tmpL ;
/* show */
for ( ii = 0 ; ii < 6 ; ii++ ) {
tmp = *(xdatx+ii) ;
tmpL = (tmp & 15 ) + '0' ;
tmp >>= 4 ;
tmpH = tmp + '0' ;
rs_putchar( tmpH );
rs_putchar( tmpL );
if ( ii < 2 ) { rs_putchar('-'); }
if ( ii == 2 ) { rs_putchar(' '); }
if ( ii == 3 ) { rs_putchar(':'); }
if ( ii == 4 ) { rs_putchar(':'); }
}
crlf();
}
ここまでの関数は、データシートから必要な内容を
読み込んで定義しています。
レジスタに関係するデータシートの内容は、以下。
レジスタから複数パラメータをリードするには
次のような便利な読み出し方法があります。
レジスタへの書き込みは、次のシーケンスを利用。
電池でバックアップできる方のRTCのレジスタ構成は以下。
レジスタは、数値をBCDで表現しているのがわかります。
レジスタとしては、0から6までの7レジスタですが
時間は、12時間制と24時間制の2種あるので選択
して使わなければなりません。
レジスタ7には、SQW/OUTから出力する矩形波の周波数を
指定するのと、矩形波にするのか固定値とするかを指定
可能となっています。
パラメータ設定のシーケンスは、以下。
西暦年の下2桁、月日、曜日、時分秒が含まれて
いるとすれば、設定関数は、次のように定義。
#define RTC_ADRSX 0x68
byte get_BCD(byte x)
{
byte result ;
byte dh ;
byte dl ;
/* separate */
dl = x % 10 ;
dh = x / 10 ;
/* concatenate */
result = (dh << 4) | dl ;
return result ;
}
void putDateTime(byte *ptr)
{
/* store */
Wire.beginTransmission(RTC_ADRSX);
Wire.write(0x00); /* start register addess */
Wire.write( get_BCD( *(ptr+6) ) ); /* second */
Wire.write( get_BCD( *(ptr+5) ) ); /* minute */
Wire.write( get_BCD( *(ptr+4) ) ); /* hour */
Wire.write( *(ptr+3) ) ) ; /* weekday */
Wire.write( get_BCD( *(ptr+2) ) ); /* date */
Wire.write( get_BCD( *(ptr+1) ) ); /* month */
Wire.write( get_BCD( *(ptr+0) ) ); /* year */
Wire.endTransmission();
}
データリードは、次のシーケンスとなっています。
レジスタアドレスを指定することなく、年月日曜日時分秒を読み出せる
モードを持っているため、専用関数を定義します。
byte get_BHEX(byte x)
{
byte result ;
/* separate */
result = (x >> 4) ;
result *= 10 ;
result += (x & 15) ;
return result ;
}
void getDateTime(byte *ptr)
{
byte xdd[7] ;
byte ii ;
/* read */
Wire.requestFrom(RTC_ADRSX,7);
*(xdd+6) = Wire.read(); /* ss */
*(xdd+5) = Wire.read(); /* mm */
*(xdd+4) = Wire.read(); /* hh */
*(xdd+3) = Wire.read(); /* weekday */
*(xdd+2) = Wire.read(); /* DD */
*(xdd+1) = Wire.read(); /* MM */
*(xdd+0) = Wire.read(); /* YY */
/* store */
for ( ii = 0 ; ii < 7 ; ii++ ) {
*(ptr+ii) = get_BHEX( *(xdd+ii) );
if ( ii == 3 ) { *(ptr+ii) = *(xdd+ii) ; }
}
}
最後に、1Hzの矩形波を出力するか否かを指定
する処理を扱う専用関数を定義していきます。
データシートの関連情報は、以下。
矩形波を出力するか否かの指定は、SQWEビットに
論理値を設定すればよいので、そのビットを設定
するように、関数を定義。
void setSQR(boolean x)
{
byte xx ;
/* SQWE bit */
xx = 0 ;
if ( x ) { xx |= (1 << 4) ; }
/* store */
Wire.beginTransmission(RTC_ADRSX);
Wire.write(0x07); /* set control register */
Wire.write( xx ); /* second */
Wire.endTransmission();
}
1Hzの矩形波を出力する場合、セレクタには00を
指定するので、SQREビットのみを'1'か'0'へと
設定するだけで済みます。
目次
前
次