Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: TextLCD WakeUp mbed
Revision 0:f40db885ccfb, committed 2014-02-26
- Comitter:
- star297
- Date:
- Wed Feb 26 21:39:57 2014 +0000
- Commit message:
- Initial version 1.0
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD.lib Wed Feb 26 21:39:57 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/simon/code/TextLCD/#44f34c09bd37
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WakeUp.lib Wed Feb 26 21:39:57 2014 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/Sissors/code/WakeUp/#89dae784c38f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Wed Feb 26 21:39:57 2014 +0000
@@ -0,0 +1,350 @@
+#include "mbed.h"
+#include "TextLCD.h"
+#include "WakeUp.h"
+
+TextLCD lcd(PTB6, PTA12, PTB5, PTA11, PTB1, PTB2, TextLCD::LCD20x4); // rs, e, d4, d5, d6, d7
+InterruptIn dcfSignalIn(PTB0); //DCF signal input,conection of output non-inverting module
+
+// Include the definition for required Time Zone
+#define TimeZone 1 //GMT
+//#define TimeZine 2 //CET
+//#define TimeZone 3 //EET
+
+DigitalOut dcfLED(LED1);
+DigitalOut WakeLED(LED3);
+
+//variable
+char paritycheck,paritym,parityu,paritydmy;
+char testu,testm,testdmy;
+char minh,minl;
+char hourh,hourl;
+char day,dayh,dayl;
+char monthh,monthl;
+char yearh,yearl;
+char summertime;
+char buffer[32];
+int interrupt_counter = 0;
+int hour = 0;
+int minute = 0;
+int second = 0;
+int dayofweek = 6;
+int dayofmonth = 1;
+int month = 1;
+int year = 0;
+int nosignal,signal_error,start,dcf_sec,sync,RTCset,getDCF;
+int p_minute,p_hour,p_dayofweek,p_dayofmonth,p_month,p_year;
+int dcf_error,error_count,dcf_good,signal_good,ISRlock;
+int n,loop;
+int dcf_array[61];
+
+typedef unsigned char byte;
+
+//makro,s
+void dcfISR(),dcf_check(),checkSIGNAL(),signal();
+void parity_calc();
+void RTC_reset(),RTC_set();
+void Displayloop();
+void setTIME();
+void restart();
+void dcfIRQ();
+
+Ticker Ticker50ms;
+Timer check;
+#define ZERO 1e-10
+#define isBetween(A, B, C) (((A-B) > -ZERO) && ((A-C) < ZERO))
+
+struct status {
+ bool is_leap; // Leap year flag (NOT actually transmitted but calculated)
+ bool sample50; // dcf sample at 50mS into the start of the second
+ bool sample150; // dcf sample at 150mS into the start of the second
+ int second; // dcf second (NOT actually transmitted but calculated)
+}
+dcf_status;
+
+struct dcf {
+ char dut1; // DUT1 (0.1 - 0.8)
+ char dut2; // DUT2 (-0.1 - -0.8)
+ char year; // Year (00 - 99)
+ char month; // Month (01 - 12)
+ char dayofmonth; // Day of month (01 - 31)
+ char dayofweek; // Day of week (Sunday=0 Saturday=6)
+ char hour; // Hour (00 - 23)
+ char minute; // Minute (00 - 59)
+} dcf_time;
+
+struct tm t;
+
+// Various text strings used in display
+char weekDayName[7][4] = {"Sun","Mon","Tue","Wed","Thu", "Fri","Sat"};
+char monthName[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+char MAX_DAY[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // Max days in a month for a non-leap year
+char leapText[2][4] = {" ", "L"};
+char dstSymbol[2][3] = {"WT", "ST"};
+
+byte maxDay(byte year, byte month) // Return the maximum day in month for a given month & year
+{
+ byte lastday, leap;
+ leap = year%4 == 0 && year%100 !=0 || year%400 == 0;
+ lastday = MAX_DAY[month - 1];
+ dcf_status.is_leap = leap > 0 ? 1 : 0;
+ if ((leap > 0) && (month == 2))
+ lastday++;
+ return lastday;
+}
+
+int dayOfWeek(int y, int m, int d) // 0 = Sunday
+{
+ static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
+ y -= m < 3;
+ return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
+}
+
+int main()
+{
+ lcd.printf("DCF77 clock\n");
+ lcd.printf("Checking Signal");
+ WakeLED=1;dcfLED=1;
+ WakeUp::calibrate();
+ wait(1);
+ checkSIGNAL();dcfSignalIn.rise(NULL);lcd.cls();
+ if (signal_good==0) {
+ lcd.printf("No Signal!!\n");
+ lcd.printf("Retry in 1 hour");
+ wait(2);lcd.cls();n=3600;
+ getDCF=0;
+ }
+ else{
+ lcd.printf("DCF detected\n");
+ lcd.printf("Setting RTC");
+ wait(2);lcd.cls();
+ restart();lcd.cls();
+ }
+
+ while (true){
+
+ while (getDCF==1) { // Get dcf time and set cpu RTC
+ if (loop==0) {
+ Displayloop(); // update display every 50mS
+ loop=1;
+ }
+ }
+
+ while (getDCF==0) { // Deep Sleep mode, Wake and update display time every second
+ WakeLED=0;
+ time_t seconds = time(NULL);
+ strftime(buffer, 32, "%I:%M:%S %p", localtime(&seconds));
+ lcd.locate(0,0);lcd.printf("RTC %s", buffer);
+ strftime(buffer, 32, "%a %d %b %Y ", localtime(&seconds));
+ lcd.locate(0,1);lcd.printf("%s", buffer);
+ WakeLED=1;
+ n--;if (n==0) {getDCF=1;} // Restart and Synchronise DCF every 1 or 24 hours
+ WakeUp::set(1);
+ deepsleep();
+ }
+ checkSIGNAL();dcfSignalIn.rise(NULL);lcd.cls();
+ if (signal_good==1) {restart();}
+ else {n=3600;getDCF=0;}
+ }
+}
+
+void Displayloop()
+{
+ if (interrupt_counter == 0) {
+ if (dcf_good == 1 && dcf_sec == 2) {
+ RTC_set(); // set cpu RTC if good data
+ }
+ time_t seconds = time(NULL);
+ strftime(buffer, 32, "%a %d %H:%M:%S", localtime(&seconds));
+ lcd.locate(0,1);lcd.printf("%s", buffer);
+ }
+
+ if (interrupt_counter==3){
+ if (start==1){
+ dcf_array[dcf_sec]=dcf_status.sample150;
+ if (dcf_sec==0){
+ dcf_array[58] = 0;
+ }
+ }
+ }
+
+ if (interrupt_counter==5) {
+ if (signal_error==1){
+ Ticker50ms.detach();dcfSignalIn.rise(NULL);getDCF=0;lcd.cls();
+ lcd.printf("10 Signal errors\n");
+ lcd.printf("detected,restart");
+ wait(2);
+ lcd.cls();restart();} // Restart DCF ISR if signal 10 errors detected
+ }
+}
+
+void setTIME() // Set time variables with Partity data
+{
+ second = dcf_sec;
+ minute=p_minute;
+ hour=p_hour;
+ dayofweek=p_dayofweek;
+ dayofmonth=p_dayofmonth;
+ month=p_month;
+ year=p_year;
+}
+
+void checkSIGNAL()
+{
+ n=10;dcfSignalIn.rise(signal);
+ while(n>0){
+ if (ISRlock==0){
+ lcd.locate(0,0);
+ if (signal_good==1) {lcd.printf ("Signal Good %d ",n);}
+ else {lcd.printf("No Signal %d ",n);}
+ signal_good=0;
+ }
+ wait(1);
+ n--;
+ }
+}
+void signal()
+{
+check.start();ISRlock=1,signal_good=1;
+while (dcfSignalIn==1){};
+check.stop();
+lcd.locate(0,1);lcd.printf ("DCF pulse %3.f mS",(check.read()*1000));
+check.reset();ISRlock=0;
+}
+
+void restart()
+{
+hour = 0;minute = 0,second = 0,dayofweek = 6;dayofmonth = 1;month = 1;year = 0;
+signal_error=0;sync=0;getDCF=1;RTCset=0;error_count=0;
+start=0;dcf_sec=0;dcf_good=0;
+dcfSignalIn.rise(dcfIRQ); //Trigger dcfISR on rising edge of DCF pulse
+while(dcfSignalIn == 1){}
+while(dcfSignalIn == 0){}
+interrupt_counter = 0;sync=1;dcf_sec=0;
+}
+
+void dcfIRQ(void) // DCF Signal Interrupt to synchronise Ticker ISR
+{
+ if (sync==0){
+ Ticker50ms.attach(& dcfISR, .05);
+ interrupt_counter = 0;sync=1;dcf_sec=0;
+ }
+}
+
+void dcfISR() //Interrupt service routine (ISR) that is called every 50ms
+{
+ interrupt_counter++;loop=0;
+
+ dcfLED = !dcfSignalIn; // Show dcf Signal state on LED
+
+ if (interrupt_counter == 20) { // 50mS x 20 = 1000mS = 1 Second
+ interrupt_counter = 0; second++;
+ if (start==1) {dcf_sec++;}
+ }
+ lcd.locate(0,0); lcd.printf("%2d:%02d:%02d.%d Dcf%02d",hour,minute,second,interrupt_counter*5/10,dcf_sec);
+
+ if (dcf_sec==59) {dcf_check();}
+ if (dcf_good==1 && dcf_sec==1) {setTIME();}
+ if (second >= 60) {++minute;second -=60;}
+ if (minute >= 60) {++hour;minute-=60;}
+ if (hour >= 24) {hour -=24;++dayofweek;++dayofmonth;}
+ if (dayofweek > 6) dayofweek = 0;
+ if (dayofmonth > maxDay(year, month)) {dayofmonth = 1;month++;}
+ if (month > 12) {month = 1;year++;}
+ if (year > 99) year = 1;
+ switch (interrupt_counter) {
+ case 1:{ // 50mS after start of second pulse
+ dcf_status.sample50 = (dcfSignalIn);
+ break;}
+ case 3: { // 150mS after start of second pulse (bit "1" dcf Data)
+ dcf_status.sample150 = (dcfSignalIn);
+ if (!dcf_status.sample150 && !dcf_status.sample50) {sync=0;start=1;} // Reset Ticker ISR to line up with 59th second pulse
+ break;}
+ case 6: { // 300mS after start of second (signal error if true)
+ if (dcfSignalIn) {dcf_error = 1;}
+ break;}
+ case 10: { // 500mS after start of second (signal error if true)
+ if (dcfSignalIn) {dcf_error = 1;}
+ break;}
+ case 15: { // 750mS after start of second (signal error if true)
+ if (dcfSignalIn) {dcf_error = 1;}
+ break;}
+ }
+ if (dcf_error==1) {error_count++;dcf_error=0;}
+ if (error_count > 9 && sync==1) {error_count = 0;signal_error=1;}
+} // End of ISR
+
+void dcf_check()
+{
+ parity_calc(); // Get Parity data and test if correct
+ paritycheck= testu or testm or testdmy;
+ if (year>99) paritycheck=1;
+ if (month>12) paritycheck=1;
+ if (day>31) paritycheck=1;
+ if (hour>23) paritycheck=1;
+ if (minute>59) paritycheck=1;
+ if (paritycheck) {
+ dcf_good = 0;
+ }
+ else {
+ dcf_good = 1;
+ }
+}
+
+void RTC_set() // Set cpu RTC to required Time Zone
+{
+ t.tm_sec = (second); // 0-59
+ t.tm_min = (minute); // 0-59
+ t.tm_hour = (hour); // 0-23
+ t.tm_mday = (dayofmonth); // 1-31
+ t.tm_mon = (month-1); // 0-11 DCF "0" = Jan, -1 added for Mbed RCT clock format
+ t.tm_year = ((year)+100); // year since 1900, current DCF year + 100 + 1900 = correct year
+ #if (TimeZone == 1)
+ set_time (mktime(&t)-3600); // set CPU RTC clock to DCF time zone -3600 for GMT
+ #elif (TimeZone==2)
+ set_time (mktime(&t)); // set CPU RTC clock to DCF time zone
+ #elif (TimeZone==3)
+ set_time (mktime(&t)+3600); // set CPU RTC clock to DCF time zone +3600 for EET
+ #endif
+ RTCset=1;getDCF=0;Ticker50ms.detach();dcfSignalIn.rise(NULL);dcfLED=1;lcd.cls();
+ lcd.printf("RTC set, run\n");
+ lcd.printf("Deep Sleep Mode");
+ n=3600*24;
+ wait(3);
+}
+
+void parity_calc()
+{
+//calculate summer/winter time----------------------------------------------------------------------
+ summertime = dcf_array[17] & 1;
+//calculate hour--------------------------------------------------------------------------------------
+ hourh = dcf_array[34] * 20 + dcf_array[33] * 10;
+ hourl = dcf_array[32] * 8 + dcf_array[31] * 4 + dcf_array[30] * 2 + dcf_array[29] * 1;
+ p_hour = hourh + hourl;
+//calculate minutes------------------------------------------------------------------------------------
+ minl = dcf_array[24] * 8 + dcf_array[23] * 4 + dcf_array[22] * 2 + dcf_array[21] * 1;
+ minh = dcf_array[27] * 40 + dcf_array[26] * 20 +dcf_array[25] * 10;
+ p_minute = minh + minl;
+//calculate day of week--------------------------------------------------------------------------------
+ p_dayofweek = dcf_array[44] * 4 +dcf_array[43] * 2 + dcf_array[42] * 1;
+//calculate day----------------------------------------------------------------------------------------
+ dayl = dcf_array[39] * 8 + dcf_array[38] * 4 + dcf_array[37] * 2 + dcf_array[36] * 1;
+ dayh = dcf_array[41] * 20 + dcf_array[40] * 10;
+ p_dayofmonth=dayh+dayl;
+//calculate month--------------------------------------------------------------------------------------
+ monthh = dcf_array[49] * 10;
+ monthl = dcf_array[48] * 8 + dcf_array[47] * 4 + dcf_array[46] * 2 + dcf_array[45] * 1;
+ p_month = monthh +monthl;
+//calculate year---------------------------------------------------------------------------------------
+ yearh = dcf_array[57] * 80 + dcf_array[56] * 40 + dcf_array[55] * 20 + dcf_array[54] * 10;
+ yearl = dcf_array[53] * 8 +dcf_array[52] * 4 + dcf_array[51] * 2 + dcf_array[50] * 1;
+ p_year = yearh+yearl;
+//calculate parity
+ paritym = dcf_array[21] + dcf_array[22] + dcf_array[23] + dcf_array[24] + dcf_array[25] + dcf_array[26] +dcf_array[27] +dcf_array [28];
+ parityu =dcf_array[29] + dcf_array[30] + dcf_array[31] + dcf_array[32] + dcf_array[33] + dcf_array[34] + dcf_array[35];
+ paritydmy =dcf_array[36] + dcf_array [37] + dcf_array [38] + dcf_array [39] + dcf_array[40] + dcf_array[41] + dcf_array [42] + dcf_array [43] + dcf_array[44] + dcf_array [45] + dcf_array[46] + dcf_array [47] + dcf_array[48] + dcf_array[49] + dcf_array[50] + dcf_array[51] + dcf_array [52] + dcf_array[53] + dcf_array[54] + dcf_array[55] + dcf_array[56] + dcf_array[57] + dcf_array[58];
+//test parity------------------------------
+ testu=parityu & 1;
+ testm=paritym & 1;
+ testdmy=paritydmy & 1;
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Feb 26 21:39:57 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/8e73be2a2ac1 \ No newline at end of file