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.
main.cpp
00001 #include "mbed.h" 00002 #include "OLED160G1.h" 00003 00004 OLED160G1 oled(PTD3,PTD2,PTD1);// Oled Display tx, rx, rs 00005 DigitalIn dcfSignalIn(PTE20);//conection to NON inverting output of dcf module 00006 00007 DigitalOut dcfLED (LED1);// dcf signal Pulse 00008 00009 //variable 00010 char paritycheck,paritym,parityu,paritydmy; 00011 char testu,testm,testdmy; 00012 char bit; 00013 char min,minh,minl; 00014 char hourh,hourl; 00015 char w_day; 00016 char day,dayh,dayl; 00017 char monthh,monthl; 00018 char yearh,yearl; 00019 char summertime; 00020 int dcf_array[61]; 00021 00022 //makro,s 00023 void dcf_check(); 00024 void showRtcDate(); 00025 void oled_time_print(); 00026 void bit_map_draw(); 00027 void bit_print(); 00028 void parity_calc(); 00029 void drawgraph(); 00030 void showRTC(); 00031 void showRtcDate(); 00032 void setRTC(); 00033 00034 Timer d; 00035 Ticker Ticker10ms; 00036 00037 #define ZERO 1e-10 00038 #define isBetween(A, B, C) (((A-B) > -ZERO) && ((A-C) < ZERO)) 00039 00040 struct status { 00041 // bool status; // Last minute received OK counts parity test results 00042 bool is_leap; // Leap year flag (NOT actually transmitted but calculated) 00043 bool sample50; // dcf sample at 70mS into the start of the second 00044 bool sample150; // dcf sample at 170mS into the start of the second 00045 int second; // dcf second (NOT actually transmitted but calculated) 00046 } dcf_status; 00047 00048 struct dcf { 00049 char dut1; // DUT1 (0.1 - 0.8) 00050 char dut2; // DUT2 (-0.1 - -0.8) 00051 char year; // Year (00 - 99) 00052 char month; // Month (01 - 12) 00053 char dayofmonth; // Day of month (01 - 31) 00054 char dayofweek; // Day of week (Sunday=0 Saturday=6) 00055 char hour; // Hour (00 - 23) 00056 char minute; // Minute (00 - 59) 00057 } dcf_time; 00058 00059 // Global variables 00060 int in_sec_counter = 0; 00061 int interrupt_counter = 0; 00062 int hour = 12; 00063 int minute = 0; 00064 int second = 0; 00065 int dayofweek = 6; 00066 int dayofmonth = 1; 00067 int month = 1; 00068 int year = 0; 00069 int nosignal; 00070 int start; 00071 int zero_bit; 00072 int dcf_sec; 00073 int s,x,y,r; 00074 int bmd; 00075 int sync; 00076 int p_minute; 00077 int p_hour; 00078 int p_dayofweek; 00079 int p_dayofmonth; 00080 int p_month; 00081 int p_year; 00082 int dcf_error; 00083 int status; 00084 int insecond_counter; 00085 int delay; 00086 int start_delay; 00087 typedef unsigned char byte; 00088 void loop(); 00089 void oled_time_print(); 00090 void showRtcDate(); 00091 void drawgraph(); 00092 void bit_map_draw(); 00093 void set_time(); 00094 void restart(); 00095 00096 // Various text strings used in display 00097 char weekDayName[7][4] = {"Sun","Mon","Tue","Wed","Thu", "Fri","Sat"}; 00098 char monthName[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; 00099 char statusText[5][17] = {"Waiting Sync ","Reading dcf data","Checking Parity ","Last Minute Okay","Signal error "}; 00100 char leapText[2][10] = {" ", "Leap Year"}; 00101 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 00102 00103 // Return the maximum day in month for a given month & year 00104 00105 byte maxDay(byte year, byte month) 00106 { 00107 byte lastday, leap; 00108 leap = year%4 == 0 && year%100 !=0 || year%400 == 0; 00109 lastday = MAX_DAY[month - 1]; 00110 dcf_status.is_leap = leap > 0 ? 1 : 0; 00111 if ((leap > 0) && (month == 2)) 00112 lastday++; 00113 return lastday; 00114 } 00115 00116 int dayOfWeek(int y, int m, int d) // 0 = Sunday 00117 { 00118 static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; 00119 y -= m < 3; 00120 return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7; 00121 } 00122 00123 void myISR() //This is the interrupt service routine (ISR) that is called every 50ms 00124 { 00125 interrupt_counter++; 00126 00127 dcfLED = !dcfSignalIn; // Show dcfSignal state on LED 00128 00129 if (interrupt_counter == 20) { // 50mS x 20 = 1000mS = 1 Second 00130 interrupt_counter = 0; 00131 second++;insecond_counter++; 00132 if (d.read()> 2) {d.reset();d.start();delay=1;} 00133 else {delay=0;} 00134 if (second > 2) {start_delay=0;} 00135 if (dcf_error==1) {status = 4;} 00136 } 00137 if (dcf_sec==58) {status = 2;} 00138 if (dcf_sec==59) {dcf_check();} // check parity 00139 if (status == 3 && dcf_sec == 1) {set_time();} // set DCF clock if good data 00140 00141 if (second >= 60) { 00142 ++minute; 00143 second -=60; 00144 } 00145 if (minute >= 60) { 00146 ++hour; 00147 minute-=60; 00148 } 00149 if (hour >= 24) { 00150 hour -=24; 00151 ++dayofweek; 00152 ++dayofmonth; 00153 } 00154 if (dayofweek > 6) 00155 dayofweek = 0; 00156 00157 if (dayofmonth > maxDay(year, month)) { 00158 dayofmonth = 1; 00159 month++; 00160 } 00161 if (month > 12) { 00162 month = 1; 00163 year++; 00164 } 00165 if (year > 99) 00166 year = 1; 00167 00168 switch (interrupt_counter) { 00169 case 1:{ // 50mS after start of second pulse 00170 dcf_status.sample50 = (dcfSignalIn); 00171 break;} 00172 case 3: { // 150mS after start of second pulse (bit "1" dcf Data) 00173 dcf_status.sample150 = (dcfSignalIn); 00174 if (!dcf_status.sample150 && !dcf_status.sample50 && start_delay==0) {zero_bit=1;sync=0;insecond_counter=0;start=1;} 00175 else {zero_bit=0;} 00176 break;} 00177 case 6: { // 300mS after start of second (signal error if true) 00178 if (status == 3 && dcf_sec == 1) {setRTC();} // set RTC clock if good data 00179 if (dcfSignalIn) {dcf_error = 1;} 00180 break;} 00181 case 10: { // 500mS after start of second (signal error if true) 00182 if (dcfSignalIn) {dcf_error = 1;} 00183 break;} 00184 case 12: { // 600mS after start of second (signal error if true) 00185 if (dcfSignalIn) {dcf_error = 1;} 00186 break;} 00187 } 00188 00189 if (interrupt_counter==1) 00190 { 00191 if (dcfSignalIn){nosignal=1;} 00192 else nosignal++; 00193 if (nosignal>5){nosignal=2; status = 0; restart();} 00194 if (dcf_error == 1 && delay == 1) {dcf_error = 0; status = 0;restart();} 00195 } 00196 if (interrupt_counter==3) 00197 { 00198 oled.locate(18,4);oled.setFontColor(oled.toRGB(0,0,255)); 00199 oled.printf("Bit %d",dcf_status.sample150); 00200 if (start==0) {oled.drawText(18,13,(OLED_FONT5X7),"No Sync ",oled.toRGB(255,0,0));} 00201 00202 if (start==1) 00203 { 00204 dcf_array[dcf_sec]=dcf_status.sample150; 00205 oled.drawText(18,13,(OLED_FONT5X7),"In Sync ",oled.toRGB(0,255,0)); 00206 if (insecond_counter==1) 00207 { 00208 dcf_sec=0;x=0;y=5;dcf_array[58] = 0; bmd=0; 00209 if (r == 1){r=0;} 00210 else {r=1;} 00211 } 00212 if (dcf_sec > 2) {status = 1;} 00213 if (dcf_sec > 20 && dcf_sec < 59 ) {bit_print();} 00214 if (dcf_sec > 60) {dcf_error = 1;bit_map_draw();status = 4;dcf_sec=0;dcf_error = 0;} 00215 if (sync==1) {dcf_sec++;} 00216 } 00217 } 00218 if (sync==0) { 00219 if (dcfSignalIn) {interrupt_counter =0 ;sync=1;} // synchronise interrupt counter to DCF sync pulse 00220 } 00221 } // End of ISR 00222 00223 int main() 00224 { 00225 oled.init(); 00226 oled.eraseScreen(); 00227 oled.setTextBackgroundType(OLED_SET_TEXT_OPAQUE); 00228 oled.drawText(1,1,(OLED_FONT8X12),"DCF77 Atomic Clock",oled.toRGB(255,0,0)); 00229 oled.drawText(1,3,(OLED_FONT8X12)," Freescale KL25Z",oled.toRGB(0,255,0)); 00230 oled.drawText(1,5,(OLED_FONT8X12)," 4D Systems",oled.toRGB(0,0,255)); 00231 oled.drawText(1,7,(OLED_FONT8X12)," Oled160 Display",oled.toRGB(255,255,0)); 00232 wait(1); 00233 oled.eraseScreen();bit_map_draw(); 00234 oled.drawText(17,6,(OLED_FONT5X7),"DCF Time",oled.toRGB(255,255,0)); 00235 dcf_sec=0;bmd=1;start=0;zero_bit=0;r = 1; 00236 status = 0; start_delay=1; 00237 d.start();showRtcDate(); 00238 if (dcfSignalIn) {interrupt_counter =0 ;sync=1;} 00239 Ticker10ms.attach(& myISR, .05 ); //Setup Ticker to call myISR every 50 ms 00240 00241 while (true) { 00242 loop(); // Continuously get dcf time and Display data interrupted by the Ticker every 50ms 00243 } 00244 } 00245 00246 void dcf_check() 00247 { 00248 parity_calc(); 00249 paritycheck= testu or testm or testdmy; 00250 if (year>99) paritycheck=1; 00251 if (month>12) paritycheck=1; 00252 if (day>31) paritycheck=1; 00253 if (hour>23) paritycheck=1; 00254 if (min>59) paritycheck=1; 00255 if (paritycheck) { 00256 status = 4; // bad parity 00257 } 00258 else { 00259 status = 3; // good parity 00260 } 00261 } 00262 00263 void bit_print() 00264 { 00265 if (r==1) {oled.setFontColor(oled.toRGB(255,0,255));} // alternate bit draw colour 00266 else {oled.setFontColor(oled.toRGB(255,255,255));} 00267 oled.locate(x+3,(y+1)); 00268 oled.printf("%d",dcf_status.sample150); 00269 (y)++; 00270 if ((dcf_sec)==27){(y)=13;} 00271 if ((dcf_sec)==28){(y)=5;(x)=(x)+2;oled.printf(" ");} 00272 if ((dcf_sec)==34){(y)=13;} 00273 if ((dcf_sec)==35){(y)=5;(x)=(x)+2;} 00274 if ((dcf_sec)==41){(y)=5;(x)=(x)+2;} 00275 if ((dcf_sec)==44){(y)=5;(x)=(x)+2;} 00276 if ((dcf_sec)==49){(y)=5;(x)=(x)+2;} 00277 } 00278 00279 void bit_map_draw() 00280 { 00281 (x)=0,(y)=4; 00282 oled.drawText(x,y,(OLED_FONT5X7)," M H D d M Y",oled.toRGB(255,255,0)); 00283 y++; 00284 oled.drawText(x,y+1,(OLED_FONT5X7)," 1 i o a a o e",oled.toRGB(255,255,0)); 00285 oled.drawText(x,y+2,(OLED_FONT5X7)," 2 n u t y n a",oled.toRGB(255,255,0)); 00286 oled.drawText(x,y+3,(OLED_FONT5X7)," 4 u r e t r",oled.toRGB(255,255,0)); 00287 oled.drawText(x,y+4,(OLED_FONT5X7)," 8 t h ",oled.toRGB(255,255,0)); 00288 oled.drawText(x,y+5,(OLED_FONT5X7),"10 e ",oled.toRGB(255,255,0)); 00289 oled.drawText(x,y+6,(OLED_FONT5X7),"20 ",oled.toRGB(255,255,0)); 00290 oled.drawText(x,y+7,(OLED_FONT5X7),"40 ",oled.toRGB(255,255,0)); 00291 oled.drawText(x,y+8,(OLED_FONT5X7),"80 ",oled.toRGB(255,255,0)); 00292 oled.drawText(x,y+9,(OLED_FONT5X7)," P arity ",oled.toRGB(255,255,0)); 00293 oled.drawLine(2,43,85,43, oled.toRGB(255, 0, 0)); 00294 oled.drawLine(14,33,14,118, oled.toRGB(255, 0, 0)); 00295 } 00296 void showClock() 00297 { 00298 oled.setFontSize(OLED_FONT5X7); 00299 oled.locate(17,8);oled.setFontColor(oled.toRGB(255,255,255)); 00300 oled.printf("%02d:%02d:%02d", hour, minute, second); 00301 oled.locate(17,9); 00302 oled.printf("%02d/%02d/%02d",dayofmonth,month,year); 00303 if (summertime) {oled.drawText(17,10,(OLED_FONT5X7),"Summer",oled.toRGB(255,100,100));} 00304 else {oled.drawText(17,10,(OLED_FONT5X7),"Winter",oled.toRGB(0,255,255));} 00305 oled.drawText(17,11,(OLED_FONT5X7),leapText[dcf_status.is_leap],oled.toRGB(0,255,160)); 00306 if (status==0) {oled.drawText(5,15,(OLED_FONT5X7),statusText[status],oled.toRGB(255,255,255));} 00307 if (status==1) {oled.drawText(5,15,(OLED_FONT5X7),statusText[status],oled.toRGB(0,255,255));} 00308 if (status==2) {oled.drawText(5,15,(OLED_FONT5X7),statusText[status],oled.toRGB(0,0,255));} 00309 if (status==3) {oled.drawText(5,15,(OLED_FONT5X7),statusText[status],oled.toRGB(0,255,0));} 00310 if (status==4) {oled.drawText(5,15,(OLED_FONT5X7),statusText[status],oled.toRGB(255,0,0));} 00311 } 00312 void loop() 00313 { 00314 if (interrupt_counter == 0) { // refresh local time at the first 50mS of every second 00315 showClock(); 00316 showRTC(); 00317 oled.setFontSize(OLED_FONT5X7); 00318 oled.locate(9,12);oled.setFontColor(oled.toRGB(255,255,255));oled.printf("%02d",dcf_sec); 00319 oled.setFontSize(OLED_FONT5X7); 00320 } 00321 } 00322 00323 void showRTC() 00324 { 00325 time_t seconds = time(NULL); 00326 char buffer[40]; 00327 strftime(buffer, 40, "%I:%M:%S %p", localtime(&seconds)); 00328 oled.drawText(1,0,(OLED_FONT8X12),buffer,oled.toRGB(255,255,255)); 00329 } 00330 00331 void showRtcDate() 00332 { 00333 time_t seconds = time(NULL); 00334 char buffer[40]; 00335 strftime(buffer, 40, "%a %d %b %Y", localtime(&seconds)); 00336 oled.drawText(1,1,(OLED_FONT8X12),buffer,oled.toRGB(255,255,255)); 00337 } 00338 00339 void setRTC() 00340 { 00341 //Mbed rtc clock set 00342 struct tm t; 00343 t.tm_sec = (second-1); // 0-59 00344 t.tm_min = (minute); // 0-59 00345 t.tm_hour = (hour); // 0-23 00346 t.tm_mday = (dayofmonth); // 1-31 00347 t.tm_mon = (month-1); // 0-11 DCF "0" = Jan, -1 added for Mbed RCT clock format 00348 t.tm_year = ((year)+100); // year since 1900, current DCF year + 100 + 1900 = correct year 00349 set_time(mktime(&t)-3600); 00350 time_t seconds = mktime(&t); 00351 showRtcDate(); // Print DATE once per minute 00352 if (summertime==0) {oled.drawText(19,0,(OLED_FONT5X7),"Winter",oled.toRGB(0,255,255));} 00353 else {oled.drawText(19,0,(OLED_FONT5X7),"Summer",oled.toRGB(255,128,128));} 00354 00355 } 00356 00357 void set_time() 00358 { 00359 second = dcf_sec; 00360 minute=p_minute; 00361 hour=p_hour; 00362 dayofweek=p_dayofweek; 00363 dayofmonth=p_dayofmonth; 00364 month=p_month; 00365 year=p_year; 00366 } 00367 00368 void restart() 00369 { 00370 start=0;s=0;x=0;y=5;dcf_sec=0;dcf_error=0; 00371 insecond_counter=0;zero_bit=0;start_delay=1; 00372 } 00373 00374 void parity_calc() 00375 { 00376 //calculate summer/winter time---------------------------------------------------------------------- 00377 summertime = dcf_array[17] & 1; 00378 //calculate hour-------------------------------------------------------------------------------------- 00379 hourh = dcf_array[34] * 20 + dcf_array[33] * 10; 00380 hourl = dcf_array[32] * 8 + dcf_array[31] * 4 + dcf_array[30] * 2 + dcf_array[29] * 1; 00381 p_hour = hourh + hourl; 00382 //calculate minutes------------------------------------------------------------------------------------ 00383 minl = dcf_array[24] * 8 + dcf_array[23] * 4 + dcf_array[22] * 2 + dcf_array[21] * 1; 00384 minh = dcf_array[27] * 40 + dcf_array[26] * 20 +dcf_array[25] * 10; 00385 p_minute = minh + minl; 00386 //calculate day of week-------------------------------------------------------------------------------- 00387 p_dayofweek = dcf_array[44] * 4 +dcf_array[43] * 2 + dcf_array[42] * 1; 00388 //calculate day---------------------------------------------------------------------------------------- 00389 dayl = dcf_array[39] * 8 + dcf_array[38] * 4 + dcf_array[37] * 2 + dcf_array[36] * 1; 00390 dayh = dcf_array[41] * 20 + dcf_array[40] * 10; 00391 p_dayofmonth=dayh+dayl; 00392 //calculate month-------------------------------------------------------------------------------------- 00393 monthh = dcf_array[49] * 10; 00394 monthl = dcf_array[48] * 8 + dcf_array[47] * 4 + dcf_array[46] * 2 + dcf_array[45] * 1; 00395 p_month = monthh +monthl; 00396 //calculate year--------------------------------------------------------------------------------------- 00397 yearh = dcf_array[57] * 80 + dcf_array[56] * 40 + dcf_array[55] * 20 + dcf_array[54] * 10; 00398 yearl = dcf_array[53] * 8 +dcf_array[52] * 4 + dcf_array[51] * 2 + dcf_array[50] * 1; 00399 p_year = yearh+yearl; 00400 //calculate parity 00401 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]; 00402 parityu =dcf_array[29] + dcf_array[30] + dcf_array[31] + dcf_array[32] + dcf_array[33] + dcf_array[34] + dcf_array[35]; 00403 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]; 00404 //test parity------------------------------ 00405 testu=parityu & 1; 00406 testm=paritym & 1; 00407 testdmy=paritydmy & 1; 00408 } 00409
Generated on Sun Jul 24 2022 01:41:43 by
1.7.2