« 今日10月31日から三日連続で星食が見られます | トップページ | PCオーディオでリサジュー図形を見る »

2014年10月31日 (金)

PICでI2C - リアルタイムクロック(RTC) DS1307+の使い方

リアルタイムクロック(RTC) DS1307+について簡単に使い方をまとめてみました。

記事を書いておいてなんですが、RTCについてはDS3234Sがお勧めです。

  「PICでSPI - 超高精度SPIバスRTC(リアルタイムクロック)DS3234Sの使い方」 (ソース付き)
  「PICでSPI - 超高精度SPIバスRTC(リアルタイムクロック)DS3234Sの実装

名前とおりとても精度(確度)がいいです。1周間で1秒も狂わないような。歩度の微調整が可能なのですが、それをしなくてもこの精度でした。

DS3234Sの問題は上のタイトルにあるようにインターフェースがSPIであることでしょうか。私はRTCだけSPIでその他のデバイスは(今のところ)ぜんぶI2Cです。まあ一度作ってしまえばSPIもI2Cもそのままソースを使えるので問題ないと言えば問題ないんですが。

SSPが一つしかないのでI2CとSPIが同時に使えないと悩んでいる方はこちらの記事をどうぞ。PIC16F1705でI2CのLCDとSPIのDS3234Sを使った例があります。

  ほよほよのブログ - 超高精度リアルタイムクロックDS3234Sを動かす

=====================

例によって秋月電子通商で買ってきました(I2C接続RTC(リアルタイムクロック)DS1307+
これは8ピンDIPなので扱いやすいです。

外付けの水晶振動子が必要ですので忘れずに買っておきます(例えば同じ秋月ですと「クリスタル(水晶発振子) 32.768kHz」があります)つまり精度は水晶振動子の精度に依存します。

--------

まず電源電圧は5Vです。データシートには4.5V~5.5Vとあります。3.3Vでは動かなかったと思います。
RTCですからバックアップ電源が必要でしょう。バックアップ電源は2V~3.5Vとなっています。主電源(Vcc)の電圧がバックアップ電源の1.25倍より低くなるとバックアップモードに入ります。つまり主電源とバックアップ電源を同じ電圧なんかにしてしまうと動きませんので注意が必要です(データシート上はこの倍率は1.216倍~1.284倍とばらつきがありますのでギリギリの設計はしない方がいいでしょう)

私は3.3Vから逆流防止用のダイオードを介して充電している1Fの電気二重層コンデンサーをバックアップ電源としていますがリチウム電池を使うというのが常識的だと思います。

電源電圧が5Vとなると3.3Vで使っているPICの回路で使えるかというのが心配になるのですがこれはだいじょうぶです。
VIH 2.2Vmin、VIL 0.8Vmaxなので3.3VでプルアップしてあるSCL/SDAバスに接続して使うことができます(出力ピンはとうぜんオープンコレクタです)

------

使い方は簡単です。レジスタのアドレスを指定して読み書きするだけです。
レジスタはアドレス0から順番に
  Seconds
  Minutes
  Hours
  Day
  Date
  Month
  Year
  Control
とならんでおりそのあとに自由に使えるRAMが56byteあります。

日付時刻のデータは原則BCDです。つまり上位4ビットが十の位、下位4ビットが一の位です。

Hoursのbit6は12/24の切り替えのためのビットで1だったら12時間表示です。12時間表示の場合はbit5がAM/PMを表し1だったらPMです。
Dayは1~7で曜日です。1が何曜日だったか調べていません。すみません。
Yearは下位二桁のみです。

Controlは秒信号等の出力の制御用です。毎秒1回パルスを出力するのであれば0x10と設定しておきます。

------

使い方は簡単なんですが、時計の場合は日時の初期設定をやったり進み遅れが出たときの調整したりといった機能が必要なのでけっこう面倒です。

時刻合わせについては別に記事を書きました。
  「
RTC(リアルタイムクロック)の時刻を合わせる方法 - DS3234Sを例に
DS3234Sについてのものですが手法としては参考になると思います。

基本的なところだけソースを示します。

いつもどおり「きむ茶工房ガレージハウス - I2C通信の実験」にあるI2Cライブラリを使うことを前提に書いています。
  => “自前”のものも用意しました。
    「I2Cのソース - PIC12F1822/16F1705/16F1938/18F26K22 - LCD(ACM1602)を例にして


日時データの取得

        ans = I2C_Start(0x68,RW_0);
        if (ans == 0) {
            I2C_Send(0) ;
            ans = I2C_rStart(0x68,RW_1);
            if (ans == 0) {
                for( j=0; j < 7; j++ ) {
                        ip_DS1307[j] = I2C_Receive(ACK);
                }
                ip_DS1307[j] = I2C_Receive(NOACK);
            }
        }
        I2C_Stop() ;

取得したデータをそのまま16進表示すればいいです。

                LCD_SetCursor(0,0);
                for( j=6; j > -1 ; j-- ) {
                    if( j == 3 ) {
                        LCD_Putc(' ');  // 日付と時刻の間に空白を入れる
                        continue;
                    }
                    putLCDhex(ip_DS1307[j]);  // 十六進表示すればOK

                }
                LCD_Putc(' ');

日時の初期設定や調整のときは該当するデータのアドレスに書き込みます。

                    ans = I2C_Start(0x68,RW_0);
                    if (ans == 0) {
                        I2C_Send(iLoc);
                        switch(iLoc) {
                            case 0:  // 秒をリセットする
                                I2C_Send(0x00);
                                break;
                            case 1:  // 分の設定
                                if(ip_DS1307[iLoc] < 0x59) {
                                    I2C_Send(ip_DS1307[iLoc]+1);
                                } else {
                                    I2C_Send(0);
                                }
                                break;
                            case 2:  // 時の設定
                                if(ip_DS1307[iLoc] < 0x23) {
                                    I2C_Send(ip_DS1307[iLoc]+1);
                                } else {
                                    I2C_Send(0);
                                }
                                break;
                            case 3:  // 曜日の設定
                                if(ip_DS1307[iLoc] < 0x07) {
                                    I2C_Send(ip_DS1307[iLoc]+1);
                                } else {
                                    I2C_Send(0);
                                }
                                break;
                            case 4:  // 日の設定
                                if(ip_DS1307[iLoc] < 0x31) {
                                    I2C_Send(ip_DS1307[iLoc]+1);
                                } else {
                                    I2C_Send(1);
                                }
                                break;
                            case 5:  // 月の設定
                                if(ip_DS1307[iLoc] < 0x12) {
                                    I2C_Send(ip_DS1307[iLoc]+1);
                                } else {
                                    I2C_Send(1);
                                }
                                break;
                            case 6:  // 年の設定
                                if(ip_DS1307[iLoc] < 0x15) {
                                    I2C_Send(ip_DS1307[iLoc]+1);
                                } else {
                                    I2C_Send(0x14);
                                }
                                break;
                            default:
                                break;
                        }
                    }
                    I2C_Stop() ;

------

関連
  「I2Cデバイス・アドレス一覧
  「同じアドレスのI2Cデバイスを使う
  「PICで平方根 - 白金薄膜抵抗で温度を測る
  「PICでI2C - 1 (温度計を作る)
  「PICでI2C - 液晶(LCD)ディスプレイ(ACM1602N1-FLW-FBW)に表示する
  「PICでI2C - LCD(液晶)ディスプレイによる違い
  「I2C大気圧センサーLPS331の驚くべき分解能
  「I2C大気圧温度センサーLPS331 - 海面更生気圧を気象庁とくらべてみた
  「炭素皮膜抵抗の温度係数を測定する話
  「サーミスタによる温度測定の精度
  「サーミスタ温度計の精度を調べる - 1
  「ミニ恒温槽の作成に向けて - 1

参考

きむ茶工房ガレージハウス - PICの動かせ方入門はこちら - 16F1938覚書
きむ茶工房ガレージハウス - I2C通信の実験
きむ茶工房ガレージハウス - 気圧センサーで大気圧と標高を測定して見ます(MPL115A1)(MPL115A2)」

ほよほよのブログ - 超高精度リアルタイムクロックDS3234Sを動かす
(I2CとSPIの共用)

« 今日10月31日から三日連続で星食が見られます | トップページ | PCオーディオでリサジュー図形を見る »

趣味の電子工作」カテゴリの記事

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: PICでI2C - リアルタイムクロック(RTC) DS1307+の使い方:

« 今日10月31日から三日連続で星食が見られます | トップページ | PCオーディオでリサジュー図形を見る »

フォト

サイト内検索

  • 記事を探されるんでしたらこれがいちばん早くて確実です。私も使ってます (^^;; 検索窓が表示されるのにちょっと時間がかかるのはどうにかしてほしいです。

新着記事

リンク元別アクセス数

  • (アクセス元≒リンク元、原則PCのみ・ドメイン別、サイト内等除く)

人気記事ランキング

  • (原則PCのみ、直近2週間)
無料ブログはココログ