This is the clock which used highly quality RTC module RT8564NB. This module is I2C controllable. At the time of poweron/reset, the start time received from ntp server. See: http://blogs.yahoo.co.jp/jf1vrr_station/19895596.html (Japanese)

Dependencies:   EthernetNetIf NTPClient_NetServices TextLCD mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002 This is the clock which used highly quality RTC module RT8564NB. 
00003 This module is I2C controllable. At the time of poweron/reset, the start 
00004 time received from ntp server.
00005 
00006 Revision History:
00007 Rev. 0.01A 2011/04/26 New
00008 Rev. 0.01B 2011/04/27 Add time justify function, sec LED 
00009  */
00010 #include "mbed.h"
00011 #include "TextLCD.h"
00012 #include "EthernetNetIf.h"
00013 #include "NTPClient.h"
00014 
00015 #define RTC8564NB_ADR 0xA2
00016 
00017 #define CONTROL1 0x00
00018 #define CONTROL2 0x01
00019 #define SECONDS 0x02
00020 #define MINUTES 0x03
00021 #define HOURS 0x04
00022 #define DAYS 0x05
00023 #define WEEKDAYS 0x06
00024 #define MONTHS 0x07
00025 #define YEARS 0x08
00026 #define MINUTE_ALARM 0x09
00027 #define HOUR_ALARM 0x0A
00028 #define DAY_ALARM 0x0B
00029 #define WEEKDAY_ALARM 0x0C
00030 #define CLOCKOUT_FREQ 0x0D
00031 #define TIMER_CINTROL 0x0E
00032 #define TIMER 0x0F
00033 #define _READ 0x01
00034 
00035 TextLCD lcd(p24, p26, p27, p28, p29, p30);
00036 EthernetNetIf eth; 
00037 NTPClient ntp;
00038 I2C i2c(p9, p10);
00039 DigitalOut sec_led(LED1);
00040 DigitalOut test_led(LED2);
00041 InterruptIn just_button(p15);
00042 
00043 int offset_JAPAN = 32400;
00044 
00045 char year, month, day, week;
00046 char hour, minute, sec;
00047 char ntp_year[3], ntp_month[3], ntp_day[3], ntp_week[4];
00048 char ntp_hour[3], ntp_minute[3], ntp_sec[3];
00049 char week_val;
00050 
00051 char week_chr[7][4] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
00052     
00053 void rtc_write(char address, char value)
00054 {
00055     i2c.start();
00056     i2c.write(RTC8564NB_ADR);
00057     i2c.write(address);
00058     i2c.write(value);
00059     i2c.stop();
00060 }
00061 
00062 char rtc_read(char address)
00063 {
00064     char value;
00065     i2c.start();
00066     i2c.write(RTC8564NB_ADR);
00067     i2c.write(address);
00068     i2c.start();
00069     i2c.write(RTC8564NB_ADR | _READ);
00070     value = i2c.read(0);
00071     i2c.stop();
00072     
00073     return value;
00074 }
00075 
00076 void time_just()
00077 {
00078     char _min, _hour;
00079     test_led = !test_led;
00080     _min = rtc_read(MINUTES);
00081     if (_min >= 0x30) { 
00082             _hour = rtc_read(HOURS);
00083             if (_hour == 0x23)
00084                 _hour = 0x00;
00085             else if ((_hour & 0x0F) == 0x09)
00086                 _hour = (_hour & 0xF0) + 0x10;
00087             else
00088                 _hour = _hour + 0x01;
00089             rtc_write(HOURS, _hour);
00090     }
00091     rtc_write(MINUTES, 0x00);
00092     rtc_write(SECONDS, 0x00);
00093 }
00094     
00095 int main() {
00096     just_button.rise(&time_just);
00097 
00098     lcd.cls();
00099     lcd.printf("RTC8564NB CLOCK" );
00100     wait(2.0);
00101     
00102     /* Set up Ethernet */
00103     lcd.cls();
00104     lcd.printf("Setting up Eth\n");
00105     EthernetErr ethErr = eth.setup();
00106     if (ethErr) {
00107         lcd.cls();
00108         lcd.printf("Error with Eth\nNum: %d", ethErr);
00109         return -1;
00110     }   
00111     
00112     /* Set up NTP */
00113     lcd.printf("Setting up NTP\n");
00114     Host server(IpAddr(), 123, "ntp1.jst.mfeed.ad.jp");
00115     ntp.setTime(server);
00116     
00117     time_t seconds = time(NULL)+offset_JAPAN;
00118     
00119     lcd.cls();
00120     strftime(ntp_year, 16, "%y", localtime(&seconds));
00121     strftime(ntp_month, 16, "%m", localtime(&seconds));
00122     strftime(ntp_day, 16, "%d", localtime(&seconds));
00123     strftime(ntp_week, 16, "%a", localtime(&seconds));
00124     strftime(ntp_hour, 16, "%H", localtime(&seconds));
00125     strftime(ntp_minute, 16, "%M", localtime(&seconds));
00126     strftime(ntp_sec, 16, "%S", localtime(&seconds));
00127     
00128     switch (ntp_week[0]){
00129         case 'S': 
00130             switch (ntp_week[1]) {
00131                 case 'u': week_val = 0x00; break;
00132                 case 'a': week_val = 0x06; break;
00133             }
00134             break;
00135         case 'M': week_val = 0x01; break;
00136         case 'T': 
00137             switch (ntp_week[1]) {
00138                 case 'u': week_val = 0x02; break;
00139                 case 'h': week_val = 0x04; break;
00140             }
00141             break;
00142         case 'W': week_val = 0x03; break;
00143         case 'F': week_val = 0x05; break;
00144     }
00145         
00146     rtc_write(CONTROL1, 0x20); //stop
00147     rtc_write(CONTROL2, 0x00);
00148     rtc_write(YEARS, ((ntp_year[0]-0x30)<<4)+(ntp_year[1]-0x30)); 
00149     rtc_write(MONTHS, ((ntp_month[0]-0x30)<<4)+(ntp_month[1]-0x30));
00150     rtc_write(DAYS, ((ntp_day[0]-0x30)<<4)+(ntp_day[1]-0x30));
00151     rtc_write(HOURS, ((ntp_hour[0]-0x30)<<4)+(ntp_hour[1]-0x30));
00152     rtc_write(MINUTES, ((ntp_minute[0]-0x30)<<4)+(ntp_minute[1]-0x30));
00153     rtc_write(SECONDS, ((ntp_sec[0]-0x30)<<4)+(ntp_sec[1]-0x30));
00154     rtc_write(WEEKDAYS, week_val);
00155     rtc_write(CLOCKOUT_FREQ, 0x00); // 0x83 = TE on & 1Hz
00156     rtc_write(TIMER_CINTROL, 0x00);
00157     rtc_write(CONTROL1, 0x00); //start
00158     
00159     while(1) { 
00160         year = rtc_read(YEARS);
00161         month = rtc_read(MONTHS);
00162         day = rtc_read(DAYS);
00163         week = rtc_read(WEEKDAYS);
00164         hour = rtc_read(HOURS);
00165         minute = rtc_read(MINUTES);
00166         sec = rtc_read(SECONDS);
00167         lcd.locate(0,0);
00168         lcd.printf("20%c%c/%c%c/%c%c %s",
00169             ((year >> 4) & 0x03) + 0x30, (year & 0x0F) + 0x30, 
00170                 ((month >> 4) & 0x01) + 0x30, (month & 0x0F) + 0x30, 
00171                     ((day >> 4) & 0x03)+ 0x30, (day & 0x0F) + 0x30, 
00172                         week_chr[week & 0x07]);
00173         lcd.locate(0,1); 
00174         lcd.printf("%c%c:%c%c:%c%c",
00175             ((hour >> 4) & 0x03) + 0x30, (hour & 0x0F) + 0x30, 
00176                 (minute >> 4) + 0x30, (minute & 0x0F) + 0x30, 
00177                     (sec >> 4) + 0x30, (sec & 0x0F) + 0x30 );
00178         
00179         sec_led = !sec_led;
00180         wait(0.5);
00181     }
00182 }