Tiny Real-Time Clock/calendar with alarm function, battery switch-over, time stamp input, and I2C-bus

Dependencies:   mbed

Committer:
wataaki
Date:
Wed Feb 04 06:13:31 2015 +0000
Revision:
0:4f2e0e1e9a05
Initial version

Who changed what in which revision?

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