/**************************************************************************************** |---------------------------------------------------------------------------------------| | Programmbeschreibung: | Mit diesem Programm wird das DCF-Signal mit einer | | | DCF-Antenne eingelesen. | |---------------------------------------------------------------------------------------| | Version: | 2.4. | |---------------------------------------------------------------------------------------| | Autor: | Marcel Kaptein. | |-----------------------|---------------------------------------------------------------| | Besonderheiten: | -In dieser neuen Version wird die Uhrzeit und das Datum in | | | einem String an das Hauptprogramm übergeben. So fällt es | | | leichter eine Uhrzeit z.B. zu einem Messwert, zu speichern. | | | Die Uhrzeit muss deshalb im Hauptprogramm ausgegeben werden, | | | und nicht mehr in der include.Datei. | | | -Nach dem Einschalten des Controllers läuft die Uhr so lange, | | | bis sie synchronisiert ist. Danach wird die Uhr allerdings | | | nur zur jeden vollen Stunde aktualisiert. | | | ( beginn zur 57. Minute, maximal bis zur 6. Minute ) | | | -Anhand der Variable >dcf.synchstatus< kann der aktuelle | | | Synchstatus z.B. auf einem Display angezeigt werden. | | | -Man benötigt keine extra Variablen im Hauptprogramm. Alle | | | Variablen stehen in der include-Datei oder im Funtionsaufruf.| | | Lediglich für die main.h wird ein define und zwei Strings | | | benötigt. | | | #define TEXTLAENGE 12 | | | unsigned char zeit[TEXTLAENGE]; //Variable für Zeit-String | | | unsigned char datum[TEXTLAENGE]; // Variable für Datum-String| | | | |-----------------------|---------------------------------------------------------------| | Anschluss: | Die DCF-Antenne wird am Port D, Pin 2 (INT_0) angeschlossen. | | (Beispiel am MEGA_16) | Zusätzlich wird auch der Interrupt 0 benötigt. | | | Von der Antenne ist der >NICHT-invertierender Ausgang< | | | zu benutzen!! | |-----------------------|---------------------------------------------------------------| | Peripherie: | | | Timer 0 | Der Timer muss mit einer Taktung von 4MHz laufen. Auch der | | | "overflow- Interrupt" wird benötigt. | |,,,,,,,,,,,,,,,,,,,,,,,|,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,| | Interrupt 0 | Die DCF-Antenne wird direkt an dem Interrupt angeschlossen. | | | Dabei ist darauf zu achten das der Interrupt auf steigende | | | Flanke reagiert. | |---------------------------------------------------------------------------------------| | | |---------------------------------------------------------------------------------------| | Erklärung der Funktionen: | |***************************************************************************************| | unsigned char checkPBit (unsigned char data,unsigned char pbit) | |,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,| | Diese Funktion überprüft, ob die Prüfbit's zu dem empfangenem Wert passt. Dabei muss | | das empfangene Parity-bit die Anzahl der Einsen im empfangenem Byte auf eine gerade | | Zahl ergänzen. | | | | INPUT: data --> detektierte Daten aus dem Synchronisierungssignal | | INPUT: pbit --> Wert des detektierte Parity-Bit | | OUTPUT: --> "true" oder "false" | |---------------------------------------------------------------------------------------| | | |***************************************************************************************| | timer_interrupt(unsigned char *antennen_signal) | |,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,| | Diese Funktion erzeugt zwei Arten von Uhren. Die erste Uhr ist die normale DCF-Uhr. | | Zusätzlich gibt es noch die interne Uhr die weiterläuft wenn es kein DCF-Signal gibt. | | | | INPUT: *antennen_signal --> bekommt den Wert der angeschlossen Antenne | | aus dem Hauptprogramm übergeben | |---------------------------------------------------------------------------------------| | | |***************************************************************************************| | antennen_interrupt() | |,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,| | Diese Funktion wird vom Antennen-Interrupt aus dem Hauptprogramm aufgerufen. | | Es wird ausgewertet ob ein Minutenwechsel vorliegt, oder nicht. | | Es wird nach drei erfolgreichen eingelesen Signalen die DCF-Uhzeit an die interne | | Uhr übergeben. | |---------------------------------------------------------------------------------------| | | |***************************************************************************************| | dcf_uhrzeit_anzeigen(char* z_zeit, char* z_datum, int laenge) | |,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,| | Diese Funktion erzeugt das Uhrzeit- und Datum- String. | | | | INPUT: *z_zeit --> ein Zeiger der auf ein String im Hauptprogramm "zeigt" | | so ist es möglich das die Uhrzeit als String an das | | Hauptprogramm übergeben wird. | | INPUT: *z_datum --> Datum an das Hauptprogramm | | INPUT: laenge --> Die länge des Stringes | |***************************************************************************************| | | |°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°| |°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°| | Erklärung der Funktionen im Hauptprogramm: | | | |---------------------------------------------------------------------------------------| | Diese Funktion bringt die Uhrzeit und das Datum auf das Display | dcf_uhr() { static unsigned char sekunden_merker; //Diese Unterfunktion wird bei jedem neuem Durchlauf von main aufgerufen. //Die Uhrzeit muss aber nur bei jedem Sekundenwechsel neu auf das Display geschrieben //werden. Das wird mit der Abfrage von >uhrwerk_sekunde< realisiert // |-- Variable von dcf_77 für Sekundenwechsel // | if(sekunden_merker != uhrwerk_sekunde) { dcf_uhrzeit_anzeigen(zeit, datum, TEXTLAENGE); // Aufruf der Funktion in dcf.h. switch (dcf.synchstatus) { case 0: //bild_01(); //Anzeige auf dem LCD break; case 1: //bild_01(); //Anzeige auf dem LCD break; case 2: //bild_2(); //Anzeige auf dem LCD break; case 3: //bild_3(); //Anzeige auf dem LCD break; case 4: //bild_4(); //Anzeige auf dem LCD break; case 5: //bild_01(); //Anzeige auf dem LCD break; } sekunden_merker = uhrwerk_sekunde; // neuen Wert abspeichern // ab hier muss die Uhrzeit ausgegeben werden. // goto x,y // puts (zeit) // goto x2, y2 // puts (datum) } } |***************************************************************************************| | Die Interrupt-Service Routine | |,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,| | Dieser Interrupt wird durch die DCF-Antenne ausgelöst. Die Uhr soll aber nur zu jeder | | Stunde synchronisiert werden. Wärend der Stunde ist die Funktion >gesperrt< | interrupt [EXT_INT0] void ext_int0_isr(void) { if((dcf.synchstatus < INSYNCH) && (dcf.synchstatus != GESPERRT)) { antennen_interrupt(); // Aufruf der Funktion in dcf_77.h } } |***************************************************************************************| | | |***************************************************************************************| | Timer_0 Interrupt-Service Routine | |,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,| | Der Timer_0 läuft mit einem Takt von 4MHz. Der Timer_0 hat 8 bit, also 256 Schritte. | | Somit dauert einen Takt des Timers 64µs. [ (4MHz/256) = 15625 -> *-1 = 64µs] | interrupt [TIM0_OVF] void timer0_ovf_isr(void) { static unsigned char *antenne; // diese Variable benötigt man um den Wert am // PORT D,Pin 2 an eine Funktion // in dcf.h zu übergeben antenne = PIND.2; // bekommt den Wert der am Port D Pin 2 // anliegt. (DCF_Antenne) // |-- übergabe des Wertes von Port D, Pin 2 // | timer_interrupt(antenne); } |***************************************************************************************| in der "main-routine" void main(void) { .... while (1) { ... dcf_uhr(); ... }; } ****************************************************************************************/ #ifndef _DCF_77_INCLUDED_ #define _DCF_77_INCLUDED_ #pragma used+ #include unsigned int zaehler_1=0; // Diese Variable wird für den Sekunden-Takt benötigt unsigned int zaehler_2=0; // Diese Variable wird für die Erkennung vom Minutenwechsel benötigt unsigned char uhrwerk_sekunde; // |-- Diese Variablen sind für die Interne Uhr, diese unsigned char uhrwerk_minute; // | Uhr läuft auch weiter wenn kein DCF-Signal unsigned char uhrwerk_stunde; // | vorhanden ist. unsigned char kalender_tag; // |-- Diese Variablen sind für den Internen Kalender. unsigned char kalender_wochentag;//| unsigned char kalender_monat; // | unsigned char kaledner_jahr; // | unsigned int vergangenes_dcf[3]; // Array für die DCF-Synkronisation unsigned char zaehler_letztes_dcf = 3; // Zähler für die DCF-Synkronisation // ( 3 = freigabe für Synchronisation ) bit stundenwechsel = 0; // Diese Variable wird für die "studenweise" Synchronisation benötigt bit abgleichen = 0; // Diese Variable ermöglicht die Speicherung des Zeitpunktes // von der letzten Synchronisation struct signal { // Struktur für das DCF-Signal unsigned char sekunde; unsigned char minute; unsigned char stunde; unsigned char tag; unsigned char wochentag; unsigned char monat; unsigned char jahr; unsigned char synchstatus; // Status des DCF-Empfangs // die folgenden Variablen werden in der >Include< nicht verwendet, sie // könne aber sehr nürtlich sein und einfach abgefragt werden. unsigned char abgleich_zeitpunkt[22]; // String für die speicherung der letzte Synchronisationszeit unsigned int fehler_zaehler; // Zähler wird jede Minute erhöht, wenn keine Synchronisation anlieg. }dcf; // Auf meinem Grafikdisplay habe ich mir 4 verschidene "Smilies" programmier die mit den // aktuellen Synchstatus anzeigen #define STARTSYNCH 0 // Bild_01 --> beim ersten Einschalten des Controllers [:( #define KEINSYNCH 1 // Bild_01 --> keine Synchronisation gefunden [:( #define INARBEIT_1 2 // Bild_2 --> es wird begonnen nach einer Synchronisation zu suchen [:| #define INARBEIT_2 3 // Bild_3 --> es wurde ein Signal erkannt [:o #define INSYNCH 4 // Bild_4 --> Uhr ist Synchronisiert [:) #define GESPERRT 5 // Bild_01 --> Synchronisation gesperrt [:( /*********************************************************************/ unsigned char checkPBit (unsigned char data,unsigned char pbit) { unsigned char t=1,i=0,p=0; for (i=0;i<8;i++) { if((data&t)==t) if(p==0) p=1; else p=0; t<<=1; } if (pbit==p) return 0;// Prüfbit stimmt - 0 als OK Antworten else return 1; // oder das Bit stimmt nicht } /*********************************************************************/ /*********************************************************************/ // |-- bekommt aus dem Hauptprogramm den // | Wert der DCF-Antenne die am Port D, Pin 2, // | angeschlossen ist. // | timer_interrupt(unsigned char *antennen_signal) { static unsigned char impuls=3;// Für die Erkennung der Impuslänge des Signale (kurz 0, lang 1) zaehler_1++; // Soll so lange erhöht werden, bis eine Sekunde vorbei ist zaehler_2++; // Soll so lange erhöht werden, bis mehr als eine Sekunde // vorbei ist um den Minutenwechsel zwischen 58. und 0. // Sekunde (etwa 1,8 Sekunden kein Signal) zu erkennen. // nach 600 Minten etwa 2 Sekunden vor if(zaehler_1>=15630) // 1 Sekunde / 64µs = 15625. Jedoch mit diesem Wert läuft die Uhr { // Uhr zu schnell. Durch probieren bin ich auf diesen Wert gekommen. uhrwerk_sekunde++; // es ist eine Sekunde vorbei, also um eins erhöhen zaehler_1=0; // Sekundenzähler wieder auf 0 } if(dcf.sekunde>59) { // wird diese Werte überschritten, dcf.synchstatus=KEINSYNCH; // liegt definitiv ein Fehler vor. dcf.sekunde=dcf.minute=dcf.stunde=0; // Fehler führt zurück zu "Keinsych" zaehler_letztes_dcf=3; // Freigabe zum Dekodieren der DCF Zeit } // ab der 57. Minute soll die Uhr beginnen sich neu zu syncronisieren. Aber nur wenn die Uhr // in Synchronisation ist. // Dazu wird die freigabe VOR der 57. Minute frei gegegen so dass man // zur 57. Minute in den >INARBEIT_2<-Mode kommt. if((dcf.synchstatus == INSYNCH)&&(uhrwerk_minute == 56)&&(uhrwerk_sekunde == 30)) { zaehler_letztes_dcf = 3; // Freigabe zum Dekodieren der DCF Zeit dcf.synchstatus = INARBEIT_1; stundenwechsel = 1; // diese Variable ermöglicht dass die Uhr sich beim // einschalten trotzdem nach der 6. Minute weiter // versucht zu Initialisieren. } /////////////////////////////////////////////////////////////////////// /***** Ab hier wird das Uhrwerk erzeugt ******************************/ ////// Minute vorbei /////// if(uhrwerk_sekunde==60) // Wenn 60 Sekunden vorbei sind... { uhrwerk_sekunde=0; // Sekunden wieder auf 0 und uhrwerk_minute++; // die Minuten um ein erhöhen dcf.fehler_zaehler++; // Dieser Zähler wird ständig erhöht, // erst bei einer erfolgreichen Synchronisation // wird er weider auf Null gesetzt. // ist die Synchtronisation fehlgeschlagen dann wird die Synchronisation // in der 6. Minute wieder gestoppt und der weitere Empfang ist bis zur // nachsten 57. Minute gesperrrt. if((uhrwerk_minute == 6)&&(stundenwechsel == 1)&&(dcf.synchstatus < INSYNCH)) { dcf.synchstatus = GESPERRT;// die Synchronisation wird bis zur 57. Minute gesperrt zaehler_letztes_dcf = 0; // Stopp der DCF Zeit stundenwechsel = 0; // Variable wieder auf "null" } } ////// Stunde vorbei /////// if(uhrwerk_minute==60) // Wenn 60 Minuten vorbei sind... { uhrwerk_minute=0; // Minuten wieder auf 0 uhrwerk_stunde++; // die Stunden um eins erhöhen } ////// Tag vorbei /////// if(uhrwerk_stunde==24) // Wenn 24 Stunden vorbei sind... { uhrwerk_stunde=0; // Stunden wieder auf 0 kalender_tag++; // den Tag um eins erhöhet kalender_wochentag++; // den Wochentag um eins erhöht } /* das Problem beim erhöhen vom Tag ist, dass das ganze ja nur bis zum 31. funktioniert. Doch jetzt auch noch die Auswertung zu machen welchen Monat wir haben, ob 28, 30 oder 31 Tage erschien mir nicht wichtig zu sein da ich "HOFFE :o)" das die Uhr nicht genau dann ohne >synk< bleibt!! Programmiertechnisch dürfe das ja kein Problem sein. */ ////// Woche vorbei /////// if(kalender_wochentag == 7) // ist der Wochentag bei 7, muss wieder { // bei 0 angefangen werde. kalender_wochentag = 0; } // Ende des Uhrwerks //Uhr dekodieren // solange die Variable >antennen_signal< "eins" ist, wird die >if-Anweisung< abgearbeitet. Erst wenn das // Antennesignal weg ist, wird das DCF-Signal dekodiert // |-- ist die Variable die aus dem Hauptprogramm übergeben wird. // | die Variabler hat immer den Wert vom Port D, Pin 2. (Antennensignal) // | if(antennen_signal) { // 2500 * 64µs = 160ms if(zaehler_2<2500) impuls=0;// Liegt ein Signal kürzer als 0,1 Sekunden an, ist da einen logisch 0 if(zaehler_2>2500) impuls=1;// liegt es länger wie 0,1 Sekunden an, ist es einen logische 1 } else // DCF Signal fertig zum dekodieren { if(impuls!=3 && zaehler_2>1200) { // Wenn impuls <3 ist und kein "flattern" // (zaehler_2<1200) festgestellt wurde //----------- Zeit vom DCF-Signal einlesen ---------------------------- // Die Minuten-Einer werden zwischen den 21 - 24 Sekunde, // die Minuten Zehner zwischen den 25 - 28 Sekuden gesendet // Zusätzlich wird das Pary-Bit zum prüfen noch mit eingelesen if(dcf.sekunde>=22 && dcf.sekunde<=28) { dcf.minute>>=1; // es werden alle bits um eins nach rechts geschoben dcf.minute|=impuls*64; // Das Momentane Bit (0,1 oder 0,2 Sekunden) // wird an die 6. Stelle von rechts in die // Variable geschoben (2^6 = 64) // | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | } // | 7. | 6. | 5. | 4. | 3.| 2.| 1.| 0.| // Jetzt stehen die Minuten im BCD-Formal in der Variable und müssen dann // umgewandelt werden. Das passiert aber nur wenn die Zeit mit dem // "Pary" Bit geprüft wurde. if(dcf.sekunde==29) { if(checkPBit(dcf.minute,impuls)==0) // Prüfe ob das Pary-Bit zum Wert passt { dcf.minute=bcd2bin(dcf.minute); // Minute umrechnen } else { dcf.synchstatus=KEINSYNCH; // Fehler festgestellt } } // Die Stunden-Einer werden zwischen den 29 - 32 Sekunde, // die Stunden Zehner zwischen den 33 - 34 Sekuden gesendet // Zusätzlich wird das Pary-Bit noch mit eingelesen if(dcf.sekunde>=30 && dcf.sekunde<=35) { dcf.stunde>>=1; // Bit schieben dcf.stunde|=impuls*64; // Bits von oben hinzufügen } if(dcf.sekunde==36) { dcf.stunde>>=1; // zusätzlich ein Bit schieben, da die Stunde nur 6 Bit lang // ist. Die Funktion >bcd2bin< würde sonst nicht funktionieren if(checkPBit(dcf.stunde,impuls)==0)// Prüfe ob das Pary-Bit zum Wert passt { dcf.stunde=bcd2bin(dcf.stunde); // Stunde umrechnen } else { dcf.synchstatus=KEINSYNCH; // Fehler festgestellt } } // Die Tages-Einer werden zwischen den 36 - 39 Sekunde, // die Tages Zehner zwischen den 40 - 41 Sekuden gesendet if(dcf.sekunde>=37 && dcf.sekunde<=42) { dcf.tag>>=1; // Bit schieben dcf.tag|=impuls*64; // Bits von oben hinzufügen } if(dcf.sekunde==42) { dcf.tag>>=1; dcf.tag=bcd2bin(dcf.tag);// Tag umrechnen } // Der Wochentag wird zwischen den 42 - 44 Sekunde gesendet if(dcf.sekunde>=43 && dcf.sekunde<=45) { dcf.wochentag>>=1; // Bit schieben dcf.wochentag|=impuls*4; // Bits von oben hinzufügen } if(dcf.sekunde==45) { dcf.wochentag=bcd2bin(dcf.wochentag); // Wochentag umrechnen } // Die Monat-Einer werden zwischen den 45 - 48 Sekunde, // der Monat Zehner wird in der 49. Sekuden gesendet if(dcf.sekunde>=46 && dcf.sekunde<=50) { dcf.monat>>=1; // Bit schieben dcf.monat|=impuls*32; // Bits von oben hinzufügen } if(dcf.sekunde==50) { dcf.monat>>=1; /**///dcf.monat|=impuls*1; // Bits von oben hinzufügen dcf.monat=bcd2bin(dcf.monat); // Monat umrechnen } // Die Jahres-Einer werden zwischen den 50 - 53 Sekunde, // die Jahres Zehner zwischen den 54 - 57 Sekuden gesendet if(dcf.sekunde>=51 && dcf.sekunde<=57) { dcf.jahr>>=1; // Bit schieben dcf.jahr|=impuls*128; // Bits von oben hinzufügen } if(dcf.sekunde==58) { dcf.jahr>>=1; dcf.jahr=bcd2bin(dcf.jahr); // Jahr umrechnen } impuls=3; // Wert wurde verarbeitet zaehler_2 = 0; // der Zähler muss zurück gesetzt werden damit der Zähler // nur in der 59. Sekunde über den Wert 26000 kommt } } // Ende der DCF-Signal dekodierung } /* */ /*********************************************************************/ /*********************************************************************/ antennen_interrupt() { /* Es wird überprüft wie lange eine Pause zwischen den zwei Signalen war. War die Pause länger wie 1,6 Sekunden (zaehler_2>26000), dann liegt ein Minutenwechsel vor. */ if(zaehler_2>26000) // 26000*64µs = 1,664 Sekunden { dcf.sekunde=0; // Stunde vorbei. Sekunden wieder auf "null" if(dcf.synchstatus < INARBEIT_2) dcf.synchstatus=INARBEIT_2; // Sollte der Synchstatus noch nicht erhöht // worden sein..... // wechsel von [:| auf [:o else // ist jedoch "dcf.synchstatus >= INARBEIT_2" { // Die Uhr sollte immer zum Stundenwechsel synchronisiert werden, da ja immer die darauf folgende // Minute, Stunde und Datum übertragen wird. Z.B. wird um 23.59 das Datum des nächsten Tages übertragen. // Gerade beim wechsel von Sommer- und Winterzeit ist dieser Stundenwechsel wichtig. // Würde man vorher oder nach 59. Minute synchronisieren, dann müsste man entweder // das ganze selber schreiben oder bis zur nächsten Synchronisation abwarten. // // das Array- >vergangenes_dcf< mit dem Element [--zaehler_letztes_dcf] wird mit der Uhrzeit gefüllt // z.b. um 12:34 // vergangenes_dcf[2] mit dem Wert 1234. (12 x 100 + 34) // vergangenes_dcf[1] mit dem Wert 1235. (12 x 100 + 35) // vergangenes_dcf[0] mit dem Wert 1236. (12 x 100 + 36) // so kann man überprüfen, ob die letzten drei Werte hintereinenader liegen. // Ein Problem gibt es aber beim Stundenwechsel. Z.B. 1259 und dann um 1300. Diese Situation // ergibt einen Fehler. (liegt nicht hintereinander) Deshalb wird, wenn die Minute = 0 ist, // der Wert manipuliert. --> 1258; 1259; 1260 // Auch beim Tageswechsel muss man manipulieren. 2358; 2359; 2360 // Sollte das einmal nicht funktionieren dann wird bis zur 6. Minute noch versucht // zu synchroniesieren ;o) if(dcf.minute == 0) { if(dcf.stunde == 0)// wenn dcf.stunde gleich "0", dann Tageswechsel { vergangenes_dcf[--zaehler_letztes_dcf]=(int)(dcf.stunde+23)*100+(dcf.minute+60); } else// sonst liegt nur ein Stundenwechsel vor { vergangenes_dcf[--zaehler_letztes_dcf]=(int)(dcf.stunde-1)*100+(dcf.minute+60); } } else// zwischen einer Stunde { vergangenes_dcf[--zaehler_letztes_dcf]=(int)dcf.stunde*100+dcf.minute; } } if(zaehler_letztes_dcf==0) { /* Wenn die drei Werte gelesen worden sind, wird überprüft ob sie in Reihe liegen. Wenn die Werte wirklich in Reihe liegen dann war die "decodierung" des DCF-Signals erfolgreich. Jetzt wird das DCF-Signal an das >Uhrwerk< und an den >Kalender< übergeben. */ if (vergangenes_dcf[0]-1==vergangenes_dcf[1] && vergangenes_dcf[1]-1==vergangenes_dcf[2]) { uhrwerk_stunde=dcf.stunde; uhrwerk_minute=dcf.minute; uhrwerk_sekunde=dcf.sekunde; kalender_tag=dcf.tag; kalender_wochentag=dcf.wochentag; kalender_monat=dcf.monat; kaledner_jahr=dcf.jahr; dcf.synchstatus=INSYNCH; // Signal ist synchronisiert dcf.fehler_zaehler = 0; // Zähler wird zurückgesetzt stundenwechsel = 0; // Variable für den stundenwechsel wieder auf "null" abgleichen = 1; // Variable ermöglicht dass die Stringkette // >dcf.abgleich_zeitpunkt< abgeglichen wird zaehler_1=0; // so wird sichergestellt dass der zähler ab jetzt wieder // genauer läuft. Falls er nämlich nicht null wäre, dann würde // ein bestehender Abweichung immer größer werden } if(dcf.synchstatus < INSYNCH) // ist der >zaehler_letztes_dcf< zwar null, aber die Werte { // lagen nicht hintereinader dann wird beginnt die Synchronisation zaehler_letztes_dcf = 3; // wieder von vorne } } }// Ende Pausenerkennung 1,6 Sekunden zaehler_2=0; // dieser Zähler wird innerhalb der Funktion (Interrupt durch die Antenne) wieder // zurück gesetzt. dcf.sekunde++; // wenn keine Pause länger wie 1,6 Sekunde war, dann muss die dcf.sekunde erhöht werden } /*********************************************************************/ /*********************************************************************/ dcf_uhrzeit_anzeigen(char* z_zeit, char* z_datum, int laenge) { unsigned char zeit[11]; // Variable für das Zeit-String unsigned char datum[11]; // Variable für das Datum-String unsigned char i; //***** Aufbau des Uhr- Strings if(uhrwerk_sekunde&1) // für das blinken der ':' auf dem Display { sprintf(zeit,"%02u %02u %02u",uhrwerk_stunde,uhrwerk_minute,uhrwerk_sekunde); } else { sprintf(zeit,"%02u:%02u:%02u",uhrwerk_stunde,uhrwerk_minute,uhrwerk_sekunde); } //***** Aufbau des Datums- Strings // Wochentag if(kalender_wochentag == 0) sprintf(datum,"So."); if(kalender_wochentag == 1) sprintf(datum,"Mo."); if(kalender_wochentag == 2) sprintf(datum,"Di."); if(kalender_wochentag == 3) sprintf(datum,"Mi."); if(kalender_wochentag == 4) sprintf(datum,"Do."); if(kalender_wochentag == 5) sprintf(datum,"Fr."); if(kalender_wochentag == 6) sprintf(datum,"Sa."); // Tag // Wenn der Tag kleiner wie 10 ist, dann braucht man nur die "einer" // Stelle auf dem Display. Sonst würde die Zahl mit eine 0 anfangen! if(kalender_tag <10)sprintf((datum+3)," %01u.",kalender_tag); if(kalender_tag >=10)sprintf((datum+3),"%02u.",kalender_tag); // Monat if(kalender_monat == 1) sprintf((datum+6),"Jan"); if(kalender_monat == 2) sprintf((datum+6),"Feb"); if(kalender_monat == 3) sprintf((datum+6),"Mrz"); if(kalender_monat == 4) sprintf((datum+6),"Apr"); if(kalender_monat == 5) sprintf((datum+6),"Mai"); if(kalender_monat == 6) sprintf((datum+6),"Jun"); if(kalender_monat == 7) sprintf((datum+6),"Jul"); if(kalender_monat == 8) sprintf((datum+6),"Aug"); if(kalender_monat == 9) sprintf((datum+6),"Sep"); if(kalender_monat == 10) sprintf((datum+6),"Okt"); if(kalender_monat == 11) sprintf((datum+6),"Nov"); if(kalender_monat == 12) sprintf((datum+6),"Dez"); strncpy(z_zeit, zeit, laenge); strncpy(z_datum, datum, laenge); // bei jeder Synchronisation wird die Variable >abgleichen< gesetzt, so dass in der // folgenden Schleife die Zeichenkette >dcf.abgleich_zeitpunkt< mit der aktuelle Zeit und dem // Datum "gefüllt" if(abgleichen == 1) { for(i=0;i<9;i++) { dcf.abgleich_zeitpunkt[i] = zeit[i]; dcf.abgleich_zeitpunkt[9+i] = datum[i]; if(i == 8)dcf.abgleich_zeitpunkt[i] = ' '; // Lehrzeichen zwischen Uhrzeit und Datum } abgleichen = 0; // Variable wieder auf "null" } } #pragma used- #endif