最終更新日 平成26年5月15日
起動した後、n キーを押すとNTPで時計を合わせます。
// RXduino sample programs. // (C)2012-2014 Copyright TokushuDenshiKairo Inc. #include <rxduino.h> #include <Ethernet.h> #include <rtc.h> #include <time.h> TEthernet Ethernet; BOOL onReceiveUDP(unsigned char dest_ip[4], unsigned char src_ip[4], unsigned short dest_port,unsigned short src_port, unsigned char *data, short datalen); bool ether_init = false; #if RTC_LIBRARY_VERSION >= 0x01060000 #define _MYRTC RXRTC #else #define _MYRTC RTC #endif void ShowRegs(const char *mes) { printf("%s\n",mes); printf("SOSCWTCR=%02X\n",*(volatile unsigned char *)0x000800A3); printf("SOSCCR=%02X\n",*(volatile unsigned char *)0x00080033); printf("RCR1=%02X\n",*(volatile unsigned char *)0x0008c422); printf("RCR2=%02X\n",*(volatile unsigned char *)0x0008c424); printf("RCR3=%02X\n",*(volatile unsigned char *)0x0008c426); printf("RCR4=%02X\n",*(volatile unsigned char *)0x0008c428); } bool EtherInit() { byte mac[] = {2,0,0,0,0,1}; Ethernet.begin(mac); Ethernet.registUdpHandler(onReceiveUDP); printf("My ip addr = %s\n",Ethernet.localIP()); ether_init = true; return Ethernet.isLinkup(); } void ShowHelp() { printf("USAGE:\n"); printf(" a: Adjust RTC to someday\n"); printf(" s: Show registers\n"); printf(" l: Enter osc into low power mode (but it may not able to continue operating)\n"); printf(" r: Reboot this application again\n"); printf(" f: Reboot gr-firmware \n"); printf(" d: Renrew ipaddress by DHCP.\n"); printf(" n: Sync to NTP server (ntp.nict.jp) \n"); printf(" h ?: Show this help \n"); printf("\n"); } void setup() { pinMode(PIN_LED0, OUTPUT); pinMode(PIN_LED1, OUTPUT); pinMode(PIN_LED2, OUTPUT); pinMode(PIN_LED3, OUTPUT); pinMode(PIN_SW , INPUT); digitalWrite(PIN_LED0, 1); Serial.begin(38400, SCI_AUTO); Serial.setDefault(); digitalWrite(PIN_LED1, 1); printf("------------------------------\n"); printf("RX RTC test program 2\n"); printf("------------------------------\n"); printf("This program diagnoses and initializes RTC.\n"); ShowHelp(); // ShowRegs("Default registers"); int ret = _MYRTC::begin(); /* if(ret < 2) { _MYRTC::setDateTime( 2013, 1, 2, 2, 14, 00 ); } */ // printf("rtc init result=%d\n",ret); // ShowRegs("After initialization"); } unsigned long lasttime = 0; void loop() { if(Serial.available()) { char c = Serial.read(); if(c == 'a') // adjust { _MYRTC::setDateTime( 2013, 2, 22, 8, 17, 20 ); } if(c == 's') // show registers { ShowRegs("Current registers"); } if(c == 'l') // low power mode { *(volatile unsigned char *)0x0008c426 = 0x03; // RTCDV=001 ShowRegs("Low power mode"); } if(c == 'r') // reboot and launch this application again { printf("Reboot userapp\n");delay(100); system_reboot(REBOOT_USERAPP); } if(c == 'f') // reboot and launch gr firmware { printf("Reboot firmware\n");delay(100); system_reboot(REBOOT_FIRMWARE); } if((c == '?') || (c == 'h')) { ShowHelp(); } if(c == 'd') { if(!ether_init) EtherInit(); if(Ethernet.isLinkup()) { printf("Renew IP address with DHCP..."); if(Ethernet.dhcp()) { printf("Success! My ip addr = %s\n",Ethernet.localIP()); } else { printf("failed\n"); } } } if(c == 'n') { if(!ether_init) EtherInit(); if(Ethernet.isLinkup()) { printf("NTP test : ntp.nict.jp is "); byte *ip = Ethernet.gethostbyname("ntp.nict.jp"); printf("Server address: %d.%d.%d.%d\n",ip[0],ip[1],ip[2],ip[3]); unsigned char buf[12*4]; memset(buf,0,12*4); buf[0] = 0xe3; // 閏秒:警告 バージョン4 クライアント buf[1] = 0x00; // 階層不明 buf[2] = 0x04; // 8秒間隔 buf[3] = 0xfa; buf[5] = 0x01; buf[9] = 0x01; Ethernet.sendUDP(ip,123,buf,12*4); } else { printf("Ether is not connected\n"); } } } if(millis() - lasttime >= 1000) { int year,mon,day,hour,min,sec; _MYRTC::getDateTime( year, mon, day, hour, min, sec ); printf("%04d/%02d/%02d %02d:%02d:%02d\n",year, mon, day, hour, min, sec); lasttime = millis(); } } BOOL onReceiveUDP( unsigned char dest_ip[4], unsigned char src_ip[4], unsigned short dest_port, unsigned short src_port, unsigned char *data, // UDPパケットのデータ部 short datalen // UDPパケットのデータの長さ(ヘッダは含まない) ) { if(dest_port == 123) // NTP受信! { unsigned char LeapIndicator = data[0] >> 6; unsigned char VersionNumber = (data[0] >> 3) & 0x07; unsigned char Mode = (data[0] >> 0) & 0x07; unsigned char Stratum = data[1]; signed char Precision = data[3]; char ReferenceID[5]; memcpy(ReferenceID,&data[12],4); ReferenceID[4] = '\0'; unsigned long TransTimeH = (data[40] << 24) | (data[41] << 16) | (data[42] << 8) | data[43]; printf("NTPv%d length=%d Mode:",VersionNumber,datalen); switch(Mode) { case 0: printf("Reserved, "); break; case 1: printf("Synmetic Active, "); break; case 2: printf("Synmetic Client, "); break; case 3: printf("Client, "); break; case 4: printf("Server, "); break; case 5: printf("Broadcast, "); break; case 6: printf("Reserved for NTP control, "); break; case 7: printf("Reserved for private, "); break; default:printf("Undefined, "); break; } printf("Leap indicator:(%d)\n",LeapIndicator); printf("Stratum %d\n",Stratum); printf("precisiton %d\n",Precision); printf("Reference-ID: %s\n",ReferenceID); // NTP時刻をUNIX時刻に変換 time_t t = TransTimeH - 2208988800UL; t += 9*60*60; // 日本標準時に変換 struct tm *t_st = localtime(&t); printf("Transit Timestamp %s\n",asctime(t_st)); printf("Set RTC datetime with NTP result.\n"); int year,mon,day,hour,min,sec; year = t_st->tm_year; mon = t_st->tm_mon + 1; day = t_st->tm_mday; hour = t_st->tm_hour; min = t_st->tm_min; sec = t_st->tm_sec; _MYRTC::setDateTime(year,mon,day,hour,min,sec); return TRUE; } return false; // この関数で処理したことにしない }
最初はめちゃくちゃな時間を指していますが、NTPで通信した後は正しい時間になっています。
(C)2012-2014 特殊電子回路株式会社 All Rights Reserved