DCF77-Auswertung

Das Zeitsignal der physikalisch-technischen Bundesanstalt in Braunschweig wird gerne für das Stellen des RTC verwendet. Die Funktionsweise der Amplitudenmo­du­la­tion und den Aufbau der DCF77-Kodierung finden sie im Kapitel 12 [2].

Um das DCF77-Signal auswerten zu können, muss das Verhältnis ti/T ermittelt werden. Ist das Verhältnis 1/10, ist eine „0“ kodiert, bei 2/10 eine „1“. Abbildung 47 enthält ei­nen Ausschnitt des DCF77-Signals. Mit dem Beginn jeder Sekunde mit Ausnahme der 59sten, wird eine „0“, bzw. eine „1“ gesendet. Somit ist zu erkennen, wann die nächste Minute anfängt.

Abbildung 47  Ausschnitt aus dem DCF77-Signal

Je nach verwendetem DCF77-Empfänger weicht das Verhältnis von ti/T um einige % ab (siehe Abbildung 48 und Abbildung 49).

Abbildung 48  Empfang des Wertes „0“

Abbildung 49  Empfang des Wertes „1“

Erstellen sie ein Programm, das die Breite des LOW-Pulses auswertet. Wird eine „0“ erkannt, wird die LED an P2.0, bei einer „1“ die LED an P2.1 eingeschaltet. Liegt die Zeit außerhalb des erlaubten Bereiches von +- 10 %, so sollen die LEDs P2.4–P2.7 ein­ge­schal­tet werden. Um die Zeit messen zu können, wird der Timer 0 mit einem Reloadwert von 10 ms geladen (siehe Listing 53, ) und bei fallender Flanke gestartet (siehe ). Alle 10 ms (siehe ƒ) wird die Variable „ucTime“ inkrementiert und der Zustand des Portpins P2.3 gewechselt (siehe ). Wechselt der Zustand des DCF77-Signals von „0“ -> „1“, wird der Timer 0 gestoppt (siehe ) und „ucTime“ wird aus­ge­wer­tet (siehe ). Danach wird der Reloadwert gesetzt (siehe ) und auf die nächste fal­len­de Flanke gewartet (siehe ˆ).

Projektname

Verzeichnis

Verwendete Sourcemodule

DCF77_Tick

Test_DCF77_Tick

TestDCF77.c, PortConfig.c

Tabelle 57  Projekt DCF77_Tick

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ˆ

 

 

 

 

 

 

 

ƒ

#include <REG932.H>

#include <PortConfig.h>

 

sbit sbDCF77 = P0^0;

sbit sb10msec = P2^3;

unsigned char ucTime;

 

void main(void)

{

  v_PortConfig(Port2, AllPins, BiDir);

  P2 = 0xFF;

 

  TMOD = 0x01;  // Timer 0, Betriebsart 1

  TL0 = 0xDD;   // fuer 10 msec initialisieren

  TH0 = 0x6F;

  TF0 = 0;      // Timer 0 Flag zuruecksetzen

 

  ET0 = 1;      // Interrupt fuer Timer 1 freigeben

  EA = 1;

 

  // Warten bis fallende Flanke gefunden

  while (sbDCF77 == 0);

  while (sbDCF77 == 1);

 

  while (1)

  {

     TR0 = 1;    // Timer 1 starten

     ucTime = 0;

      while (sbDCF77 == 0);

     TR0 = 0;    // Timer 1 stoppen

 

     if (ucTime >= 10 & ucTime <= 11)

        P2 = 0x01;

     else if (ucTime > 20 & ucTime <= 21)

         P2 = 0x02;

     else

         P2 = 0xF0;

 

     // Timerwert auf Reloadwert setzen

     TL0 = 0xDD;

     TH0 = 0x6F;

      

     while (sbDCF77 == 1); // Warten auf fallende Flanke

  }

}

 

void v_Timer0Int(void) interrupt 1 using 1

{

  TL0 = 0xDD;

  TH0 = 0x6F;

  ucTime++;

  sb10msec = !sb10msec;

}

Listing 53  Inhalt von TestDCF77.c

Um eine volle Minute aufzeichnen und auswerten zu können, muss zuerst die 59ste Sekunde gefunden werden. Erstellen sie ein Programm, das diese Sekunde findet und bei der fallenden Flanke von der nächsten Sekunde stoppt.

Die Initialisierung des Timers ist zur besseren Lesbarkeit in eine eigene Unterfunktion ausgelagert worden (siehe Listing 54, ). Für die Konfiguration von Port 2 wurde die Libraryfunktion „v_PortConfig()„ aus Kapitel 0 verwendet (siehe ). Im Gegensatz zum vorangegangenen Beispiel wird auf die steigende Flanke des DCF77-Signals gewar­tet (siehe ƒ). Ist sie gefunden, wird die Zeitmessung gestartet (siehe ). Es wird jetzt so lange gewartet, bis eine fallende Flanke erkannt wird (siehe ). Ist die gemessene Zeit größer 1,8 s (siehe ), ist die 59ste gefunden worden.

Projektname

Verzeichnis

Verwendete Sourcemodule

DCF77_59sec

Test_DCF77_59sec

FindDCF77_59sec.c

Tabelle 58  Projekt DCF77_59sec

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ƒ

 

 

 

 

 

#include <REG932.H>

#include <PortConfig.H>

 

sbit sbDCF77 = P0^0;

sbit sb10msec = P2^3;

unsigned char ucTime;

 

void v_InitTimer10msec(void)

{

  // Timer 0 für 10 msec initialisieren

  TMOD = 0x01;

  TL0 = 0xDD;

  TH0 = 0x6F;

  TF0 = 0;

  ET0 = 1;

  EA = 1;

}

 

void main(void)

{

  unsigned char Low, High;

  v_PortConfig(Port2, AllPins, BiDir); // P2 als Quasi-bidir.

  v_InitTimer10msec();

 

  while (sbDCF77 == 1);  // Warten bis fallende Flanke gefunden

  while (sbDCF77 == 0);  // Warten bis steigende Flanke gefunden

  TR0 = 1;    // Timer 0 starten

 

  while (1)

  {

     ucTime = 0;

        while (sbDCF77 == 1);

 

     if (ucTime >= 180)

     {

      TR0 = 0; // Timer 0 stoppen

     }

     while (sbDCF77 == 0);

     TL0 = 0xDD;

     TH0 = 0x6F;

  }

}

 

void v_Timer0Int(void) interrupt 1 using 1

{

  TL0 = 0xDD;

  TH0 = 0x6F;

  ucTime++;

  sb10msec = !sb10msec;

}

Listing 54  Inhalt von FindDCF77_59sec.c

Abbildung 50  DCF77-Lücke bei der 59sec

Meist sehen die DCF77-Signale aber nicht so sauber aus, wie bisher dargestellt. Leichte Änderungen des Ferritkerns zur Senderichtung oder ein störendes Umfeld, z. B. durch Ra­dio­sender ergeben folgendes DCF77-Signalbild für die Auswertung:

Abbildung 51  DCF77 gestörter Empfang

Um eine Spikeunterdrückung durchzuführen, startet der Flankenwechsel des DCF77-Signals den zweiten Timer. Ist diese Zeit abgelaufen und kein erneuter Flan­ken­wechsel aufgetreten, wird der Flankenwechsel an Portpin 2.3 ausgegeben. Abbildung 52 enthält eine Filterfunktion mit einem Timer1 Intervall von 5 ms.

Abbildung 52  DCF77 gestörter Empfang (P0.0), Filter 5ms (P2.3)

Um den Softwareaufbau und die Funktionsweise der Spikeunterdrückung nachvollzie­hen zu können, erstellen sie das Projekt aus Tabelle 59. Mit Hilfe des Makros „#define FILTER“ (siehe Listing 55, ) wird die Zeit für den Timer 1 definiert.

F !! Aufbau und Funktionsweise des Makros #define können sie im Kapitel 5 [1], in der Rubrik Makro Definitionen nachlesen. !!

Am Anfang des Programms wird der Timer 1 initialisiert (siehe ). Die Initialisierung selbst ist in Funktionen ausgelagert worden (siehe ƒ). Das Programm wartet so lan­ge, bis eine fallende Flanke gefunden wurde (siehe ). Es wird nun die Spike­unter­drü­ckung gestartet (siehe ). Ist die Zeit des Timer 1 abgelaufen und es hat kein weiterer Flankenwechsel am DCF77-Signal stattgefunden, wird der aktuelle Zustand des DCF77-Signals an P2.3 ausgegeben (siehe ). Der Timer 1 wird zudem gestoppt. Erfolgt ein Flankenwechsel während der Timer 1 läuft, wird der Timer 1 erneut aufgesetzt. Somit wird erreicht, das kurzzeitige Spikes kleiner der  Timer 1 Zeit unterdrückt werden.

Projektname

Verzeichnis

Verwendete Sourcemodule

DCF77_DetectSpike

Test_DCF77_DetectSpike

DetectSpike.c

 

..\Library

PortConfig.c

Tabelle 59  Projekt  DCF77_ DetectSpike   

 

 

 

 

 

 

 

 

 

ƒ

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

#include <REG932.H>

#include <PortConfig.H>

 

sbit sbDCF77 = P0^0;

sbit sbCleanDCF77 = P2^3;

 

unsigned char ucTime;

// Reload value 1ms (RC-Oscillator) = 0xE6A

#define FILTER 0x10000 - (5 * 0xE6A)

 

void v_InitTimer1(void)

{

  // Timer 1 für  initialisieren

  TMOD = TMOD | 0x10;

  TL1 = (unsigned char) FILTER;

  TH1 = FILTER / 256;

  TF1 = 0;

  ET1 = 1;

  EA = 1;

}

 

void v_StartFilter(void)

{

  TH1 = FILTER / 256;

  TL1 = (unsigned char) FILTER;

  TR1 = 1;  // Timer 1 starten

}

 

void main(void)

{

//  unsigned char Low, High;

  v_PortConfig(Port2, AllPins, BiDir); // P2 als Quasi-bidir.

  v_InitTimer1();

 

  while (sbDCF77 == 1);  // Warten bis fallende Flanke gefunden

  v_StartFilter();

 

  while (1)

  {

     while (sbDCF77 == 1);

     v_StartFilter();

    

     while (sbDCF77 == 0);

     v_StartFilter();

  }

}

 

void v_Timer1Int(void) interrupt 3 using 1

{

  sbCleanDCF77 = sbDCF77;

  TR1 = 0;   // Timer 1 stoppen

}

Listing 55  Inhalt DetectSpike.c

Dieser Filtermechanismus erkennt allerdings nicht, wenn die Spikes > 5 ms sind. In die­sem Fall entsteht ein Signalwechsel mit einer Zeitbreite >= 5 ms (siehe Abbildung 53). Um diese kurzzeitigen Wechsel unterdrücken zu können, muss die Startzeit des letzten Flankenwechsels abgespeichert werden.

Abbildung 53  DCF77 gestörter Empfang (P0.0), Filter 5ms (P2.3)