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.
Revision 0:89274444b840, committed 2013-03-08
- Comitter:
- star297
- Date:
- Fri Mar 08 21:00:45 2013 +0000
- Child:
- 1:cad87f63a115
- Commit message:
- Update for Leap year
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NokiaLCD_X3.lib Fri Mar 08 21:00:45 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/star297/code/DCF77_Atomic_Clock_Nokia_Display/#af10e3629210
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Fri Mar 08 21:00:45 2013 +0000
@@ -0,0 +1,368 @@
+#include "mbed.h"
+#include "MobileLCD.h"
+
+MobileLCD lcd(p5, p6, p7, p8, p9);
+DigitalIn dcfSignalIn(p21);//conection to NON inverting output of dcf module
+DigitalOut dcfLED (LED1);//received DCF signal
+
+//variable
+char paritycheck,paritym,parityu,paritydmy;
+char testu,testm,testdmy;
+char min,minh,minl;
+char hourh,hourl;
+char w_day;
+char day,dayh,dayl;
+char monthh,monthl;
+char yearh,yearl;
+char summertime;
+int dcf_array[61];
+
+//makro,s
+void getbit();
+void dcf_check();
+void lcd_date_print();
+void lcd_time_print();
+void bit_map_draw();
+void bit_print();
+void parity_calc();
+void reset_rtc();
+void local_time();
+void set_rtc();
+void s_display();
+void drawgraph();
+
+Timer d;
+Ticker Ticker10ms;
+
+#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;
+
+// Global variables
+int in_sec_counter = 0;
+int interrupt_counter = 0;
+int hour = 12;
+int minute = 0;
+int second = 0;
+int dayofweek = 6;
+int dayofmonth = 1;
+int month = 1;
+int year = 0;
+int nosignal;
+int start;
+int zero_bit;
+int dcf_sec;
+int s,x,y,r;
+int bmd;
+int sync;
+int p_minute;
+int p_hour;
+int p_dayofweek;
+int p_dayofmonth;
+int p_month;
+int p_year;
+int dcf_error;
+int status;
+int insecond_counter;
+int delay;
+int start_delay;
+typedef unsigned char byte;
+void loop();
+void oled_time_print();
+void oled_date_print();
+void drawgraph();
+void bit_map_draw();
+void set_time();
+void restart();
+
+// 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 statusText[5][17] = {"Waiting Sync ","Reading dcf data","Checking Parity ","Last Minute Okay","Signal error "};
+char leapText[2][10] = {" ", "L"};
+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
+
+// Return the maximum day in month for a given month & year
+
+byte maxDay(byte year, byte month)
+{
+ 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;
+}
+
+void myISR() //This is the interrupt service routine (ISR) that is called every 50ms
+{
+ interrupt_counter++;
+
+ dcfLED = dcfSignalIn; // Show dcfSignal state on LED
+
+ if (interrupt_counter == 20) { // 50mS x 20 = 1000mS = 1 Second
+ interrupt_counter = 0;
+ second++;insecond_counter++;
+ if (d.read()> 2) {d.reset();d.start();delay=1;}
+ else {delay=0;}
+ if (second > 2) {start_delay=0;}
+ if (dcf_error==1) {status = 4;}
+ }
+ if (dcf_sec==58) {status = 2;}
+ if (dcf_sec==59) {dcf_check();}
+ if (status == 3 && dcf_sec == 1) {set_time();}
+
+ 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 && start_delay==0) {zero_bit=1;sync=0;insecond_counter=0;start=1;}
+ else {zero_bit=0;}
+ 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 12: { // 600mS after start of second (signal error if true)
+ if (dcfSignalIn) {dcf_error = 1;}
+ break;}
+ }
+ if (interrupt_counter==1)
+ {
+ if (dcfSignalIn){nosignal=1;}
+ else nosignal++;
+ if (nosignal>5){nosignal=2; status = 0; restart();}
+ if (dcf_error == 1 && delay == 1) {dcf_error = 0; status = 0;restart();}
+ }
+ if (interrupt_counter==3)
+ {
+ lcd.locate(0,4); lcd.foreground (CYAN);
+ lcd.printf("Bit %d ",dcf_status.sample150);
+ if (start==0) {lcd.foreground (RED);lcd.printf("No Sync ");}
+ if (start==1)
+ {
+ dcf_array[dcf_sec]=dcf_status.sample150;
+ lcd.foreground (GREEN);
+ lcd.printf("In Sync ");
+ if (insecond_counter==1)
+ {
+ dcf_sec=0;x=0;y=5;dcf_array[58] = 0; bmd=0;
+ if (r == 1){r=0;}
+ else {r=1;}
+ }
+ if (dcf_sec > 2) {status = 1;}
+ if (dcf_sec > 20 && dcf_sec < 59 ) {bit_print();}
+ if (dcf_sec > 60) {dcf_error = 1;bit_map_draw();status = 4;dcf_sec=0;dcf_error = 0;}
+ if (sync==1) {dcf_sec++;}
+ }
+ }
+ if (sync==0) {
+ if (dcfSignalIn) {interrupt_counter =0 ;sync=1;}
+ }
+} // End of ISR
+
+int main()
+{
+ lcd.locate (1,2);
+ lcd.foreground (WHITE);
+ lcd.printf("DCF77 Clock");
+ lcd.locate (1,4);
+ lcd.printf("Nokia 6610 LCD");
+ lcd.locate (1,6);
+ lcd.printf("Signal pin 21");
+ wait (5);lcd.cls();r = 1;
+ bit_map_draw();dcf_sec=0;bmd=1;start=0;zero_bit=0;
+ status = 0; start_delay=1;
+ d.start();
+ if (dcfSignalIn) {interrupt_counter =0 ;sync=1;}
+ Ticker10ms.attach(& myISR, .05 ); //Setup Ticker to call myISR every 50 ms
+
+ while (true) {
+ loop(); // Continuously get dcf time and Display data interrupted by the Ticker every 50ms
+ }
+}
+
+void dcf_check()
+{
+ parity_calc();
+ 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 (min>59) paritycheck=1;
+ if (paritycheck) {
+ status = 4;
+ }
+ else {
+ status = 3;
+ }
+}
+void showClock()
+{
+ lcd.locate(0,0);lcd.foreground (WHITE);
+ lcd.printf("%02d:%02d:%02d", hour, minute, second);
+ lcd.locate(0,1);
+ lcd.printf("%s %02d %s'20%02d", weekDayName[dayofweek], dayofmonth, monthName[month-1], year);
+ lcd.locate(0,2);
+ if (summertime) {lcd.foreground (RED);lcd.printf("Summer Time");}
+ else {lcd.foreground (BLUE);lcd.printf("Winter Time");}
+ if (dcf_status.is_leap){lcd.foreground (RED);lcd.printf(" %d"),leapText[dcf_status.is_leap];}
+ if (status==0) {lcd.foreground (WHITE);}
+ if (status==1) {lcd.foreground (CYAN);}
+ if (status==2) {lcd.foreground (BLUE);}
+ if (status==3) {lcd.foreground (GREEN);}
+ if (status==4) {lcd.foreground (RED);}
+ lcd.locate(0,15);
+ lcd.printf(statusText[status]);
+}
+
+void bit_print()
+{
+ if (r==1) {lcd.foreground (MAGENTA);} // alternate bit draw colour
+ else {lcd.foreground (WHITE);}
+ lcd.locate(x+3,(y+1));
+ lcd.printf("%d",dcf_status.sample150);
+ (y)++;
+ if ((dcf_sec)==27){(y)=13;}
+ if ((dcf_sec)==28){(y)=5;(x)=(x)+2;lcd.printf(" ");}
+ if ((dcf_sec)==34){(y)=13;}
+ if ((dcf_sec)==35){(y)=5;(x)=(x)+2;}
+ if ((dcf_sec)==41){(y)=5;(x)=(x)+2;}
+ if ((dcf_sec)==44){(y)=5;(x)=(x)+2;}
+ if ((dcf_sec)==49){(y)=5;(x)=(x)+2;}
+}
+
+void bit_map_draw()
+{
+ lcd.foreground (YELLOW);(x)=0,(y)=5;
+ lcd.locate(x,y);lcd.printf(" M H D d M Y");
+ lcd.locate(x,y+1);lcd.printf(" 1 i o a a o e");
+ lcd.locate(x,y+2);lcd.printf(" 2 n u t y n a");
+ lcd.locate(x,y+3);lcd.printf(" 4 u r e t r");
+ lcd.locate(x,y+4);lcd.printf(" 8 t h ");
+ lcd.locate(x,y+5);lcd.printf("10 e ");
+ lcd.locate(x,y+6);lcd.printf("20 ");
+ lcd.locate(x,y+7);lcd.printf("40 ");
+ lcd.locate(x,y+8);lcd.printf("80 ");
+ lcd.locate(x,y+9);lcd.printf(" P arity ");
+}
+
+void loop()
+{
+ if (interrupt_counter == 0) {
+ showClock();
+ lcd.locate(10,12);lcd.foreground (WHITE);lcd.printf("%02d",dcf_sec);
+ }
+ }
+
+void set_time()
+{
+ second = dcf_sec;
+ minute=p_minute;
+ hour=p_hour;
+ dayofweek=p_dayofweek;
+ dayofmonth=p_dayofmonth;
+ month=p_month;
+ year=p_year;
+}
+
+void restart()
+{
+start=0;s=0;x=0;y=5;dcf_sec=0;dcf_error=0;
+insecond_counter=0;zero_bit=0;start_delay=1;
+}
+
+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 Fri Mar 08 21:00:45 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/5e5da4a5990b \ No newline at end of file