Created
April 30, 2016 22:20
-
-
Save weldtype/d7f54fcf196b914879d9b70304057849 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// RTC-8564をつないでみる。 | |
// 2016/04/29:edy | |
// 2016/04/30:detachInterrupt を使う。 | |
// 2016/05/01:変数名の変更、RTCとのやり取りはBCDで行うが、内部ではDECIMAL | |
// 参考にしたサイト | |
//http://baticadila.dip.jp/arduino_104.html | |
//http://iizukakuromaguro.sakura.ne.jp/365_rtc8564/365_rtc8564.html | |
//http://edu.clipper.co.jp/pg-2-47.html | |
//http://genine.web.fc2.com/contents/arduino_memo.html | |
#include <Wire.h> | |
#define I2C_ADDR (0xA2 >> 1) // 1ビット目未使用のため1ビット右シフトする。 | |
// DECIMAL not BCD | |
int gYear, gMonth, gDay, gSec, gMin, gHour, gWeek; | |
void clk_IRQ(void) | |
{ | |
interrupts();// 割り込みを有効にする。 | |
Wire.beginTransmission(I2C_ADDR); | |
Wire.write(0x02); | |
Wire.endTransmission(); | |
delay(1); | |
Wire.requestFrom(I2C_ADDR, 7); | |
gSec = bcd2dec(Wire.read() & 0x7f) ; // 秒 | |
gMin = bcd2dec(Wire.read() & 0x7f) ; // 分 | |
gHour = bcd2dec(Wire.read() & 0x3f) ; // 時 | |
gDay = bcd2dec(Wire.read() & 0x3f) ; // 日 | |
gWeek = bcd2dec(Wire.read() & 0x07) ; // 曜日 | |
gMonth = bcd2dec(Wire.read() & 0x1f) ; // 月 | |
gYear = bcd2dec(Wire.read()); // 年 | |
Serial.print(gYear); | |
Serial.print("/"); | |
Serial.print(gMonth); | |
Serial.print("/"); | |
Serial.print(gDay); | |
Serial.print("("); | |
Serial.print(gWeek); | |
Serial.print(")"); | |
Serial.print(gHour); | |
Serial.print(":"); | |
Serial.print(gMin); | |
Serial.print(":"); | |
Serial.println(gSec); | |
} | |
void setup() { | |
Serial.begin(9600); | |
Serial.println("RTC Test Start"); | |
Wire.begin(); // I2C の初期化 | |
attachInterrupt(0, clk_IRQ, CHANGE); | |
/* | |
Wire.beginTransmission(I2C_ADDR); | |
Wire.write(byte(0x02)); // RTCモジュールへレジスタの先頭番号を指定 | |
Wire.endTransmission(); | |
Wire.requestFrom(I2C_ADDR, 1); // レジスタの先頭より1バイト転送依頼 | |
byte b = Wire.read(); // 1バイト受信 | |
if (b & 0x80) { // データの bit7 を判定し true なら初期化 | |
} | |
Serial.println("begin"); | |
*/ | |
} | |
void loop() { | |
String sInput; | |
while (Serial.available()) { | |
delay(3); //delay to allow buffer to fill | |
if (Serial.available() > 0) { | |
char c = Serial.read(); //gets one byte from serial buffer | |
sInput += c; //makes the string readString | |
} | |
} | |
if (sInput.length() >= 12) { | |
Serial.print("length:"); Serial.println(sInput.length()); | |
Serial.println(sInput); //see what was received | |
int year = (sInput.substring(0, 2)).toInt(); | |
int month = (sInput.substring(2, 4)).toInt(); | |
int day = (sInput.substring(4, 6)).toInt(); | |
int hour = (sInput.substring(6, 8)).toInt(); | |
int min = (sInput.substring(8, 10)).toInt(); | |
int sec = (sInput.substring(10, 12)).toInt(); | |
detachInterrupt(0); | |
setRTC(year, month, day, hour, min, sec); | |
attachInterrupt(0, clk_IRQ, CHANGE); | |
} | |
// 秒が30以上なら切り上げ、未満なら秒切捨て。 | |
if (sInput.substring(0, 1) == "*") | |
{ | |
Serial.println("sec clear"); | |
if (gSec >= 30) { | |
// 処理が複雑になるので59分では切り上げはしない | |
if (gMin < 59) { | |
gMin++; | |
} | |
} | |
gSec = 0; | |
detachInterrupt(0); | |
setRTC(gYear, gMonth, gDay, gHour, gMin, gSec); | |
attachInterrupt(0, clk_IRQ, CHANGE); | |
} | |
sInput = ""; | |
} | |
void setRTC(int year, int month, int day, int hour, int min, int sec) | |
{ | |
Wire.beginTransmission(I2C_ADDR); | |
Wire.write((0x00)); // データを転送する先頭のレジスタ番号を指定 | |
Wire.write((0x20)); // 00 Control 1 STOP(bit5)-1 をセットし動作を停止させる。 | |
Wire.write((0x00)); // 01 Control 2 | |
Wire.write(byte(dec2bcd(sec))); // 02 Seconds 初期値を転送(秒)0 ~ 59 | |
Wire.write(byte(dec2bcd(min))); // 03 Minutes 〃 (分)0 ~ 59 | |
Wire.write(byte(dec2bcd(hour))); // 04 Hours 〃 (時)0 ~ 23 | |
Wire.write(byte(dec2bcd(day))); // 05 Days 〃 (日)1 ~ 31 | |
Wire.write(byte(dec2bcd(subZeller(year + 2000, month, day)))); // 06 Weekdays 〃 (曜日)0 ~ 6 | |
Wire.write(byte(0x80 | dec2bcd(month))); // 07 Months 〃 (月)1 ~ 12 | |
Wire.write(byte(dec2bcd(year))); // 08 Years 〃 (年)0 ~ 99 | |
Wire.write(byte(0x00)); // 09 Minutes Alarm アラームの初期値を転送(分)0 ~ 59 | |
Wire.write(byte(0x00)); // 0A Hours Alarm 〃 (時)0 ~ 23 | |
Wire.write(byte(0x00)); // 0B Days Alarm 〃 (日)1 ~ 31 | |
Wire.write(byte(0x00)); // 0C Weekdays Alarm 〃 (曜日)0 ~ 6 | |
Wire.write(byte(0xff)); // 0D CLKOUT タイマー用レジスタ | |
Wire.write(byte(0x00)); // 0E Timer control 〃 | |
Wire.write(byte(0x00)); // 0F Timer 〃 | |
Wire.write(byte(0x00)); // 00 Control 1 STOP(bit5)-0 をリセットし動作を開始する。 | |
// アドレス 0F の次は先頭アドレスの 00 に戻る。 | |
Wire.endTransmission(); | |
} | |
int subZeller( int y, int m, int d ) | |
{ | |
if ( m < 3 ) { | |
y--; m += 12; | |
} | |
return ( y + y / 4 - y / 100 + y / 400 + ( 13 * m + 8 ) / 5 + d ) % 7; | |
} | |
// DECIMAL -> BCD | |
byte dec2bcd( byte data ) | |
{ | |
return ((( data / 10) << 4) + (data % 10)); | |
} | |
// BCD -> DECIMAL | |
byte bcd2dec( byte data ) | |
{ | |
return ((( data >> 4) * 10) + (data % 16)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment