DCF-Dekodierung in C (mit PIC-Mikrocontroller, Elektronik)


zurück zu Elektronik, Homepage


5. Demonstrationsbeispiel

Das folgende Beispiel dient nur zur Demonstration. Es zeigt eine mögliche Einbindung der zuvor beschriebenen Unterprogramme. Bei diesem Demonstrationsbeispiel werden die Uhrzeit und das Datum abwechselnd (alle 4 Sekunden) auf 7-Segment-Anzeigen dargestellt. Weiters wird der Wochentag (Montag bis Samstag) mit Hilfe von Leuchtdioden angezeigt. Die Statusinformationen, also ob gerade ein Low, ein High oder ein ungültiges Bit empfangen wurde, werden ebenfalls mit Leuchtdioden angezeigt (siehe folgende Abbildung).

Demonstrationsbeispiel (Foto)
nach oben

5.1. Schaltung (Hardware)

Die Abbildung 8 zeigt die Schaltung für dieses Demonstrationsbeispiel.

Demonstrationsbeispiel (Schaltung)

Die Schaltung besteht aus einem Mikrocontroller (IC1) vom Typ PIC16F874, der im Abschnitt 3 (Hardware) besprochenen Anpass-Schaltung, sechs 7-Segment-Anzeigen (LD1 bis LD6) mit den zugehörigen Dekodern (IC3 bis IC8) für die Anzeige der Uhrzeit und des Datums, sowie einigen Leuchtdioden für die Statusanzeigen (D2 bis D6) sowie zur Anzeige des Wochentages (D7 bis D13) und einer einfachen Spannungsversorgung mit einem 5-V-Fixspannungsregler (IC9) vom Typ 7805.

Bei diesem Demonstrationsbeispiel werden sehr viele Portpins benötigt. Daher fiel die Wahl für den Mikrocontroller auf den PIC16F874, der insgesamt 33 Portpins besitzt, die wie Abbildung 8 zeigt auch alle benötigt werden.
Für die Takterzeugung dient eine Standardbeschaltung bestehend aus einem 4,096-MHz-Quarz (X1), zwei Kondensatoren (C3 und C4) sowie dem Widerstand R59.
Das RC-Glied (R58 und C2) erzeugt einen definierten Reset beim Anlegen der Betriebs-spannung. Zusätzlich kann mit dem Taster S2 ein Reset jederzeit ausgelöst werden.
Der Kondensator C5 dient zur Entkoppelung der Betriebsspannung für den Mikrocontroller IC1. Für diesen Koppelkondensator sollte ein Keramiktyp verwendet werden. Dieser muss möglichst nahe beim Mikrocontroller angebracht werden.

Der Wochentag ist gemäß dem DCF-Protokoll binär kodiert (der Wert 1 entspricht dem Montag und der Wert 7 entspricht dem Sonntag. Damit für jeden Wochentag eine eigene Leuchtdiode leuchtet ist ein Binär-zu-Oktal-Dekoder notwendig. Hier wird der Typ 74LS138 (IC2) verwendet.

Die Kondensatoren C10 bis C13 sind Koppelkondensatoren für die Dekoder-ICs IC2 bis IC8.

Die Stromversorgung besteht hier aus einer sehr einfachen Standardlösung. Ein Festspannungsregler (IC9) vom Typ 7805 übernimmt mit den Kondensatoren C6 bis C9 die Spannungsregelung. Die Diode D14 dient hier als Verpolungsschutz, und die Leuchtdiode D15 dient zusammen mit dem Strombegrenzungswiderstand R60 als Spannungskontrolle.

nach oben

5.2. Stückliste

Demonstrationsbeispiel (Stückliste)
nach oben

5.3. Layout und Bestückungsplan

Das Layout für dieses Demonstrationsbeispiel befindet sich im Download-Bereich auf dieser Seite, der Bestückungsplan ist in Abbildung 10 zu sehen. Der Nachbau sollte keine Probleme bereiten. Bei der Bestückung beginnt man üblicherweise mit den niedrigen Bauteilen.

Demonstrationsbeispiel (Bestückungsplan)

Achtung:
Auf der Lötseite befinden sich 13 0-Ohm-SMD-Widerstände. Diese dürfen bei der Bestückung nicht vergessen werden.
Neben dem Widerstand R59 befindet sich ein 0-Ohm-Widerstand (siehe auch Stückliste). Alternativ kann auch ein Stück Draht verwendet werden.

nach oben

5.4. Anmerkungen zur Software

Die Software zum Demonstrationsbeispiel befindet sich im Download-Bereich auf dieser Seite.

Der Quellcode für dieses Demonstrationsbeispiel wurde in C mit der freien Demoversion des mikroC-Compilers erstellt.

Die Software besteht im Wesentlichen aus den folgenden Programmteilen:

Interrupt-Service-Routine (kurz: ISR):
Die ISR (in der Datei DCF_Demo.c, Zeilen 89 bis 107) wird alle 4ms aufgerufen und besitzt hier nur die Aufgabe drei Zeitbasen (4ms, 100ms und eine Sekunde) zu erzeugen, indem sie für jede der drei Zeiten ein Botschaftsflag für das Hauptprogramm erzeugt. Das Hauptprogramm reagiert auf diese Botschaftsflags, indem es die Unterprogramme DCF_Routine (alle 4ms), DCF_Get_Status und Anzeige_Demo (alle 100 ms, zur Statusanzeige und zur Anzeige der Uhrzeit und des Datums) und DCF_Innere_Uhr (jede Sekunde) aufruft. Durch diesen Mechanismus werden diese Unterprogramm zyklisch aufgerufen.
Eine Zeitbasis von 4ms ist hier besonders einfach zu erzeugen, da ja die ISR ohnehin schon genau zu diesen Zeitabständen aufgerufen wird. Es ist also nur notwendig ein Flag zu setzen. Dieses Flag trägt hier den Namen bFlagZeitbasis4ms und befindet sich im Register cFlagISRHP. Die Erzeugung für die 100-ms-Zeitbasis ist dagegen schon etwas "umfangreicher". Damit eine Zeit von 100ms entsteht muss die ISR 25-mal aufgerufen werden (25 x 4ms = 100ms). Bei jedem ISR-Aufruf muss ein Zählregister (cZaehlerZeitbasis100ms) um eins vermindert werden. Besitzt es danach den Wert 0, so sind 100ms vergangen. Nun wird das Botschaftsflag bFlagZeitbasis100ms im Register cFlagISRHP gesetzt und das Zählregister muss mit dem Wert 25 neu geladen werden. Der Wert 25 wird hier durch die Konstante KONSTZEITBASIS100MS ersetzt. Die Ein-Sekunden-Zeitbasis wird genauso wie die 100-ms-Zeitbasis erzeugt. Jedes Mal wenn 100ms vergangen sind wird das Zählregister cZaehlerZeitbasis1sek um eins vermindert. Besitzt es danach den Wert 0, so ist eine Sekunde vergangen. Nun wird das Botschaftsflag bFlagZeitbasis1sek im Register cFlagISRHP gesetzt und das Zählregister muss mit dem Wert 10 (10 x 100ms = 1000ms = 1 Sekunde) neu geladen werden. Der Wert 10 wird hier durch die Konstante KONSTZEITBASIS1SEK ersetzt.
Die Zeit von 4ms ergibt sich, weil als Takt ein 4,096-MHz-Quarz verwendet wird und weil der Vorteiler (VT) im Register OPTION_REG mit dem Wert 1:16 geladen wird (Zeile 141 im Unterprogramm Init).

Formel (ISR)

Hauptprogramm:
Zuerst müssen der Mikrocontroller und die für die DCF-Dekodierung globalen Register initialisiert werden. Diese Aufgaben werden von den Unterprogrammen Init (Zeile 393) und DCF_Init (Zeile 396) ausgeführt.

Nun befindet sich das Hauptprogramm in einer Endlosschleife. Diese Schleife besitzt die Aufgabe ständig die so genannten Botschaftsflags abzufragen. Ist eines dieser Botschaftsflags gesetzt, so muss vom Hauptprogramm eine bestimmte Aufgabe ausgeführt werden. Diese Aufgaben sind in Form von Unterprogrammen vorhanden.

Hier die Tätigkeiten in der Endlosschleife, welche durch die Botschaftsflags ausgelöst werden:

Achtung:
Die Botschaftsflags müssen nach der Ausführung der Aufgaben wieder gelöscht werden, da diese Aufgaben sonst ununterbrochen wiederholt werden!
Wichtig:
Gemäß dem DCF-Dekodierverfahren (siehe Abschnitt 4.1) muss jede Sekunde das Unterprogramm DCF_UP_Sekunde aufgerufen werden. Weiters muss jede Minute das Unterprogramm DCF_UP_Minute aufgerufen werden. Auch hier bestimmen zwei "Botschaftsflags" wann diese beiden Unterprogramme aufgerufen werden müssen. Diese Botschaftsflags werden aber im Unterprogramm DCF_Routine (in der Datei DCF.C) gesetzt, und können daher, wegen der so genannten Datenkapselung, nicht direkt gelesen werden. Für das Lesen dieser Flags sind daher wieder eigene Unterprogramme notwendig. Die Unterprogramme DCF_Is_Neue_Sekunde bzw. DCF_Is_Neue_Minute haben daher die Aufgabe als Rückgabewert den Wert der Botschaftsflags an das aufrufende Hauptprogramm zu übergeben. Die Zeilen 440 bis 444 zeigen diesen vielleicht etwas kompliziert erscheinenden Sachverhalt.

Unterprogramm Init:
Das Unterprogramm Init (Datei: DCF_Demo.c, Zeilen 137 bis 316) dient zur Initialisierung des Mikrocontrollers. Hier werden unter anderem die Ports konfiguriert (Port dient als Eingang oder als Ausgang), der oder die Timer eingestellt usw. Dieses Unterprogramm ist vom Controllertyp abhängig und je nach Anwendung mehr oder weniger umfangreich.
In diesem Unterprogramm werden auch die globalen Register initialisiert. Hier, bei diesem Demonstrationsbeispiel die Zählregister für die 100-ms-Zeitbasis (Zeile 284) und für die 1-Sekunden-Zeitbasis (Zeile 286).

Unterprogramm Anzeige_Demo:
Das Unterprogramm Anzeige_Demo (Datei: DCF_Demo.c, Zeilen 347 bis 370) ist das wesentliche Unterprogramm für die Ausgabe der Uhrzeit, des Datums und des Wochentages.
Dieses Unterprogramm ist eigentlich sehr einfach, so dass hier keine weitere Erklärung notwendig ist. Wichtig ist nur, dass es vom Hauptprogramm regelmäßig (zyklisch) aufgerufen werden muss (siehe Hauptprogramm, Datei: DCF_Demo.c, Zeile 423).

Unterprogramme zur DCF-Dekodierung:
Diese Unterprogramme befinden sich in der Datei DCF.C und wurden bereits im Abschnitt 4 (Software) sehr ausführlich behandelt, so dass sie hier nicht mehr näher erläutert werden müssen.

Wichtig:
In der Datei DCF.H muss der Portpin (bDCF_Port_In) gemäß der Demonstrationsschaltung nach Abbildung 8 definiert werden. Hier also der Portpin RA4, Zeile 18.

Sonstiges:
Am Beginn des Quellcodes (in der Datei DCF_Demo.c) befinden sich die folgenden Definitionen und Einstellungen:

Ein kleiner Nachteil beim mikroC-Compiler ist, dass die Konfigurationsbits für den PIC-Mikrocontroller in der IDE gesetzt werden müssen. Ich persönlich würde diese lieber im Quellcode mit einer geeigneten Anweisung setzen.

Hier sind die notwendigen Einstellungen für den PIC16F874 für dieses Demonstrationsbeispiel:

nach oben


zurück zu Elektronik, Homepage

Autor: Stefan Buchgeher
Erstellt: 21. Februar 2010
Letzte Änderung: 25. März 2010