Accurate RTC with integrated quartz crystal for industrial applications

Dependencies:   mbed

Revision:
0:6bee9019d980
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PCF2129AT.cpp	Wed Feb 04 06:12:10 2015 +0000
@@ -0,0 +1,123 @@
+#include "mbed.h"
+#include "PCF2129AT.h"
+ 
+I2C i2c(p28,p27);        // sda, scl
+Serial pc(USBTX, USBRX); // tx, rx
+char cmd[32];
+char i;
+dt_dat dt;                          // 日時構造体の変数設定
+ 
+void set_ch(char sel)
+{    // PCA9541のサンプル
+        // MST_0側の自分にスレーブ側の制御権を得る場合
+    cmd[0] = 1;                     // PCA9541 コマンドコード Cont Reg
+    i2c.write( 0xe2, cmd, 1);       // Cont Regを指定
+    i2c.read( 0xe2, cmd, 1);        // Cont Regを読込み
+    wait(0.1);                      // 0.1s待つ
+    switch(cmd[0] & 0xf)
+    {
+    case 0:                         // bus off, has control
+    case 1:                         // bus off, no control
+    case 5:                         // bus on, no control
+        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
+        cmd[1] = 4;                 // bus on, has control
+        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
+        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
+        break;
+    case 2:                         // bus off, no control
+    case 3:                         // bus off, has control
+    case 6:                         // bus on, no control
+        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
+        cmd[1] = 5;                 // bus on, has control
+        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
+        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
+        break;
+    case 9:                         // bus on, no control
+    case 0xc:                       // bus on, no control
+    case 0xd:                       // bus off, no control
+        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
+        cmd[1] = 0;                 // bus on, has control
+        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
+        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
+        break;
+    case 0xa:                       // bus on, no control
+    case 0xe:                       // bus off, no control
+    case 0xf:                       // bus on, has control
+        cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
+        cmd[1] = 1;                 // bus on, has control
+        i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
+        i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
+        break;
+    default:
+        break;
+    }
+
+    cmd[0] = sel;                   // PCA9546 Cont Reg sel channel enabled
+    i2c.write( 0xe8, cmd, 1);       // Send command string
+}
+
+void  get_time(dt_dat *dt)      // 日時の取得
+{
+    cmd[0] = Seconds;                       // 取得はレジスタSecondsから
+    i2c.write(PCF2129AT_ADDR, cmd, 1);      // レジスタの設定
+    i2c.read(PCF2129AT_ADDR, cmd, 7);       // SecondsからYearsまで取得
+    cmd[0] &= 0x7f;                         // 有効なのは下位7ビット
+    dt->s = (cmd[0] >> 4) * 10 + (cmd[0] & 0xf);    // BCDの数値化
+    cmd[1] &= 0x7f;                         // 有効なのは下位7ビット
+    dt->m = (cmd[1] >> 4) * 10 + (cmd[1] & 0xf);    // BCDの数値化
+    cmd[2] &= 0x3f;                         // 有効なのは下位6ビット
+    dt->h = (cmd[2] >> 4) * 10 + (cmd[2] & 0xf);    // BCDの数値化
+    cmd[3] &= 0x3f;                         // 有効なのは下位6ビット
+    dt->d = (cmd[3] >> 4) * 10 + (cmd[3] & 0xf);    // BCDの数値化
+    dt->wd = (cmd[4] & 0x3);                        // BCDの数値化
+    cmd[5] &= 0x1f;                         // 有効なのは下位5ビット
+    dt->mm = (cmd[5] >> 4) * 10 + (cmd[5] & 0xf);   // BCDの数値化
+    dt->y = (cmd[6] >> 4) * 10 + (cmd[6] & 0xf);    // BCDの数値化
+}        
+
+void set_time(dt_dat *dt)       // 日時の設定
+{
+    cmd[0] = Seconds;                       // 設定はレジスタSecondsから
+    cmd[1] = ((dt->s / 10) << 4) + (dt->s % 10) + 0x80; // 秒のBCD化
+    cmd[2] = ((dt->m / 10) << 4) + (dt->m % 10);        // 分のBCD化
+    cmd[3] = ((dt->h / 10) << 4) + (dt->h % 10);        // 時のBCD化
+    cmd[4] = ((dt->d / 10) << 4) + (dt->d % 10);        // 日のBCD化
+    cmd[6] = ((dt->mm / 10) << 4) + (dt->mm % 10);      // 月のBCD化
+    dt->y = dt->y - 2000;       
+    cmd[7] = ((dt->y / 10) << 4) + (dt->y % 10);        // 年のBCD化
+    i2c.write(PCF2129AT_ADDR, cmd, 8);      // 日時の設定
+}
+
+
+int main ()
+{
+    i2c.frequency(100000);
+    pc.printf("PC2129AT Sample Program\r\n");
+     
+    set_ch(2);              // PCF2129ATはch1に接続
+
+  // PCF2129AT
+    cmd[0] = CLKOUT_ctl;                // CLKOUTレジスタ設定
+    cmd[1] = (3 << 6) + 4;              // 温度測定は30s毎、出力周波数は2048Hz
+    i2c.write(PCF2129AT_ADDR, cmd, 2);  // CLKOUT設定
+
+    cmd[0] = Aging_offset;              // Aging_offsetレジスタ設定
+    cmd[1] = 0x9;                       // -1ppm
+    i2c.write(PCF2129AT_ADDR, cmd, 2);  // Aging_offset設定
+
+    dt.y = 2014;                // 年の設定
+    dt.mm = 10;                 // 月の設定
+    dt.d = 5;                   // 日の設定
+    dt.h = 8;                   // 時の設定
+    dt.m = 31;                  // 分の設定
+    dt.s = 0;                   // 秒の設定
+    set_time(&dt);              // 日時の設定
+
+    while(1)
+    {
+        get_time(&dt);          // 日時の取得
+             // 日時の表示
+        pc.printf("%04d/%02d/%02d %02d:%02d:%02d\r\n", 2000 + dt.y, dt.mm, dt.d, dt.h, dt.m, dt.s);
+        wait(1.0);
+    }
+}
\ No newline at end of file