ホーム > カテゴリ > ロボット・電子工作・マイコン >

リアルタイムクロック(DS1307)の使い方 [Arduino]

このDS1307は前回の記事でSOPからDIPに変換しています。はんだ付けがタイヘンな方はDIP版(I-06949)が販売されていますので、そちらをご購入ください。また、SOP版とDIP版に機能の違いはありません。

使用部品・材料

総額で約550円です。(Arduino本体の値段を除く)

部品/材料値段備考
ブレッドボード¥270秋月電子の通販コード(P-00315)
I2C接続RTC(リアルタイムクロック)DS1307ZN+T&RTR¥250秋月電子の通販コード(I-06950)
クリスタル(水晶発振子) 32.768kHz¥30秋月電子の通販コード(P-04005)
カーボン抵抗器数円3.3kΩ(2個)を使用。

配線図

公式データシートより引用(DS1307.pdf)

クリスタル(水晶発振子)はブレッドボードにそのまま差してください。

コネクタ付コード(みの虫xジャンパーワイヤ)[C-08916]などでクリスタルの端子を挟んでも、ノイズ(?)などでクリスタルが正常に動作しませんのでご注意ください。

クリスタルはDS1307のX1及びX2の端子(足)に直に「はんだ付け」をするのも有りだと思います。

スケッチ(プログラム)

現在時刻をシリアルモニターへ表示します。

#include <Wire.h>

// RTCのレジスタテーブル(8byte)
int RegTbl[8];

// デバイスアドレス(スレーブ)
byte DEVICE_ADDRESS = 0x68;  // 2進数 1101000

// 2進化10進数(BCD)を10進数に変換
byte BCDtoDec(byte value) {
  return ((value >> 4) * 10) + (value & 0x0F) ;
}

void setup() {
  Serial.begin(9600);
  
  // マスタとしてI2Cバスに接続する
  Wire.begin();

  // I2Cスレーブに対して送信処理を開始する
  Wire.beginTransmission(DEVICE_ADDRESS);

    // レジスタのアドレスを指定する(0-63の内、先頭から)
    Wire.write(0x00);
  
    // ---------------------------------
    //  タイマーキーパーレジスタ
    // ---------------------------------
    // 2進化10進数(BCD)で指定します。(03以外)
  
    // [00]Seconds(45秒)
    Wire.write(0x45);
    // [01]Minutes(59分)
    Wire.write(0x59);
    // [02]Hours(23時)
    Wire.write(0x23);
    // [03]Day(月)
    // 1:日 2:月 3:火 4:水 5:木 6:金 7:土
    Wire.write(0x01);
    // [04]Date(31日)
    Wire.write(0x31);
    // [05]Month(12月)
    Wire.write(0x12);
    // [06]Years(2017年)
    Wire.write(0x17);

  // I2Cスレーブへの送信完了
  Wire.endTransmission();

  Serial.println("RTCの初期化完了。");
}

void loop() {

  // レジスタのアドレスを先頭にする
  Wire.beginTransmission(DEVICE_ADDRESS);
    Wire.write(0x00);
  Wire.endTransmission();

  // I2Cスレーブに8byteのレジスタデータを要求する
  Wire.requestFrom(DEVICE_ADDRESS, 8);

  // 8byteのデータを取得する
  int i;
  for (i = 0; i < 8; i++) {
    while (Wire.available() == 0 ) {}
    RegTbl[i] = Wire.read();
  }

  // 現在日時
  Serial.print(String(BCDtoDec(RegTbl[6]) + 2000)  + "年");
  Serial.print(String(BCDtoDec(RegTbl[5] & 0x1F))  + "月");
  Serial.print(String(BCDtoDec(RegTbl[4] & 0x3F))  + "日");

  switch (RegTbl[3] & 0x07) {
    case 1 :  Serial.print("(日)"); break;
    case 2 :  Serial.print("(月)"); break;
    case 3 :  Serial.print("(火)"); break;
    case 4 :  Serial.print("(水)"); break;
    case 5 :  Serial.print("(木)"); break;
    case 6 :  Serial.print("(金)"); break;
    case 7 :  Serial.print("(土)"); break;
  }

  Serial.print(" ");
  Serial.print(String(BCDtoDec(RegTbl[2] & 0x3F)) + "時");
  Serial.print(String(BCDtoDec(RegTbl[1] & 0x7F)) + "分");
  Serial.print(String(BCDtoDec(RegTbl[0] & 0x7F)) + "秒");
  Serial.println("");

  delay(1000);
}

setup()でRTCに現在時刻を「2017年12月31日(日) 23時59分45秒」に設定します。loop()では1秒毎にRTCから現在時刻を取得してシリアルモニターに表示します。

[実行結果]

以上です。





掲示板

ArduinoやRaspberry Piなどの電子工作の掲示板を作成しました。質問やわからない事は電子工作 (Arduino・ラズパイ等)でユーザー同士で情報を共有して下さい。

関連記事



公開日:2017年06月19日
記事NO:02426