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

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PCF85263AT.cpp Source File

PCF85263AT.cpp

00001 #include "mbed.h"
00002 #include "PCF85263AT.h"
00003  
00004 I2C i2c(p28,p27);        // sda, scl
00005 Serial pc(USBTX, USBRX); // tx, rx
00006 char cmd[32];
00007 char i;
00008 dt_dat dt;                          // 日時構造体の変数設定
00009  
00010 void set_ch(char sel)
00011 {    // PCA9541のサンプル
00012         // MST_0側の自分にスレーブ側の制御権を得る場合
00013     cmd[0] = 1;                     // PCA9541 コマンドコード Cont Reg
00014     i2c.write( 0xe2, cmd, 1);       // Cont Regを指定
00015     i2c.read( 0xe2, cmd, 1);        // Cont Regを読込み
00016     wait(0.1);                      // 0.1s待つ
00017     switch(cmd[0] & 0xf)
00018     {
00019     case 0:                         // bus off, has control
00020     case 1:                         // bus off, no control
00021     case 5:                         // bus on, no control
00022         cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
00023         cmd[1] = 4;                 // bus on, has control
00024         i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
00025         i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
00026         break;
00027     case 2:                         // bus off, no control
00028     case 3:                         // bus off, has control
00029     case 6:                         // bus on, no control
00030         cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
00031         cmd[1] = 5;                 // bus on, has control
00032         i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
00033         i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
00034         break;
00035     case 9:                         // bus on, no control
00036     case 0xc:                       // bus on, no control
00037     case 0xd:                       // bus off, no control
00038         cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
00039         cmd[1] = 0;                 // bus on, has control
00040         i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
00041         i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
00042         break;
00043     case 0xa:                       // bus on, no control
00044     case 0xe:                       // bus off, no control
00045     case 0xf:                       // bus on, has control
00046         cmd[0] = 1;                 // PCA9541 コマンドコード Cont Reg
00047         cmd[1] = 1;                 // bus on, has control
00048         i2c.write( 0xe2, cmd, 2);   // Cont Regにcmd[1]を書込み
00049         i2c.read( 0xe2, cmd, 1);    // Cont Regを読込み
00050         break;
00051     default:
00052         break;
00053     }
00054 
00055     cmd[0] = sel;                   // PCA9546 Cont Reg sel channel enabled
00056     i2c.write( 0xe8, cmd, 1);       // Send command string
00057 }
00058 
00059 void  get_time(dt_dat *dt)      // 日時の取得
00060 {
00061     cmd[0] = Seconds_100th;                       // 取得はレジスタSecondsから
00062     i2c.write(PCF85263AT_ADDR, cmd, 1);      // レジスタの設定
00063     i2c.read(PCF85263AT_ADDR, cmd, 8);       // SecondsからYearsまで取得
00064     cmd[1] &= 0x7f;                         // 有効なのは下位7ビット
00065     dt->s = (cmd[1] >> 4) * 10 + (cmd[1] & 0xf);    // BCDの数値化
00066     cmd[2] &= 0x7f;                         // 有効なのは下位7ビット
00067     dt->m = (cmd[2] >> 4) * 10 + (cmd[2] & 0xf);    // BCDの数値化
00068     cmd[3] &= 0x3f;                         // 有効なのは下位6ビット
00069     dt->h = (cmd[3] >> 4) * 10 + (cmd[3] & 0xf);    // BCDの数値化
00070     cmd[4] &= 0x3f;                         // 有効なのは下位6ビット
00071     dt->d = (cmd[4] >> 4) * 10 + (cmd[4] & 0xf);    // BCDの数値化
00072     dt->wd = (cmd[5] & 0x3);                        // BCDの数値化
00073     cmd[6] &= 0x1f;                         // 有効なのは下位5ビット
00074     dt->mm = (cmd[6] >> 4) * 10 + (cmd[6] & 0xf);   // BCDの数値化
00075     dt->y = (cmd[7] >> 4) * 10 + (cmd[7] & 0xf);    // BCDの数値化
00076 }        
00077 
00078 void set_time(dt_dat *dt)       // 日時の設定
00079 {
00080     cmd[0] = Seconds_100th;                // 設定はレジスタSeconds_100thから
00081     cmd[1] = ((dt->s100th / 10) << 4) + (dt->s100th % 10);// 0.01秒のBCD化
00082     cmd[2] = ((dt->s / 10) << 4) + (dt->s % 10) + 0x80; // 秒のBCD化
00083     cmd[3] = ((dt->m / 10) << 4) + (dt->m % 10);        // 分のBCD化
00084     cmd[4] = ((dt->h / 10) << 4) + (dt->h % 10);        // 時のBCD化
00085     cmd[5] = ((dt->d / 10) << 4) + (dt->d % 10);        // 日のBCD化
00086     cmd[7] = ((dt->mm / 10) << 4) + (dt->mm % 10);      // 月のBCD化
00087     dt->y = dt->y - 2000;       
00088     cmd[8] = ((dt->y / 10) << 4) + (dt->y % 10);        // 年のBCD化
00089     i2c.write(PCF85263AT_ADDR, cmd, 9);      // 日時の設定
00090 }
00091 
00092 
00093 int main ()
00094 {
00095     i2c.frequency(100000);
00096     pc.printf("PC85263AT Sample Program\r\n");
00097      
00098     set_ch(1);              // PC85263ATはch0に接続
00099 
00100   // PC85263AT
00101 /*    cmd[0] = CLKOUT_ctl;                // CLKOUTレジスタ設定
00102     cmd[1] = (3 << 6) + 4;              // 温度測定は30s毎、出力周波数は2048Hz
00103     i2c.write(PCF85263AT_ADDR, cmd, 2);  // CLKOUT設定
00104 
00105     cmd[0] = Aging_offset;              // Aging_offsetレジスタ設定
00106     cmd[1] = 0x9;                       // -1ppm
00107     i2c.write(PCF85263AT_ADDR, cmd, 2);  // Aging_offset設定
00108 */
00109 
00110     cmd[0] = Oscillator;              // Aging_offsetレジスタ設定
00111     cmd[1] = 0x80 + 0x40 + 0x1;                       // -1ppm
00112     i2c.write(PCF85263AT_ADDR, cmd, 2);  // Aging_offset設定
00113 
00114     cmd[0] = Function;              // Aging_offsetレジスタ設定
00115     cmd[1] = 0x1;                       // -1ppm
00116     i2c.write(PCF85263AT_ADDR, cmd, 2);  // Aging_offset設定
00117 
00118     cmd[0] = Offset;              // Aging_offsetレジスタ設定
00119     cmd[1] = 60;                       // -1ppm
00120     i2c.write(PCF85263AT_ADDR, cmd, 2);  // Aging_offset設定
00121 
00122 
00123     dt.y = 2014;                // 年の設定
00124     dt.mm = 10;                 // 月の設定
00125     dt.d = 7;                   // 日の設定
00126     dt.h = 10;                  // 時の設定
00127     dt.m = 22;                  // 分の設定
00128     dt.s = 0;                   // 秒の設定
00129     set_time(&dt);              // 日時の設定
00130 
00131     while(1)
00132     {
00133         get_time(&dt);          // 日時の取得
00134              // 日時の表示
00135         pc.printf("%04d/%02d/%02d %02d:%02d:%02d\r\n", 2000 + dt.y, dt.mm, dt.d, dt.h, dt.m, dt.s);
00136         wait(1);
00137     }
00138 }