Skip to content
RealMerlin edited this page Feb 4, 2019 · 11 revisions

Allgemeines

Ein DCF77-Device erlaubt den Anschluß eines DCF77-Moduls am C1612-Controllerboard (getestet wurde das Device mit einem Modulbaustein von Conrad). Damit kann ein HCAN-System auch ohne PC mit einer verläßlichen Zeitreferenz als Teil des HCAN Real Time Systems konfiguriert werden. Das Device kann minütlich die via DCF77-Signal empfangene Zeitinformation in das HCAN System einspeisen.

Die Implementierung basiert auf der Arbeit von Peter Dannegger in DCF77 Uhr in C mit ATtiny26 und der von Martin Haller in timeservice.

Hardware

Das DCF77-Modul besitzt 4 Kontakte, die wie im Bild unten dargestellt angeschlossen werden. Als Spannungsversorgung wird die 5V-Versorgung auf dem Controllerboard verwendet. Der unbeschaltete Ausgang ist der invertierte Ausgang. Der Ausgang des DCF77-Moduls kann direkt mit einem der Eingangsports des Controller1612-Boards verbunden werden.

patch dcf77-anschluesse

Die Ausrichtung der Antenne sollte wie in http://www.funkuhr.com/aufstellhilfe-fuer-funkuhren erfolgen. Bei den Arbeiten zu diesem Device hat sich empfohlen, den Empfangsbaustein in einem Abstand von ca. 1-3m von anderen elektrischen Verbrauchern wie PC's zu platzieren.

EDS Konfiguration

create dcf77_receiver
set level 1
set takeover_time 90
set dummy0 1
set port 2
set id 100
set enable_error_reporting 1
exit
Feldname Bit Beschreibung Belegung
level Priorität des Devices im HCAN RTS 0..255, sinnvoll: 1..255
takeover_time Zeitdauer in Sekunden, die das Device wartet, bis es selbst sendet - solange, bis ein Device mit niedrigerem Level sendet 0 .. 255, sinnvoll: 61..255
dummy0 nicht genutzter Eintrag für den Parameter interval, ist aus Kompatibilitätsgründen zu anderen Zeit-Devices definiert 0 .. 255
port Eingangsport, an dem das DCF77-Modul angeschlossen ist 0..15
id ID des Moduls, wird bei der Fehlerausgabe mitgesendet 0 .. 255
enable_error_reporting '0': keine Fehlerangaben, '1..255': Fehlercodes werden ggf. im Minutentakt gesendet. 0..255

Der für ein timeservice-Device definierte Parameter interval ist für das DCF77-Modul entfallen, da das Modul nur minütlich senden kann. Eine weitere Einschränkung des Sendeintervalls scheint nicht sinnvoll. Der Parameter dummy0 repräsentiert den weggelassenen Parameter interval, der auf diese Weise ohne Änderung der Struktur nachträglich eingefügt werden könnte.

Funktionsbeschreibung

Das DCF77 Signal

Der grundsätzliche Aufbau eines DCF77-Signals ist in http://de.wikipedia.org/wiki/DCF77 erläutert. Ein launiger Hintergrundartikel findet sich in http://www.wolfgang-back.com/PDF/DCF77.pdf.

Der Anfang jeder Sekunde im demodulierten Signal wird durch einen Flankenwechsel 1->0 eingeleitet (Ausnahme: Sekunde 59). In den Sekunden 1 bis 58 wird zusätzlich eine Bitinformation übertragen, die im Sekundenbereich 21 bis 58 die Zeit- und Datumsinformation sowie Paritätsinformationen enthält. Die in einer Minute übertragene Zeitinformation bezieht sich auf den Zeitpunkt des nachfolgenden Minutenübergangs.

Im Signal leitet der Flankenwechsel 1->0 einen Puls (mit Pegel 0) ein: die Information '0' wird durch eine Pulslänge von 0,1s, eine '1' durch eine Pulslänge der Dauer 0,2s ausgedrückt.

Der Beginn einer neuen Minute kann durch das Ausbleiben des sekündlichen Flankenwechsels erkannt werden. Wenn zwei aufeinanderfolgende 1->0 Flankenwechsel eine Periode beschreiben, besteht eine Minute aus 58 Perioden der Länge 1s und einer Periode der Länge 2s. Im Quellcode wird die Periode durch die Tickzahl in der Variable dcf77_period ausgedrückt.

Der Aufbau des DCF77-Signals ist im Bild unten zusammengefaßt.

dcf77_struktur

Die Abtastung des DCF77 Signals

Das Device tastet durch einen Interrupt-Handler das DCF77-Signal ab. Die Abtastung erfolgt 60 Mal in der Sekunde, die Abtastzeitpunkte heißen im folgenden Ticks. Das Informationsbit '0' entspricht daher einer Dauer von 6 Ticks (0,1s*60 = 6), das Informationsbit '1' entsprechend einer Dauer von 12 Ticks. Im Quellcode wird die Pulslänge durch die Tickzahl in der Variablen dcf77_pulse ausgedrückt.

Die Taktfrequenz XTAL (3,6864 MHz) mit einem Teiler von 1024 für TIMER2 liefert eine Frequenz von 3600 Hz. Mit Hilfe eines weiteren Teilers von 60 (T2COUNT) läßt sich eine Abtastfrequenz von 60 Hz einstellen. Jede Sekunde wird so auf 60 Ticks mit einem Abstand von 1s/60 = 0,01666s aufgeteilt.

Der Zusammenhang ist für 60 Ticks pro Sekunde ist für das Informationsbit '0' in Sekunde 21 nachfolgend dargestellt:

dcf77_second60

Anmerkung: Die Größe 60 Ticks pro Sekunde ist ein Kompromiß aus dem Wunsch nach einer

  • hohen Abtastrate der Pulslängen zur sicheren Unterscheidung
  • Beschränkung der Tick-Zählervariablen auf 8 bit und damit einer niedrigen Abtastrate

Fehler bei der Abtastung des DCF77 Signals

Signal und Abtastvorgang weichen in der Realität von der Darstellung in den oberen Bildern ab. Im folgenden werden deshalb drei Fälle bei der Abtastung unterschieden (am Beispiel eines Pulses der Länge 0,1s). Mit einem erkannten Flankenwechsel wird der Pulszähler auf 0 gesetzt. Im Standardfall ist die Abtastung gegenüber der Pulsflanke 1->0 zeitversetzt. Ebenso wird auch der Flankenwechsel 0->1 zeitversetzt erkannt. Dies liefert verläßlich eine Pulslänge von 6 Ticks.

Bei den Varianten 1 und 2 fallen Flankenwechsel und Abtastung praktisch zusammen. Da der Flankenwechsel (durch die Empfangsfilter des Moduls) real eine endliche Steigung hat und auch die Abtastung kleinen zeitlichen Schwankungen unterliegt, kann im Einzelfall:

  • der 1->0 Flankenwechsel sofort erkannt werden, dafür aber der 0->1 verspätet (Variante 1) und liefert 7 Ticks.
  • der 1->0 Flankenwechsel verspätet erkannt werden, dafür aber der 1->0 sofort (Variante 2) und liefert 5 Ticks.

dcf77_pulsabtastung

Im Quellcode wird bei jeder Messung diese Fehlermöglichkeit, die für die Bestimmung der Puls- und Periodenlängen gleichermaßen gilt, durch den TICK_ERROR (d.h. durch eine erlaubte Abweichung um einen Tick) berücksichtigt. Diese Toleranz wird im folgenden Abschnitt vorausgesetzt.

Die Auswertung des DCF77 Signals

Die Variable dcf77_period beschreibt im Quellcode die Anzahl Ticks zwischen zwei aufeinanderfolgenden 1->0 Übergängen und ist ein Maß für den ermittelten Sekundentakt. Ist die Periodenlänge von 60 verschieden, liegt ein Empfangsfehler vor (DCF77_ILLEGAL_PERIOD_LENGTH). Erreicht die Periodenlänge den Wert 255, geht das Device davon aus, daß gar kein Empfang vorliegt (DCF77_NO_SIGNAL). Ausnahme: Der Minutenanfang wird durch eine erkannte dcf77_period von 120 Ticks, d.h. 2 Sekunden, festgestellt. In diesem Fall wird der interne Sekundenzähler (newtime.second) auf Null gesetzt.

Für jede Sekunde wird die Pulslänge (dcf77_pulse) des Informationsbits ermittelt, d.h. es werden die Ticks zwischen einem 1->0 und dem nachfolgenden 0->1 Übergang gezählt. Weicht die Pulslänge von den Zielgrößen 6 bzw. 12 ab, liegt ein Empfangsfehler vor (DCF77_ILLEGAL_PULSE_LENGTH).

Mit jeder abgelaufenen Sekunde wird der interne Sekundenzähler hochgezählt. Dieser Sekundenzähler dient dazu, um die erkannten Pulse zuordnen zu können, denn ab Sekunde 21 wird die Zeitinformation eingelesen. Jedes Bit wird entsprechend seiner Wertigkeit und seiner Bedeutung (Minute, Stunde,..) in den entsprechenden Variablen der Datenstruktur newtime addiert. Zusätzlich wird die mitübertragene Paritätsinformation ausgewertet und ggf. ein Paritätsfehler (DCF77_PARITY_ERROR) angezeigt.

Beispiel: Die Stundeninformation wird in sechs aufeinander folgenden Bits übertragen. Die Bits haben in der Reihenfolge ihres Empfangs die Wertigkeit 1, 2, 4, 8, 10 und 20 (BCD kodiert), d.h. die Bitfolge 1000001 entspricht 1+20 = 21 Stunden. Wenn das nachfolgend empfangene Paritätsbit 1 ist, liegt ein Paritätsfehler (DCF77_PARITY_ERROR) vor, denn die Zahl der empfangenen Einsen muß gerade sein (gerade Parität).

Die in einer Minute erkannten Fehler werden in der Variablen dcf77error festgehalten. Die in dcf77-receiver.h definierten Fehlercodes können innerhalb einer Minute einzeln oder zusammen auftreten:

#define DCF77_NO_SIGNAL              0x80
#define DCF77_ILLEGAL_PERIOD_LENGTH  0x40
#define DCF77_ILLEGAL_PULSE_LENGTH   0x20
#define DCF77_PARITY_ERROR           0x10

Einmal pro Minute liegt daher entweder eine gültige Zeit oder ein Fehlercode vor, d.h. sobald eine Minute mit einem Empfangsfehler behaftet ist, wird die ermittelte Zeitinformation verworfen. Ein Fehlercode wird immer versendet - wenn der Parameter enable_error_reporting gesetzt ist-, die gültige Zeit nur, wenn die Voraussetzungen gegeben sind (siehe [HCAN Real Time Systems](HCAN Real Time System)).

Nach dem Einschalten wird das Modul auch bei guten Empfangsbedinungen mindestens für die erste Minute einen Empfangsfehler feststellen und für enable_error_reporting > 0 auch ausgeben:

  • Wenn der Minutenanfang durch das Device nicht erkannt wurde, wird der Fehlercode anhand des Minutenübergangs der internen Uhr ausgegeben.
  • Alternativ wird der Fehlercode mit dem erkannten Minutenanfang ausgegeben.

Änderungen gegenüber dem Originalcode

Im Originalcode von Peter Dannegger ist die Abtastung auf 64 Ticks pro Sekunde ausgelegt. Dadurch gibt es einen Rundungsfehler, der durch einen längeren Tick am Ende der Sekunde korrigiert wird:

dcf77_second64

Auch diese Verlängerung des letzten Ticks weist bei beliebigem Wert für XTAL einen möglichen Rundungsfehler auf - der Originalcode sieht deshalb für den letzten Tick einer Minute eine nochmals angepaßte Korrektur vor. Diese Korrekturen sind notwendig, damit eine SW-basierte Uhr mit möglichst geringem Fehler die Zeit zwischen zwei fehlerfrei empfangenen Zeit-und Datumsangaben überbrückt. Dafür arbeitet der Code von Peter Dannegger für (fast) beliebige XTAL-Frequenzen und erlaubt mit 64 Ticks auch eine etwas vereinfachte Sekundenbehandlung im Code.

Mit der im HCAN-System verwendeten Taktfrequenz zusammen mit der Wahl von 60 Ticks pro Sekunde gäbe es für eine Uhrenfunktion keinen Korrekturbedarf. Die SW-Uhr ist allerdings gegenüber dem Originalcode entfernt, da das Device ausschließlich die minütlich empfangenen Zeit- und Datumsinformationen liefern soll.

Clone this wiki locally