株式会社ジーテック

制御機器を小ロット多品種で設計製作

RTCモジュール(RX6110SA)の時間取得

マイコンボードZT-PIC16F194701にはあらかじめRTCが搭載している物もあり、別途時計チップを試す必要も無いかもしれませんが、RX6110SAはバッテリー接続用のピンもあり、時計を保持させる面に関しては優れています。 そこであえて時計無しのマイコンボードを使用し、時間を取得します。

今回の試作ではバッテリーを付けていません。バッテリーを接続する場合はマニュアルのP.3をご確認ください。 接続に関してはライブラリの説明文をご確認ください。

OLYMPUS DIGITAL CAMERA

UARTポートに接続したシリアルからコマンドを入力することで時間取得が確認できるようにしています。

RTCについてちょっと一言・・・
元々マイコンボードに乗せているRTC-8564JEは使い慣れているという点から採用しました。しかし、バッテリー用端子が無く、電気二重層コンデンサでの時計の保持について少々いまいちな気もしてました。 そこで時折、他にいいチップは無いかと思い、条件としては時計用クロックは内蔵で時間を刻む事に対してチップ以外の部品が必要でない事、I2C接続な事で探していました。気になる毎に探していましたが、最近バッテリー用端子付きがあることに気が付き、今回試してみる事に至りました。RTCのICは色々ありますがクロック内蔵というのはなかなか無いと思います。

使用機器

使用機器は下記のとおり。他、パソコンや電源、PICKIT2も当然ながら必要です。

I2CリアルタイムクロックIC Epson RX6110SA カタログ マニュアル
マイコンボード(PIC16F1947搭載) ZEATEC co.,ltd. ZT-PIC16F194701(5V仕様)
プロジェクトファイルも含めたサンプル zt-16f194701_rx6110sa.zip
接続ハーネスの図面 Harness_RX6110SA.zip Harness_RX6110SA.pdf
開発環境:MPLAB_IDE_8_92 + CCS-C PCMコンパイラVer.4.132
※VBAT端子からコンデンサへ電源を供給する場合は80mAまでです。
(セイコーエプソン株式会社TD営業グループより回答)

使用機器

RX6110SA用ライブラリ「rtc_rx6110sa.c」の中身です。使用方法等、も記載しています。

///////////////////////////////////////////////////////////////////
//  リアルタイムクロックライブラリ
//■対応RTC IC:Seiko Epson Corp. RX6110SA
//■使用デバイス番号:書込みモード=0x64,読込みモード=0x65
//■通信方式:I2C
//■通信速度:100kHz or 400kHz
//■製作:2016年12月31日 ZEATEC co.,ltd. S.Hirai
///////////////////////////////////////////////////////////////////
//
//■事前準備
//ヘッダー部分で先にI2Cと、このファイルの読み込みが必要です。
//#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3,SLOW,FORCE_HW)//FAST=400kbps SLOW=100kbps
//#include "rtc_rx6110sa.c"
//
//■使い方
//rtc_date_setに12桁または13桁の数字を割り当てることで日時を更新します。
//12桁入力の場合:param1 = 160323101840(2016年03月23日10時18分40秒)
//13桁入力の場合:param1 = 1603233101840(2016年03月23日水曜日10時18分40秒)
//rtc_date_set(param1);
//曜日は数字に置き換えると下記のようになります。
//0=日曜日 1=月曜日 2=火曜日 3=水曜日 4=木曜日 5=金曜日 6=土曜日
//時刻を読み込むには、rtc_date_read()を実行するだけで各変数(sec,minなど)の値が更新される。
//fprintf(c1," %02x:%02x:%02x\r\n",hour,min,sec);とする事で時間が表示できます。
//各値を10進数に変換したい場合は下記の計算例を元に変換してください。
//sec = ((sec >> 4)*10)+ (sec & 0x0f);
//
//■接続
//1.CLK/SCL →SCL
//2.DI/SDA  →SDA
//3.DO/FOUT →クロック出力
//4.CE/FOE  →GND
//5.SPISEL  →GND
//6.GND  →GND
//7./IRQ2   →タイマー出力②
//8.N.C.    →空き
//9.Vbat    →電池のプラス
//10.Vdd    →VCC
//11.Vio    →VCC
//12./IRQ1  →タイマー出力②
//13.N.C.   →空き
//14.N.C.   →空き

int year,month,week,day,hour,min,sec;// 現時刻
char c_week[] = "xxx";
int rtc_flag = 0;

void rtc_init(){
    delay_ms(40);//ウェイクアップウェイト
    //初期化設定
    i2c_start();
    i2c_write(0x64); // デバイス番号(書き込みモード)
    i2c_write(0x1e); // 
    i2c_start();
    i2c_write(0x65); // デバイス番号(読込みモード)
    rtc_flag = i2c_read(0); // 
    i2c_stop();
    if(bit_test(rtc_flag,1) == 1){
        i2c_start();
        i2c_write(0x64); // デバイス番号(書き込みモード)
        i2c_write(0x1d); // Extention Register
        i2c_write(0b01000010); // 設定値(動作設定前にTEビットをゼロクリア)
        
        i2c_write(0x1b); // Timer Counter0
        i2c_write(0b00000001); // 設定値
        i2c_write(0x1c); // Timer Counter1
        i2c_write(0b00000000); // 設定値
        i2c_write(0x1f); // Control Register
        i2c_write(0b00111000); // 設定値      
        i2c_write(0x31); // Reserved
        i2c_write(0b00011100); // 設定値
        i2c_write(0x32); // IRQ Control
        i2c_write(0b00010100); // 設定値

        i2c_write(0x1d); // Extention Register
        i2c_write(0b01010010); // 設定値(動作設定後TEビットをセット)
        i2c_stop();
    }
}

//日時設定
int rtc_date_set(int *data) {

    int tmp_update = 0;
    int tmp_week = 0;
    int ans = 0;
    //fprintf(c1, "%02x\r\n", strlen(data));

    //RTC初期化(RX6110SA)
    rtc_init();

    if(strlen(data) == 13){
        //パラメータを分割して書き込み
        //設定例:time,160323101840(2016年03月23日10時18分40秒)
        //曜日指定なし
        year = ((data[0] - 0x30)*16) + (data[1] - 0x30);
        month = ((data[2] - 0x30)*16) + (data[3] - 0x30);
        day = ((data[4] - 0x30)*16) + (data[5] - 0x30);
        hour = ((data[6] - 0x30)*16) + (data[7] - 0x30);
        min = ((data[8] - 0x30)*16) + (data[9] - 0x30);
        sec = ((data[10] - 0x30)*16) + (data[11] - 0x30);

        tmp_update = 1;
        ans = 1;
        //fprintf(c1,"time set ok.\r\n");
    }else if(strlen(data) == 14){
        //パラメータを分割して書き込み
        //設定例:time,1603234101840(2016年03月23日水曜日10時18分40秒)
        //曜日指定あり
        year = ((data[0] - 0x30)*16) + (data[1] - 0x30);
        month = ((data[2] - 0x30)*16) + (data[3] - 0x30);
        day = ((data[4] - 0x30)*16) + (data[5] - 0x30);
        week = data[6] - 0x30;
        hour = ((data[7] - 0x30)*16) + (data[8] - 0x30);
        min = ((data[9] - 0x30)*16) + (data[10] - 0x30);
        sec = ((data[11] - 0x30)*16) + (data[12] - 0x30);

        tmp_update = 1;
        ans = 1;
        //fprintf(c1,"time set ok.\r\n");
    }else{
        ans = 2;
        //fprintf(c1,"Parameter error.\r\n");
    }

    if (tmp_update == 1) {
        //先に曜日のデータを変換
        if (week == 0x0) {
            tmp_week = 0x1;
        }else if (week == 0x1) {
            tmp_week = 0x2;
        }else if (week == 0x2) {
            tmp_week = 0x4;
        }else if (week == 0x3) {
            tmp_week = 0x8;
        }else if (week == 0x4) {
            tmp_week = 0x10;
        }else if (week == 0x5) {
            tmp_week = 0x20;
        }else if (week == 0x6) {
            tmp_week = 0x40;
        }

        i2c_start();
        i2c_write(0x64); // デバイス番号(書き込みモード)
        i2c_write(0x10); // 秒のアドレス

        i2c_write(sec);  // 秒の値 0-59
        i2c_write(min);  // 分の値 0-59
        i2c_write(hour); // 時の値 0-23
        i2c_write(tmp_week); // 曜の値 日月火水木金土 week
        i2c_write(day);  // 日の値 1-31
        i2c_write(month);// 月の値 (C:MSB)1-12   Cは1のとき21世紀
        i2c_write(year); // 年の値 00-99

        i2c_stop();
    }

    return ans;
}

//日時の読み出し
void rtc_date_read() {
    int tmp_week = 0;

    i2c_start();
    i2c_write(0x64); // デバイス番号(書き込みモード)
    i2c_write(0x10); // 秒のアドレス(読み出し先頭アドレス)
    i2c_start();
    i2c_write(0x65); // デバイス番号(読込みモード)

    sec = i2c_read(1); // 秒の値
    min = i2c_read(1); // 分の値
    hour = i2c_read(1); // 時の値
    tmp_week = i2c_read(1); // 曜の値
    day = i2c_read(1); // 日の値
    month = i2c_read(1); // 月の値
    year = i2c_read(0); // 年の値
    i2c_stop();
    bit_clear(month, 7);
    bit_clear(month, 6);
    bit_clear(month, 5);
    bit_clear(day, 7);
    bit_clear(day, 6);
    bit_clear(hour, 7);
    bit_clear(hour, 6);
    bit_clear(min, 7);
    bit_clear(sec, 7);
    if (tmp_week == 0x01) {
        week = 0; c_week = "SUN";
    }else if (tmp_week == 0x02) {
        week = 1; c_week = "MON";
    }else if (tmp_week == 0x04) {
        week = 2; c_week = "TUE";
    }else if (tmp_week == 0x08) {
        week = 3; c_week = "WED";
    }else if (tmp_week == 0x10) {
        week = 4; c_week = "THU";
    }else if (tmp_week == 0x20) {
        week = 5; c_week = "FRI";
    }else if (tmp_week == 0x40) {
        week = 6; c_week = "SAT";
    }else {
        week = 7; c_week = "ERR";
    }
}

©ZEATEC co.,ltd.