DCF77-Decoder V4 - Beschreibung:
==============================
Bei der Beschreibung beschränke ich mich auf den eigentlichen DCF77-Decoder V0.97 (Unterprogramm DCF77Decoder).
Da mein DCF-Empfänger mit invertierendem Ausgang an I8 angeschlossen ist, wird dieser Eingang (D 10V) anfangs abgefragt. Da der Decoder Pausenlängen (Highpegel = 1 an I8!) misst, summiert er in der Variable ZählerP die Durchläufe der "Messschleife" auf. Die Pause von 0,009s bestimmt die Abfragezeit von I8 (ca. 10ms). Eine schnellere Abfragezeit ist nicht sinnvoll, da intern der Wert von I8 nicht schneller aktualisiert wird. Pausenlängen messen bedeutet in diesem Fall, dass der ZählerP so lange hochgezählt wird, bis wieder ein Signalanfang (Lowpegel = 0 an I8!) bemerkt wird. Dann ist die aktuelle Pause zuende und der letzte Wert von ZählerP wird in die Variable Pause übernommen.
Zwei Dinge sind in diesem Programmteil noch auffällig:
1. Warum wird ein Vergleich A?B bei Signalanfang verwendet? Der Grund: Es wird erst dann davon ausgegangen, dass eine verwertbare Pause vorliegt, wenn sie mehr als 2 Abfragen lang (> 20ms) anliegt. Dies ist ein Schutz vor sog. "Spikes", also kurzen Signalspitzen/-einbrüchen, die Störungen entsprechen. Das ist also ein gewisser Schutz vor Störsignalen.
2. Warum gibt es die Abfrage A>6000 bei der Pausenlänge? Der Grund: Der ZählerP soll nicht überlaufen, wenn gar kein DCF-Empfänger angeschlossen ist oder aus anderem Grund ein permanenter Highpegel an I8 anliegt. Das Programm würde sich dann "aufhängen", was eigentlich gar nicht passieren dürfte (Bug in RoboPro?).
Steht die Pausendauer in "Pause" fest, wird die Dauer bewertet: Ein DCF-Bit wird als 1 (Soll: 800 oder 1800ms) erkannt, wenn die Pausendauer 71..85 (x10ms) oder 171..185 (x10ms) beträgt. Als 0 gilt das das DCF-Bit (Soll: 900 oder 1900ms), wenn die Pausendauer 86..99 (x10ms) oder 186..199 (x10ms) beträgt.
Die DCF-Bit-Information wird in "Bit" weiterverarbeitet. Ob ein "Ende-Bit" (Telegrammende: Pause 1800/1900ms!) erkannt wurde, wird in "EndBit" gespeichert.
Jedes erkannte/decodierte DCF-Bit wird gezählt (in "BitZähler") und in eine Variable "BitSchieber" bitweise von oben hineingeschoben. Was bedeutet "von oben"? Das aktuelle DCF-Bit wird an die höchste Bitstelle (15x SHL auf Bit 15) hineinkopiert (OR), dann wird der BitSchieber um eine Stelle nach rechts (nach unten) rotiert (SHR). Damit ist er bereit für das nächste DCF-Bit.
Rechts oben im Programm ist auch noch "Parität" zu erkennen. Jedes DCF-Bit wird hier addiert,- letztlich also nur die Anzahl der 1-Bits, die wir später für die Paritätsberechnung brauchen.
Danach werden mit den Verzweigungen A=0 bis A=60 die BitZähler-Stände abgefragt. Mit A=14 beginnt das DCF-Telegramm. Bei A=20 sind schon die "DCF-Flags" eingesammelt und können in DCFFlg gesichert werden. Der Sinn dieser Abfragen ergibt sich aus der Kenntnis des Aufbaus des DCF-Telegramms, der hier nicht noch einmal erläutert wird. Warum wird der BitSchieber eigentlich noch mit 9x SHR nach "unten" geschoben, bis er in DCFFlg gespeichert wird? Der Grund: Da der BitSchieber Platz für 16 Bits hat und die Flags (DCF-Bits 15..20) nur aus 6 Bits bestehen, muss der Inhalt des Bitschiebers noch nach unten geschoben werden, bis DCF-Bit 15 an Bitnummer 0 des BitSchiebers liegt. So geht das auch bei allen anderen Werten des Telegramms.
Da die Werte für Minute, Stunde ... als BCD-Zahlen decodiert werden, müssen sie mithilfe von BCD2DEC in Dezimalwerte umgewandelt werden. Das Unterprogramm MinMax testet die Werte auf den jeweils zulässigen Bereich,- für den Monat also z.B. auf 1 bis 12.
Bleibt noch das Problem der Parität:
An der Stelle A=28 (BitZähler ist 28) wird z.B. das Paritätsbit P1 (Minutenparität) ausgewertet: Die GERADE Parität bedeutet einen fehlerfreien Minutenwert. Die Variable "Parität" wird also bitweise UND-verknüpft mit 1 (AND B=1). Die nachfolgende Verzweigung bestimmt das Ergebnis: Ist A>0, dann ist die Parität UNGERADE und das Telegramm fehlerhaft. DCFErr wird also auf 1 gesetzt. Das Telegramm wird am Ende verworfen. Nach diesem Paritätstest wird Parität auf 0 gesetzt, genauso auch der BitSchieber. Das selbe Verfahren gibt es für die Paritätsbits P2 und P3.
Irgendwann ist das DCF-Telegramm zuende. Das ist der Fall, wenn ein "Ende-Bit" (Pause 1800 oder 1900ms) erkannt wurde oder der BitZähler die 59 überschreitet (darf nicht passieren: Fehler!).
Wenn am Telegrammende DCFErr den Wert 0 (kein Fehler im ganzen Telegramm!) hat, wird die Variable DCF_Ok auf 1 gesetzt. Damit liegt ein gültiges DCF-Telegramm vor, mit dem eine Uhr gestellt werden kann. DCF_Ok bleibt für eine 1/4 Minute auf 1, um dann wieder 0 zu werden. Obwohl DCF_Ok so lange 1 bleibt, sollte eine Uhr SOFORT gestellt werden, wenn DCF_Ok 1 wird, damit die DCF-Zeit möglichst rasch übernommen wird.
Bleibt noch ein Sonderfall bei A=59 (BitZähler ist 59): Die Schaltsekunde.
Hier wird im DCF-Telegramm ab und zu eine sog. Schaltsekunde eingefügt, da sich die Erde immer langsamer dreht. Die Bedingungen dafür (DCF-Bit 59 ist 0 und A2 ist 1) werden in dem (seltenen) Fall geprüft.
So viel zur kurzen Erklärung des eigentlichen DCF77-Decoders V0.97 ...
Ob es mal eine Version 1.0 gibt? Ich weiß es nicht ...
Fragen
hier!