DCF77 Atomic clock using Nokia 6610 colour LCD display. This will continue to run with no signal and shows a graphic bit map display demonstrating the time build. Does not use the Mbed RTC so will run on the LPC11U24. The main signal timing is achieved by using a Ticker ISR that looks at the DCF signal input every 50mS this also produces the seconds on the local clock incase of signal errors or no signal. Many thanks to Lynton Towler for the idea of this part of the code and Wim who helped me convert it from an Arduino program. The Parity code was fromHans program that works.

Dependencies:   mbed

/media/uploads/star297/_scaled_20130306_221042.jpg

Re published due to error in title.

I have also updated the 'Leap' year print code as that was incorrect.

This program works on the both Mbed's (LPC1768 and LPC11U24)

Committer:
star297
Date:
Tue Mar 19 11:25:13 2013 +0000
Revision:
2:31f5b5d56af6
Parent:
0:89274444b840
Leap indicator correction

Who changed what in which revision?

UserRevisionLine numberNew contents of line
star297 0:89274444b840 1 #include "mbed.h"
star297 0:89274444b840 2 #include "MobileLCD.h"
star297 0:89274444b840 3
star297 0:89274444b840 4 MobileLCD lcd(p5, p6, p7, p8, p9);
star297 0:89274444b840 5 DigitalIn dcfSignalIn(p21);//conection to NON inverting output of dcf module
star297 0:89274444b840 6 DigitalOut dcfLED (LED1);//received DCF signal
star297 0:89274444b840 7
star297 0:89274444b840 8 //variable
star297 0:89274444b840 9 char paritycheck,paritym,parityu,paritydmy;
star297 0:89274444b840 10 char testu,testm,testdmy;
star297 0:89274444b840 11 char min,minh,minl;
star297 0:89274444b840 12 char hourh,hourl;
star297 0:89274444b840 13 char w_day;
star297 0:89274444b840 14 char day,dayh,dayl;
star297 0:89274444b840 15 char monthh,monthl;
star297 0:89274444b840 16 char yearh,yearl;
star297 0:89274444b840 17 char summertime;
star297 0:89274444b840 18 int dcf_array[61];
star297 0:89274444b840 19
star297 0:89274444b840 20 //makro,s
star297 0:89274444b840 21 void getbit();
star297 0:89274444b840 22 void dcf_check();
star297 0:89274444b840 23 void lcd_date_print();
star297 0:89274444b840 24 void lcd_time_print();
star297 0:89274444b840 25 void bit_map_draw();
star297 0:89274444b840 26 void bit_print();
star297 0:89274444b840 27 void parity_calc();
star297 0:89274444b840 28 void reset_rtc();
star297 0:89274444b840 29 void local_time();
star297 0:89274444b840 30 void set_rtc();
star297 0:89274444b840 31 void s_display();
star297 0:89274444b840 32 void drawgraph();
star297 0:89274444b840 33
star297 0:89274444b840 34 Timer d;
star297 0:89274444b840 35 Ticker Ticker10ms;
star297 0:89274444b840 36
star297 0:89274444b840 37 #define ZERO 1e-10
star297 0:89274444b840 38 #define isBetween(A, B, C) (((A-B) > -ZERO) && ((A-C) < ZERO))
star297 0:89274444b840 39
star297 0:89274444b840 40 struct status {
star297 0:89274444b840 41 bool is_leap; // Leap year flag (NOT actually transmitted but calculated)
star297 0:89274444b840 42 bool sample50; // dcf sample at 50mS into the start of the second
star297 0:89274444b840 43 bool sample150; // dcf sample at 150mS into the start of the second
star297 0:89274444b840 44 int second; // dcf second (NOT actually transmitted but calculated)
star297 0:89274444b840 45 }
star297 0:89274444b840 46 dcf_status;
star297 0:89274444b840 47
star297 0:89274444b840 48 struct dcf {
star297 0:89274444b840 49 char dut1; // DUT1 (0.1 - 0.8)
star297 0:89274444b840 50 char dut2; // DUT2 (-0.1 - -0.8)
star297 0:89274444b840 51 char year; // Year (00 - 99)
star297 0:89274444b840 52 char month; // Month (01 - 12)
star297 0:89274444b840 53 char dayofmonth; // Day of month (01 - 31)
star297 0:89274444b840 54 char dayofweek; // Day of week (Sunday=0 Saturday=6)
star297 0:89274444b840 55 char hour; // Hour (00 - 23)
star297 0:89274444b840 56 char minute; // Minute (00 - 59)
star297 0:89274444b840 57 } dcf_time;
star297 0:89274444b840 58
star297 0:89274444b840 59 // Global variables
star297 0:89274444b840 60 int in_sec_counter = 0;
star297 0:89274444b840 61 int interrupt_counter = 0;
star297 0:89274444b840 62 int hour = 12;
star297 0:89274444b840 63 int minute = 0;
star297 0:89274444b840 64 int second = 0;
star297 0:89274444b840 65 int dayofweek = 6;
star297 0:89274444b840 66 int dayofmonth = 1;
star297 0:89274444b840 67 int month = 1;
star297 0:89274444b840 68 int year = 0;
star297 0:89274444b840 69 int nosignal;
star297 0:89274444b840 70 int start;
star297 0:89274444b840 71 int zero_bit;
star297 0:89274444b840 72 int dcf_sec;
star297 0:89274444b840 73 int s,x,y,r;
star297 0:89274444b840 74 int bmd;
star297 0:89274444b840 75 int sync;
star297 0:89274444b840 76 int p_minute;
star297 0:89274444b840 77 int p_hour;
star297 0:89274444b840 78 int p_dayofweek;
star297 0:89274444b840 79 int p_dayofmonth;
star297 0:89274444b840 80 int p_month;
star297 0:89274444b840 81 int p_year;
star297 0:89274444b840 82 int dcf_error;
star297 0:89274444b840 83 int status;
star297 0:89274444b840 84 int insecond_counter;
star297 0:89274444b840 85 int delay;
star297 0:89274444b840 86 int start_delay;
star297 0:89274444b840 87 typedef unsigned char byte;
star297 0:89274444b840 88 void loop();
star297 0:89274444b840 89 void oled_time_print();
star297 0:89274444b840 90 void oled_date_print();
star297 0:89274444b840 91 void drawgraph();
star297 0:89274444b840 92 void bit_map_draw();
star297 0:89274444b840 93 void set_time();
star297 0:89274444b840 94 void restart();
star297 0:89274444b840 95
star297 0:89274444b840 96 // Various text strings used in display
star297 0:89274444b840 97 char weekDayName[7][4] = {"Sun","Mon","Tue","Wed","Thu", "Fri","Sat"};
star297 0:89274444b840 98 char monthName[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
star297 0:89274444b840 99 char statusText[5][17] = {"Waiting Sync ","Reading dcf data","Checking Parity ","Last Minute Okay","Signal error "};
star297 2:31f5b5d56af6 100 char leapText[2][10] = {" ", "Leap"};
star297 0:89274444b840 101 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
star297 0:89274444b840 102
star297 0:89274444b840 103 // Return the maximum day in month for a given month & year
star297 0:89274444b840 104
star297 0:89274444b840 105 byte maxDay(byte year, byte month)
star297 0:89274444b840 106 {
star297 0:89274444b840 107 byte lastday, leap;
star297 0:89274444b840 108 leap = year%4 == 0 && year%100 !=0 || year%400 == 0;
star297 0:89274444b840 109 lastday = MAX_DAY[month - 1];
star297 0:89274444b840 110 dcf_status.is_leap = leap > 0 ? 1 : 0;
star297 0:89274444b840 111 if ((leap > 0) && (month == 2))
star297 0:89274444b840 112 lastday++;
star297 0:89274444b840 113 return lastday;
star297 0:89274444b840 114 }
star297 0:89274444b840 115
star297 0:89274444b840 116 int dayOfWeek(int y, int m, int d) // 0 = Sunday
star297 0:89274444b840 117 {
star297 0:89274444b840 118 static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
star297 0:89274444b840 119 y -= m < 3;
star297 0:89274444b840 120 return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
star297 0:89274444b840 121 }
star297 0:89274444b840 122
star297 0:89274444b840 123 void myISR() //This is the interrupt service routine (ISR) that is called every 50ms
star297 0:89274444b840 124 {
star297 0:89274444b840 125 interrupt_counter++;
star297 0:89274444b840 126
star297 0:89274444b840 127 dcfLED = dcfSignalIn; // Show dcfSignal state on LED
star297 0:89274444b840 128
star297 0:89274444b840 129 if (interrupt_counter == 20) { // 50mS x 20 = 1000mS = 1 Second
star297 0:89274444b840 130 interrupt_counter = 0;
star297 0:89274444b840 131 second++;insecond_counter++;
star297 0:89274444b840 132 if (d.read()> 2) {d.reset();d.start();delay=1;}
star297 0:89274444b840 133 else {delay=0;}
star297 0:89274444b840 134 if (second > 2) {start_delay=0;}
star297 0:89274444b840 135 if (dcf_error==1) {status = 4;}
star297 0:89274444b840 136 }
star297 0:89274444b840 137 if (dcf_sec==58) {status = 2;}
star297 0:89274444b840 138 if (dcf_sec==59) {dcf_check();}
star297 0:89274444b840 139 if (status == 3 && dcf_sec == 1) {set_time();}
star297 0:89274444b840 140
star297 0:89274444b840 141 if (second >= 60) {
star297 0:89274444b840 142 ++minute;
star297 0:89274444b840 143 second -=60;
star297 0:89274444b840 144 }
star297 0:89274444b840 145 if (minute >= 60) {
star297 0:89274444b840 146 ++hour;
star297 0:89274444b840 147 minute-=60;
star297 0:89274444b840 148 }
star297 0:89274444b840 149 if (hour >= 24) {
star297 0:89274444b840 150 hour -=24;
star297 0:89274444b840 151 ++dayofweek;
star297 0:89274444b840 152 ++dayofmonth;
star297 0:89274444b840 153 }
star297 0:89274444b840 154 if (dayofweek > 6)
star297 0:89274444b840 155 dayofweek = 0;
star297 0:89274444b840 156
star297 0:89274444b840 157 if (dayofmonth > maxDay(year, month)) {
star297 0:89274444b840 158 dayofmonth = 1;
star297 0:89274444b840 159 month++;
star297 0:89274444b840 160 }
star297 0:89274444b840 161 if (month > 12) {
star297 0:89274444b840 162 month = 1;
star297 0:89274444b840 163 year++;
star297 0:89274444b840 164 }
star297 0:89274444b840 165 if (year > 99)
star297 0:89274444b840 166 year = 1;
star297 0:89274444b840 167
star297 0:89274444b840 168 switch (interrupt_counter) {
star297 0:89274444b840 169 case 1:{ // 50mS after start of second pulse
star297 0:89274444b840 170 dcf_status.sample50 = (dcfSignalIn);
star297 0:89274444b840 171 break;}
star297 0:89274444b840 172 case 3: { // 150mS after start of second pulse (bit "1" dcf Data)
star297 0:89274444b840 173 dcf_status.sample150 = (dcfSignalIn);
star297 0:89274444b840 174 if (!dcf_status.sample150 && !dcf_status.sample50 && start_delay==0) {zero_bit=1;sync=0;insecond_counter=0;start=1;}
star297 0:89274444b840 175 else {zero_bit=0;}
star297 0:89274444b840 176 break;}
star297 0:89274444b840 177 case 6: { // 300mS after start of second (signal error if true)
star297 0:89274444b840 178 if (dcfSignalIn) {dcf_error = 1;}
star297 0:89274444b840 179 break;}
star297 0:89274444b840 180 case 10: { // 500mS after start of second (signal error if true)
star297 0:89274444b840 181 if (dcfSignalIn) {dcf_error = 1;}
star297 0:89274444b840 182 break;}
star297 0:89274444b840 183 case 12: { // 600mS after start of second (signal error if true)
star297 0:89274444b840 184 if (dcfSignalIn) {dcf_error = 1;}
star297 0:89274444b840 185 break;}
star297 0:89274444b840 186 }
star297 0:89274444b840 187 if (interrupt_counter==1)
star297 0:89274444b840 188 {
star297 0:89274444b840 189 if (dcfSignalIn){nosignal=1;}
star297 0:89274444b840 190 else nosignal++;
star297 0:89274444b840 191 if (nosignal>5){nosignal=2; status = 0; restart();}
star297 0:89274444b840 192 if (dcf_error == 1 && delay == 1) {dcf_error = 0; status = 0;restart();}
star297 0:89274444b840 193 }
star297 0:89274444b840 194 if (interrupt_counter==3)
star297 0:89274444b840 195 {
star297 0:89274444b840 196 lcd.locate(0,4); lcd.foreground (CYAN);
star297 0:89274444b840 197 lcd.printf("Bit %d ",dcf_status.sample150);
star297 0:89274444b840 198 if (start==0) {lcd.foreground (RED);lcd.printf("No Sync ");}
star297 0:89274444b840 199 if (start==1)
star297 0:89274444b840 200 {
star297 0:89274444b840 201 dcf_array[dcf_sec]=dcf_status.sample150;
star297 0:89274444b840 202 lcd.foreground (GREEN);
star297 0:89274444b840 203 lcd.printf("In Sync ");
star297 0:89274444b840 204 if (insecond_counter==1)
star297 0:89274444b840 205 {
star297 0:89274444b840 206 dcf_sec=0;x=0;y=5;dcf_array[58] = 0; bmd=0;
star297 0:89274444b840 207 if (r == 1){r=0;}
star297 0:89274444b840 208 else {r=1;}
star297 0:89274444b840 209 }
star297 0:89274444b840 210 if (dcf_sec > 2) {status = 1;}
star297 0:89274444b840 211 if (dcf_sec > 20 && dcf_sec < 59 ) {bit_print();}
star297 0:89274444b840 212 if (dcf_sec > 60) {dcf_error = 1;bit_map_draw();status = 4;dcf_sec=0;dcf_error = 0;}
star297 0:89274444b840 213 if (sync==1) {dcf_sec++;}
star297 0:89274444b840 214 }
star297 0:89274444b840 215 }
star297 2:31f5b5d56af6 216 if (sync==0 ) {
star297 0:89274444b840 217 if (dcfSignalIn) {interrupt_counter =0 ;sync=1;}
star297 0:89274444b840 218 }
star297 0:89274444b840 219 } // End of ISR
star297 0:89274444b840 220
star297 0:89274444b840 221 int main()
star297 0:89274444b840 222 {
star297 0:89274444b840 223 lcd.locate (1,2);
star297 0:89274444b840 224 lcd.foreground (WHITE);
star297 0:89274444b840 225 lcd.printf("DCF77 Clock");
star297 0:89274444b840 226 lcd.locate (1,4);
star297 0:89274444b840 227 lcd.printf("Nokia 6610 LCD");
star297 0:89274444b840 228 lcd.locate (1,6);
star297 0:89274444b840 229 lcd.printf("Signal pin 21");
star297 0:89274444b840 230 wait (5);lcd.cls();r = 1;
star297 0:89274444b840 231 bit_map_draw();dcf_sec=0;bmd=1;start=0;zero_bit=0;
star297 0:89274444b840 232 status = 0; start_delay=1;
star297 0:89274444b840 233 d.start();
star297 0:89274444b840 234 if (dcfSignalIn) {interrupt_counter =0 ;sync=1;}
star297 0:89274444b840 235 Ticker10ms.attach(& myISR, .05 ); //Setup Ticker to call myISR every 50 ms
star297 0:89274444b840 236
star297 0:89274444b840 237 while (true) {
star297 0:89274444b840 238 loop(); // Continuously get dcf time and Display data interrupted by the Ticker every 50ms
star297 0:89274444b840 239 }
star297 0:89274444b840 240 }
star297 0:89274444b840 241
star297 0:89274444b840 242 void dcf_check()
star297 0:89274444b840 243 {
star297 0:89274444b840 244 parity_calc();
star297 0:89274444b840 245 paritycheck= testu or testm or testdmy;
star297 0:89274444b840 246 if (year>99) paritycheck=1;
star297 0:89274444b840 247 if (month>12) paritycheck=1;
star297 0:89274444b840 248 if (day>31) paritycheck=1;
star297 0:89274444b840 249 if (hour>23) paritycheck=1;
star297 0:89274444b840 250 if (min>59) paritycheck=1;
star297 0:89274444b840 251 if (paritycheck) {
star297 0:89274444b840 252 status = 4;
star297 0:89274444b840 253 }
star297 0:89274444b840 254 else {
star297 0:89274444b840 255 status = 3;
star297 0:89274444b840 256 }
star297 0:89274444b840 257 }
star297 0:89274444b840 258 void showClock()
star297 0:89274444b840 259 {
star297 0:89274444b840 260 lcd.locate(0,0);lcd.foreground (WHITE);
star297 0:89274444b840 261 lcd.printf("%02d:%02d:%02d", hour, minute, second);
star297 0:89274444b840 262 lcd.locate(0,1);
star297 0:89274444b840 263 lcd.printf("%s %02d %s'20%02d", weekDayName[dayofweek], dayofmonth, monthName[month-1], year);
star297 0:89274444b840 264 lcd.locate(0,2);
star297 2:31f5b5d56af6 265 if (summertime) {lcd.foreground (RED);lcd.printf("Summer Time ");}
star297 2:31f5b5d56af6 266 else {lcd.foreground (BLUE);lcd.printf("Winter Time ");}
star297 2:31f5b5d56af6 267 lcd.foreground (RED);lcd.printf("%s",leapText[dcf_status.is_leap]);
star297 0:89274444b840 268 if (status==0) {lcd.foreground (WHITE);}
star297 0:89274444b840 269 if (status==1) {lcd.foreground (CYAN);}
star297 0:89274444b840 270 if (status==2) {lcd.foreground (BLUE);}
star297 0:89274444b840 271 if (status==3) {lcd.foreground (GREEN);}
star297 0:89274444b840 272 if (status==4) {lcd.foreground (RED);}
star297 0:89274444b840 273 lcd.locate(0,15);
star297 0:89274444b840 274 lcd.printf(statusText[status]);
star297 0:89274444b840 275 }
star297 0:89274444b840 276
star297 0:89274444b840 277 void bit_print()
star297 0:89274444b840 278 {
star297 0:89274444b840 279 if (r==1) {lcd.foreground (MAGENTA);} // alternate bit draw colour
star297 0:89274444b840 280 else {lcd.foreground (WHITE);}
star297 0:89274444b840 281 lcd.locate(x+3,(y+1));
star297 0:89274444b840 282 lcd.printf("%d",dcf_status.sample150);
star297 0:89274444b840 283 (y)++;
star297 0:89274444b840 284 if ((dcf_sec)==27){(y)=13;}
star297 0:89274444b840 285 if ((dcf_sec)==28){(y)=5;(x)=(x)+2;lcd.printf(" ");}
star297 0:89274444b840 286 if ((dcf_sec)==34){(y)=13;}
star297 0:89274444b840 287 if ((dcf_sec)==35){(y)=5;(x)=(x)+2;}
star297 0:89274444b840 288 if ((dcf_sec)==41){(y)=5;(x)=(x)+2;}
star297 0:89274444b840 289 if ((dcf_sec)==44){(y)=5;(x)=(x)+2;}
star297 0:89274444b840 290 if ((dcf_sec)==49){(y)=5;(x)=(x)+2;}
star297 0:89274444b840 291 }
star297 0:89274444b840 292
star297 0:89274444b840 293 void bit_map_draw()
star297 0:89274444b840 294 {
star297 0:89274444b840 295 lcd.foreground (YELLOW);(x)=0,(y)=5;
star297 0:89274444b840 296 lcd.locate(x,y);lcd.printf(" M H D d M Y");
star297 0:89274444b840 297 lcd.locate(x,y+1);lcd.printf(" 1 i o a a o e");
star297 0:89274444b840 298 lcd.locate(x,y+2);lcd.printf(" 2 n u t y n a");
star297 0:89274444b840 299 lcd.locate(x,y+3);lcd.printf(" 4 u r e t r");
star297 0:89274444b840 300 lcd.locate(x,y+4);lcd.printf(" 8 t h ");
star297 0:89274444b840 301 lcd.locate(x,y+5);lcd.printf("10 e ");
star297 0:89274444b840 302 lcd.locate(x,y+6);lcd.printf("20 ");
star297 0:89274444b840 303 lcd.locate(x,y+7);lcd.printf("40 ");
star297 0:89274444b840 304 lcd.locate(x,y+8);lcd.printf("80 ");
star297 0:89274444b840 305 lcd.locate(x,y+9);lcd.printf(" P arity ");
star297 0:89274444b840 306 }
star297 0:89274444b840 307
star297 0:89274444b840 308 void loop()
star297 0:89274444b840 309 {
star297 0:89274444b840 310 if (interrupt_counter == 0) {
star297 0:89274444b840 311 showClock();
star297 0:89274444b840 312 lcd.locate(10,12);lcd.foreground (WHITE);lcd.printf("%02d",dcf_sec);
star297 0:89274444b840 313 }
star297 0:89274444b840 314 }
star297 0:89274444b840 315
star297 0:89274444b840 316 void set_time()
star297 0:89274444b840 317 {
star297 0:89274444b840 318 second = dcf_sec;
star297 0:89274444b840 319 minute=p_minute;
star297 0:89274444b840 320 hour=p_hour;
star297 0:89274444b840 321 dayofweek=p_dayofweek;
star297 0:89274444b840 322 dayofmonth=p_dayofmonth;
star297 0:89274444b840 323 month=p_month;
star297 0:89274444b840 324 year=p_year;
star297 0:89274444b840 325 }
star297 0:89274444b840 326
star297 0:89274444b840 327 void restart()
star297 0:89274444b840 328 {
star297 0:89274444b840 329 start=0;s=0;x=0;y=5;dcf_sec=0;dcf_error=0;
star297 0:89274444b840 330 insecond_counter=0;zero_bit=0;start_delay=1;
star297 0:89274444b840 331 }
star297 0:89274444b840 332
star297 0:89274444b840 333 void parity_calc()
star297 0:89274444b840 334 {
star297 0:89274444b840 335 //calculate summer/winter time----------------------------------------------------------------------
star297 0:89274444b840 336 summertime = dcf_array[17] & 1;
star297 0:89274444b840 337 //calculate hour--------------------------------------------------------------------------------------
star297 0:89274444b840 338 hourh = dcf_array[34] * 20 + dcf_array[33] * 10;
star297 0:89274444b840 339 hourl = dcf_array[32] * 8 + dcf_array[31] * 4 + dcf_array[30] * 2 + dcf_array[29] * 1;
star297 0:89274444b840 340 p_hour = hourh + hourl;
star297 0:89274444b840 341 //calculate minutes------------------------------------------------------------------------------------
star297 0:89274444b840 342 minl = dcf_array[24] * 8 + dcf_array[23] * 4 + dcf_array[22] * 2 + dcf_array[21] * 1;
star297 0:89274444b840 343 minh = dcf_array[27] * 40 + dcf_array[26] * 20 +dcf_array[25] * 10;
star297 0:89274444b840 344 p_minute = minh + minl;
star297 0:89274444b840 345 //calculate day of week--------------------------------------------------------------------------------
star297 0:89274444b840 346 p_dayofweek = dcf_array[44] * 4 +dcf_array[43] * 2 + dcf_array[42] * 1;
star297 0:89274444b840 347 //calculate day----------------------------------------------------------------------------------------
star297 0:89274444b840 348 dayl = dcf_array[39] * 8 + dcf_array[38] * 4 + dcf_array[37] * 2 + dcf_array[36] * 1;
star297 0:89274444b840 349 dayh = dcf_array[41] * 20 + dcf_array[40] * 10;
star297 0:89274444b840 350 p_dayofmonth=dayh+dayl;
star297 0:89274444b840 351 //calculate month--------------------------------------------------------------------------------------
star297 0:89274444b840 352 monthh = dcf_array[49] * 10;
star297 0:89274444b840 353 monthl = dcf_array[48] * 8 + dcf_array[47] * 4 + dcf_array[46] * 2 + dcf_array[45] * 1;
star297 0:89274444b840 354 p_month = monthh +monthl;
star297 0:89274444b840 355 //calculate year---------------------------------------------------------------------------------------
star297 0:89274444b840 356 yearh = dcf_array[57] * 80 + dcf_array[56] * 40 + dcf_array[55] * 20 + dcf_array[54] * 10;
star297 0:89274444b840 357 yearl = dcf_array[53] * 8 +dcf_array[52] * 4 + dcf_array[51] * 2 + dcf_array[50] * 1;
star297 0:89274444b840 358 p_year = yearh+yearl;
star297 0:89274444b840 359 //calculate parity
star297 0:89274444b840 360 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];
star297 0:89274444b840 361 parityu =dcf_array[29] + dcf_array[30] + dcf_array[31] + dcf_array[32] + dcf_array[33] + dcf_array[34] + dcf_array[35];
star297 0:89274444b840 362 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];
star297 0:89274444b840 363 //test parity------------------------------
star297 0:89274444b840 364 testu=parityu & 1;
star297 0:89274444b840 365 testm=paritym & 1;
star297 0:89274444b840 366 testdmy=paritydmy & 1;
star297 0:89274444b840 367 }
star297 0:89274444b840 368