-
Notifications
You must be signed in to change notification settings - Fork 6
DCF77
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.
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.
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.
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.
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.
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:
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
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.
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 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.
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:
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.
-
Tutorials
-
FAQ
-
Referenz
- Konzepte
- Hardware
- Software/PC
- Software/Firmware
- Patches
- EDS - EEPROM Data System
- HCAN Protokoll
- HCAN Protokoll - Referenz