Accurate RTC with integrated quartz crystal for industrial applications

Dependencies:   mbed

Committer:
wataaki
Date:
Wed Feb 04 06:12:10 2015 +0000
Revision:
0:6bee9019d980
Initial version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wataaki 0:6bee9019d980 1 #include "mbed.h"
wataaki 0:6bee9019d980 2 #include "PCF2129AT.h"
wataaki 0:6bee9019d980 3
wataaki 0:6bee9019d980 4 I2C i2c(p28,p27); // sda, scl
wataaki 0:6bee9019d980 5 Serial pc(USBTX, USBRX); // tx, rx
wataaki 0:6bee9019d980 6 char cmd[32];
wataaki 0:6bee9019d980 7 char i;
wataaki 0:6bee9019d980 8 dt_dat dt; // 日時構造体の変数設定
wataaki 0:6bee9019d980 9
wataaki 0:6bee9019d980 10 void set_ch(char sel)
wataaki 0:6bee9019d980 11 { // PCA9541のサンプル
wataaki 0:6bee9019d980 12 // MST_0側の自分にスレーブ側の制御権を得る場合
wataaki 0:6bee9019d980 13 cmd[0] = 1; // PCA9541 コマンドコード Cont Reg
wataaki 0:6bee9019d980 14 i2c.write( 0xe2, cmd, 1); // Cont Regを指定
wataaki 0:6bee9019d980 15 i2c.read( 0xe2, cmd, 1); // Cont Regを読込み
wataaki 0:6bee9019d980 16 wait(0.1); // 0.1s待つ
wataaki 0:6bee9019d980 17 switch(cmd[0] & 0xf)
wataaki 0:6bee9019d980 18 {
wataaki 0:6bee9019d980 19 case 0: // bus off, has control
wataaki 0:6bee9019d980 20 case 1: // bus off, no control
wataaki 0:6bee9019d980 21 case 5: // bus on, no control
wataaki 0:6bee9019d980 22 cmd[0] = 1; // PCA9541 コマンドコード Cont Reg
wataaki 0:6bee9019d980 23 cmd[1] = 4; // bus on, has control
wataaki 0:6bee9019d980 24 i2c.write( 0xe2, cmd, 2); // Cont Regにcmd[1]を書込み
wataaki 0:6bee9019d980 25 i2c.read( 0xe2, cmd, 1); // Cont Regを読込み
wataaki 0:6bee9019d980 26 break;
wataaki 0:6bee9019d980 27 case 2: // bus off, no control
wataaki 0:6bee9019d980 28 case 3: // bus off, has control
wataaki 0:6bee9019d980 29 case 6: // bus on, no control
wataaki 0:6bee9019d980 30 cmd[0] = 1; // PCA9541 コマンドコード Cont Reg
wataaki 0:6bee9019d980 31 cmd[1] = 5; // bus on, has control
wataaki 0:6bee9019d980 32 i2c.write( 0xe2, cmd, 2); // Cont Regにcmd[1]を書込み
wataaki 0:6bee9019d980 33 i2c.read( 0xe2, cmd, 1); // Cont Regを読込み
wataaki 0:6bee9019d980 34 break;
wataaki 0:6bee9019d980 35 case 9: // bus on, no control
wataaki 0:6bee9019d980 36 case 0xc: // bus on, no control
wataaki 0:6bee9019d980 37 case 0xd: // bus off, no control
wataaki 0:6bee9019d980 38 cmd[0] = 1; // PCA9541 コマンドコード Cont Reg
wataaki 0:6bee9019d980 39 cmd[1] = 0; // bus on, has control
wataaki 0:6bee9019d980 40 i2c.write( 0xe2, cmd, 2); // Cont Regにcmd[1]を書込み
wataaki 0:6bee9019d980 41 i2c.read( 0xe2, cmd, 1); // Cont Regを読込み
wataaki 0:6bee9019d980 42 break;
wataaki 0:6bee9019d980 43 case 0xa: // bus on, no control
wataaki 0:6bee9019d980 44 case 0xe: // bus off, no control
wataaki 0:6bee9019d980 45 case 0xf: // bus on, has control
wataaki 0:6bee9019d980 46 cmd[0] = 1; // PCA9541 コマンドコード Cont Reg
wataaki 0:6bee9019d980 47 cmd[1] = 1; // bus on, has control
wataaki 0:6bee9019d980 48 i2c.write( 0xe2, cmd, 2); // Cont Regにcmd[1]を書込み
wataaki 0:6bee9019d980 49 i2c.read( 0xe2, cmd, 1); // Cont Regを読込み
wataaki 0:6bee9019d980 50 break;
wataaki 0:6bee9019d980 51 default:
wataaki 0:6bee9019d980 52 break;
wataaki 0:6bee9019d980 53 }
wataaki 0:6bee9019d980 54
wataaki 0:6bee9019d980 55 cmd[0] = sel; // PCA9546 Cont Reg sel channel enabled
wataaki 0:6bee9019d980 56 i2c.write( 0xe8, cmd, 1); // Send command string
wataaki 0:6bee9019d980 57 }
wataaki 0:6bee9019d980 58
wataaki 0:6bee9019d980 59 void get_time(dt_dat *dt) // 日時の取得
wataaki 0:6bee9019d980 60 {
wataaki 0:6bee9019d980 61 cmd[0] = Seconds; // 取得はレジスタSecondsから
wataaki 0:6bee9019d980 62 i2c.write(PCF2129AT_ADDR, cmd, 1); // レジスタの設定
wataaki 0:6bee9019d980 63 i2c.read(PCF2129AT_ADDR, cmd, 7); // SecondsからYearsまで取得
wataaki 0:6bee9019d980 64 cmd[0] &= 0x7f; // 有効なのは下位7ビット
wataaki 0:6bee9019d980 65 dt->s = (cmd[0] >> 4) * 10 + (cmd[0] & 0xf); // BCDの数値化
wataaki 0:6bee9019d980 66 cmd[1] &= 0x7f; // 有効なのは下位7ビット
wataaki 0:6bee9019d980 67 dt->m = (cmd[1] >> 4) * 10 + (cmd[1] & 0xf); // BCDの数値化
wataaki 0:6bee9019d980 68 cmd[2] &= 0x3f; // 有効なのは下位6ビット
wataaki 0:6bee9019d980 69 dt->h = (cmd[2] >> 4) * 10 + (cmd[2] & 0xf); // BCDの数値化
wataaki 0:6bee9019d980 70 cmd[3] &= 0x3f; // 有効なのは下位6ビット
wataaki 0:6bee9019d980 71 dt->d = (cmd[3] >> 4) * 10 + (cmd[3] & 0xf); // BCDの数値化
wataaki 0:6bee9019d980 72 dt->wd = (cmd[4] & 0x3); // BCDの数値化
wataaki 0:6bee9019d980 73 cmd[5] &= 0x1f; // 有効なのは下位5ビット
wataaki 0:6bee9019d980 74 dt->mm = (cmd[5] >> 4) * 10 + (cmd[5] & 0xf); // BCDの数値化
wataaki 0:6bee9019d980 75 dt->y = (cmd[6] >> 4) * 10 + (cmd[6] & 0xf); // BCDの数値化
wataaki 0:6bee9019d980 76 }
wataaki 0:6bee9019d980 77
wataaki 0:6bee9019d980 78 void set_time(dt_dat *dt) // 日時の設定
wataaki 0:6bee9019d980 79 {
wataaki 0:6bee9019d980 80 cmd[0] = Seconds; // 設定はレジスタSecondsから
wataaki 0:6bee9019d980 81 cmd[1] = ((dt->s / 10) << 4) + (dt->s % 10) + 0x80; // 秒のBCD化
wataaki 0:6bee9019d980 82 cmd[2] = ((dt->m / 10) << 4) + (dt->m % 10); // 分のBCD化
wataaki 0:6bee9019d980 83 cmd[3] = ((dt->h / 10) << 4) + (dt->h % 10); // 時のBCD化
wataaki 0:6bee9019d980 84 cmd[4] = ((dt->d / 10) << 4) + (dt->d % 10); // 日のBCD化
wataaki 0:6bee9019d980 85 cmd[6] = ((dt->mm / 10) << 4) + (dt->mm % 10); // 月のBCD化
wataaki 0:6bee9019d980 86 dt->y = dt->y - 2000;
wataaki 0:6bee9019d980 87 cmd[7] = ((dt->y / 10) << 4) + (dt->y % 10); // 年のBCD化
wataaki 0:6bee9019d980 88 i2c.write(PCF2129AT_ADDR, cmd, 8); // 日時の設定
wataaki 0:6bee9019d980 89 }
wataaki 0:6bee9019d980 90
wataaki 0:6bee9019d980 91
wataaki 0:6bee9019d980 92 int main ()
wataaki 0:6bee9019d980 93 {
wataaki 0:6bee9019d980 94 i2c.frequency(100000);
wataaki 0:6bee9019d980 95 pc.printf("PC2129AT Sample Program\r\n");
wataaki 0:6bee9019d980 96
wataaki 0:6bee9019d980 97 set_ch(2); // PCF2129ATはch1に接続
wataaki 0:6bee9019d980 98
wataaki 0:6bee9019d980 99 // PCF2129AT
wataaki 0:6bee9019d980 100 cmd[0] = CLKOUT_ctl; // CLKOUTレジスタ設定
wataaki 0:6bee9019d980 101 cmd[1] = (3 << 6) + 4; // 温度測定は30s毎、出力周波数は2048Hz
wataaki 0:6bee9019d980 102 i2c.write(PCF2129AT_ADDR, cmd, 2); // CLKOUT設定
wataaki 0:6bee9019d980 103
wataaki 0:6bee9019d980 104 cmd[0] = Aging_offset; // Aging_offsetレジスタ設定
wataaki 0:6bee9019d980 105 cmd[1] = 0x9; // -1ppm
wataaki 0:6bee9019d980 106 i2c.write(PCF2129AT_ADDR, cmd, 2); // Aging_offset設定
wataaki 0:6bee9019d980 107
wataaki 0:6bee9019d980 108 dt.y = 2014; // 年の設定
wataaki 0:6bee9019d980 109 dt.mm = 10; // 月の設定
wataaki 0:6bee9019d980 110 dt.d = 5; // 日の設定
wataaki 0:6bee9019d980 111 dt.h = 8; // 時の設定
wataaki 0:6bee9019d980 112 dt.m = 31; // 分の設定
wataaki 0:6bee9019d980 113 dt.s = 0; // 秒の設定
wataaki 0:6bee9019d980 114 set_time(&dt); // 日時の設定
wataaki 0:6bee9019d980 115
wataaki 0:6bee9019d980 116 while(1)
wataaki 0:6bee9019d980 117 {
wataaki 0:6bee9019d980 118 get_time(&dt); // 日時の取得
wataaki 0:6bee9019d980 119 // 日時の表示
wataaki 0:6bee9019d980 120 pc.printf("%04d/%02d/%02d %02d:%02d:%02d\r\n", 2000 + dt.y, dt.mm, dt.d, dt.h, dt.m, dt.s);
wataaki 0:6bee9019d980 121 wait(1.0);
wataaki 0:6bee9019d980 122 }
wataaki 0:6bee9019d980 123 }