#ifndef __FUNKUHR_H #define __FUNKUHR_H //-------------------------------------------------------------------------- // funkuhr.h //-------------------------------------------------------------------------- // Realisierung einer Funkuhr // Anzeige von Datum und Uhrzeit //-------------------------------------------------------------------------- // Autor: Sven Jordan, http://www.s-jordan.de // Version: 1.0 // Stand: 2007-06-06 //-------------------------------------------------------------------------- #include #include #include #include "display.h" struct zeit { unsigned char second; // Sekunde (0...59) unsigned char minute; // Minute (0...59) unsigned char hour; // Stunde (0...23) unsigned char day; // Wochentag (1...7) unsigned char date; // Monatstag (1...31) unsigned char month; // Monat (1...12) unsigned char year; // Jahr (0...99) unsigned char MESZ; // Zeit ist (0 = MEZ, 1 = MESZ, 2 = Unbekannt) unsigned char zeitumstellung; // 1, wenn Zeitumstellung MEZ/MESZ am Ende der Stunde unsigned char RX_OK; // 1, wenn letzte empfangene Zeitinformation plausibel }; struct zeit funkuhr(unsigned char eingangsport, unsigned char eingangsbit); // Diese Funktion muss alle 10 ms aufgerufen werden void print_time(struct zeit uhrzeit); // Zeigt (DD TT.MM.JJ HH:MM:SS) an. Benoetigt Modul display.h struct zeit funkuhr(unsigned char eingangsport, unsigned char eingangsbit) { static struct zeit aktuell={0,0,0,0,0,0,0,2,0,0}; // Aktuelle Systemzeit static struct zeit empfangen1={0,0,0,0,0,0,3,2,0,0}; // Letzte empfangene Zeitinformation static struct zeit empfangen2={0,0,0,0,0,0,5,2,0,0}; // Vorletzte empfangene Zeitinformation static unsigned char hundertstelsek = 0, // Aktuelle Hundertstelsekunde DCF77_Imp = 0, // Aktueller Zustand des DCF77-Signals data_index = 0, // Zeiger auf die aktuell empfangene Info DCF77_HI = 0, // Dauer des HI-Pegels des DCF77-Signals DCF77_LO = 0; // Dauer des LO-Pegels des DCF77-Signals static unsigned char data[61]; // Empfangene Daten hundertstelsek++; switch(eingangsport) { case 'A': if(PINA & (1<= 250 || DCF77_HI >= 250) // Empfang gestoert (HI-/LO-Pegel zu lange unveraendert) { aktuell.RX_OK = 0; } if(DCF77_Imp == 0) { DCF77_LO++; if(DCF77_HI >= 15) // 1 empfangen (Pulsbreite mindestens 150 ms) { DCF77_HI=0; data[data_index]=1; data_index++; } else if(DCF77_HI >= 5) // 0 empfangen (Pulsbreite mindestens 50 ms) { DCF77_HI=0; data[data_index]=0; data_index++; } } if(data_index > 59) // Schutz vor Speicherzugriffsfehler { data_index = 0; aktuell.RX_OK = 0; } if(DCF77_Imp == 1) { DCF77_HI++; if(DCF77_LO >= 120) { empfangen1.MESZ = data[17]; empfangen1.zeitumstellung = data[16]; empfangen1.minute = data[21]+data[22]*2+data[23]*4+data[24]*8+data[25]*10+data[26]*20+data[27]*40; empfangen1.hour = data[29]+data[30]*2+data[31]*4+data[32]*8+data[33]*10+data[34]*20; empfangen1.date = data[36]+data[37]*2+data[38]*4+data[39]*8+data[40]*10+data[41]*20; empfangen1.day = data[42]+data[43]*2+data[44]*4; empfangen1.month = data[45]+data[46]*2+data[47]*4+data[48]*8+data[49]*10; empfangen1.year = data[50]+data[51]*2+data[52]*4+data[53]*8+data[54]*10+data[55]*20+data[56]*40+data[57]*80; // Plausibilitaetspruefung der empfangenen Daten if // Letzte Zeitinformation muss 1 Minute spaeter sein als vorletzte Zeitinformation ( empfangen1.MESZ==empfangen2.MESZ && empfangen1.zeitumstellung==empfangen2.zeitumstellung && ( (empfangen1.minute==empfangen2.minute+1 && empfangen1.hour==empfangen2.hour) || (empfangen1.minute==0 && empfangen2.minute==59 && empfangen1.hour==empfangen2.hour+1) ) && empfangen1.day==empfangen2.day && empfangen1.date==empfangen2.date && empfangen1.month==empfangen2.month && empfangen1.year==empfangen2.year && data_index==59 ) aktuell.RX_OK = 1; else if // Empfangene Zeitinformation weicht max. 1 Minute von aktueller Systemzeit ab ( empfangen1.MESZ==aktuell.MESZ && empfangen1.zeitumstellung==aktuell.zeitumstellung && ( empfangen1.minute==aktuell.minute || empfangen1.minute==aktuell.minute-1 || empfangen1.minute==aktuell.minute+1 ) && empfangen1.hour==aktuell.hour && empfangen1.day==aktuell.day && empfangen1.date==aktuell.date && empfangen1.month==aktuell.month && empfangen1.year==aktuell.year && data_index==59 ) aktuell.RX_OK = 1; else aktuell.RX_OK = 0; data_index=0; // Merken der Zeitinformation der letzten Minute fuer Plausibilitaetspruefung empfangen2.MESZ = empfangen1.MESZ; empfangen2.zeitumstellung = empfangen1.zeitumstellung; empfangen2.minute = empfangen1.minute; empfangen2.hour = empfangen1.hour; empfangen2.day = empfangen1.day; empfangen2.date = empfangen1.date; empfangen2.month = empfangen1.month; empfangen2.year = empfangen1.year; // Bei bestandener Plausibilitaetspruefung empfangene Daten fuer aktuelle Zeit uebernehmen if(aktuell.RX_OK == 1) { hundertstelsek = 0; aktuell.second = 0; aktuell.MESZ = empfangen1.MESZ; aktuell.zeitumstellung = empfangen1.zeitumstellung; aktuell.minute = empfangen1.minute; aktuell.hour = empfangen1.hour; aktuell.day = empfangen1.day; aktuell.date = empfangen1.date; aktuell.month = empfangen1.month; aktuell.year = empfangen1.year; } } DCF77_LO = 0; } if(hundertstelsek>=100) { hundertstelsek=0; aktuell.second++; if(aktuell.second>=60) { aktuell.second=0; aktuell.minute++; } if(aktuell.minute>=60) { aktuell.minute=0; aktuell.hour++; if(aktuell.zeitumstellung==1) { aktuell.zeitumstellung=0; if(aktuell.MESZ==1) { aktuell.MESZ=0; aktuell.hour--; } else { aktuell.MESZ=1; aktuell.hour++; } } } if(aktuell.hour>=24) { aktuell.hour=0; aktuell.day++; aktuell.date++; if(aktuell.day>7) { aktuell.day=1; } if(aktuell.month==2) { if(aktuell.date==29+1 && aktuell.year%4==0) // Schaltjahr { aktuell.month++; aktuell.date=1; } else if(aktuell.date==28+1 && aktuell.year%4!=0) // kein Schaltjahr { aktuell.month++; aktuell.date=1; } } else if(aktuell.date==30+1) { if(aktuell.month==4 || aktuell.month==6 || aktuell.month==9 || aktuell.month==11) { aktuell.month++; aktuell.date=1; } } else if(aktuell.date==31+1) { aktuell.month++; aktuell.date=1; if(aktuell.month>=13) { aktuell.month=1; aktuell.year++; } } } } return(aktuell); } void print_time(struct zeit uhrzeit) { switch(uhrzeit.day) { case 0: print_string("-- "); break; case 1: print_string("Mo "); break; case 2: print_string("Di "); break; case 3: print_string("Mi "); break; case 4: print_string("Do "); break; case 5: print_string("Fr "); break; case 6: print_string("Sa "); break; case 7: print_string("So "); break; } if(uhrzeit.date == 0) print_string("--"); else { print_char((uhrzeit.date/10)+48); print_char(uhrzeit.date%10+48); } print_char('.'); if(uhrzeit.month == 0) print_string("--"); else { print_char((uhrzeit.month/10)+48); print_char(uhrzeit.month%10+48); } print_char('.'); if(uhrzeit.year == 0) print_string("--"); else { print_char((uhrzeit.year/10)+48); print_char(uhrzeit.year%10+48); } print_char(' '); print_char((uhrzeit.hour/10)+48); print_char(uhrzeit.hour%10+48); print_char(':'); print_char((uhrzeit.minute/10)+48); print_char(uhrzeit.minute%10+48); print_char(':'); print_char((uhrzeit.second/10)+48); print_char(uhrzeit.second%10+48); } #endif