53
DCF-Dekodierung mit PIC-Mikrocontroller in C Stefan Buchgeher 25. M¨ arz 2010 www.stefan-buchgeher.info [email protected] Großambergstraße 106/3, A-4040 Linz ( ¨ Osterreich) ++43/699/11 29 63 38

DCF-Dekodierung mit PIC-Mikrocontroller in C · 2Der mikroC-Compiler wurde von der Firma mikroElektronika [2] ... Dieses Modul enth¨alt eine Empfangsantenne und einen Demodulator,

Embed Size (px)

Citation preview

DCF-Dekodierung mitPIC-Mikrocontroller in C

Stefan Buchgeher

25. Marz 2010

www.stefan-buchgeher.info� [email protected]� Großambergstraße 106/3, A-4040 Linz (Osterreich)� ++43/699/11 29 63 38

INHALTSVERZEICHNIS 1

Inhaltsverzeichnis

1 Einleitung 1

2 Grundlagen zu DCF 2

3 Hardware 5

4 Software 64.1 Das Dekodierverfahren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74.2 Benotigte Register, Konstanten und Portdefinition fur die DCF-Dekodierung 84.3 Unterprogramme fur die DCF-Dekodierung . . . . . . . . . . . . . . . . . . 11

5 Demonstrationsbeispiel 235.1 Schaltung (Hardware) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235.2 Stuckliste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255.3 Layout und Bestuckungsplan . . . . . . . . . . . . . . . . . . . . . . . . . . 265.4 Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275.5 Anmerkungen zur Software . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

1 Einleitung

Der Zeitsignalsender DCF77 ist ein Langwellensender in Mainflingen (Deutschland), derdie meisten funkgesteuerten Uhren im westlichen Europa mit der genauen Uhrzeit ver-sorgt. Die Bezeichnung DCF77 ist das Rufzeichen der Internationalen Frequenzliste desIFRB1. Es leitet sich ab von D fur Deutschland, C fur Langwellensender, F wegen derNahe zu Frankfurt, sowie der Zahl 77 fur die Tragerfrequenz 77,5 kHz.[1]Andere bekannte Zeitdienste sind HBG in der Schweiz (75 kHz), MSF in England (60kHz) und die Sendergruppen RWM in Russland und WWV, WWVB, WWVH in denUSA.[1]

Uber DCF77 sendet die Physikalisch-Technische Bundesanstalt (PTB) in Braunschweigseit 1959 eine Normalfrequenz und seit 1973 zusatzlich dazu ein Datensignal fur Datumund Uhrzeit.Als Zeitbasis zur Erzeugung des Zeitsignals dient am Senderstandort eine hochgenaueSpezialuhr, die ihrerseits mit den bei der PTB in Braunschweig stationierten Atomuhrenabgeglichen wird (derzeit drei Casium-Uhren und seit 1999 eine Casium-Fontane). Das sogewonnene Signal hat am Sendeort als Genauigkeit eine relative Standardabweichung vonmaximal 10−12. Dies entspricht einem Fehler von einer Sekunde in etwa 30.000 Jahren.[1]

Diese Arbeit zeigt wie man mit einem Mikrocontroller aus der PIC16Fxx-Familie dasDCF-Telegramm dekodiert und daraus die Uhrzeit und das Datum erhalt. Der Mikrocon-troller benotigt ausser einem Timer keine besonderen Hardwaremodule. Die Idee der hier

1IFRB steht fur International Frequency Registration Board, einem Standardisierungsgremium zurFrequenzvergabe und Klarung technischer Fragen der Funkubertragung

2 GRUNDLAGEN ZU DCF 2

beschriebenen Dekodiermethode kann daher mit jedem beliebigen Mikrocontroller (auchvon anderen Herstellern) realisiert werden.

Als Demonstrationsbeispiel wird eine einfache Uhr mit Datum und Wochentagsanzeigerealisiert. Als Anzeige dienen 7-Segment-Anzeigen. Die Uhrzeit und das Datum werdenabwechselnd, je 4 Sekunden lang, an den 7-Segment-Anzeigen angezeigt.

Als Programmiersprache fur die PIC-Mikrocontroller-Software wurde C mit dem mikroC-Compiler2 verwendet. Fur das Demonstrationsbeispiel (ab Seite 23) ist die kostenloseDemoversion3 ausreichend.

2 Grundlagen zu DCF

Der Zeitzeichensender DCF77 befindet sich in Mainflingen, ca. 25 km sudostlich vonFrankfurt am Main. Dieser Langwellensender hat, bedingt durch die niedrige Tragerfre-quenz von 77,5 kHz eine Reichweite von ca. 1500 km bis 2000 km. (Abbildung 1)

Abbildung 1: Reichweite des DCF77-Senders, (Quelle: [3])

Der Dauertrager des DCF-Senders senkt im Sekundentakt fur 100ms oder 200ms die Am-plitude der Tragerfrequenz auf 25 % ab, was einer einfachen Amplitudenmodulation ent-spricht. Die Lange dieser so genannten Sekundenmarken ubertragt in codierter Form dasZeittelegramm. Eine Absenkdauer des Tragers um 100ms (Toleranz: ±20ms) entspricht

2Der mikroC-Compiler wurde von der Firma mikroElektronika [2] entwickelt und dient zum Program-mieren der PIC16Fxx-Familie in der Hochsprache C

3Die freie Demoversion ist nur auf eine Programmspeichergroße von 2k begrenzt. Ansonst voll kom-patibel zur Vollversion. Die Demoversion ist auf der Firmen-Webseite [2] downloadbar

2 GRUNDLAGEN ZU DCF 3

dabei einem logischen Low-Pegel, wahrend ein logischer High-Pegel mit einer Absenkdauervon 200ms (Toleranz: ±40ms) codiert ist. In jeder 59. Sekunde wird die Absenkung nichtvorgenommen, so dass damit eine eindeutige Zuordnung des Minutenanfangs moglich ist.Die neue Sekunde beginnt, mit Ausnahme der 59. Sekunde, jeweils mit dem Absenken des77,5 kHz-Tragers. (Abbildung 2)

Abbildung 2: Amplitudenmodulation des 77,5kHz-Tragers

Im jeweils einminutigem Zeittelegramm ist die Zeit (Stunde und Minute) der nachst fol-genden Minute sowie das gesamte Datum und der jeweilige Wochentag codiert. (Abbildung3 und Tabelle 1)

Abbildung 3: Kodierschema

2 GRUNDLAGEN ZU DCF 4

Bit Bedeutung Wert- Gespeichert Bit Bedeutung Wert- Gespeichert

igkeit igkeit

0 Minutenbeginn Low 30 Stunden Einer 2 cDCF Telegramm4.4

1 Wetterdaten 31 Stunden Einer 4 cDCF Telegramm4.3

2 Wetterdaten 32 Stunden Einer 8 cDCF Telegramm4.2

3 Wetterdaten 33 Stunden Zehner 10 cDCF Telegramm4.1

4 Wetterdaten 34 Stunden Zehner 20 cDCF Telegramm4.0

5 Wetterdaten 35 Prufbit 2 cDCF Telegramm3.7

6 Wetterdaten 36 Kalendertag Einer 1 cDCF Telegramm3.6

7 Wetterdaten 37 Kalendertag Einer 2 cDCF Telegramm3.5

8 Wetterdaten 38 Kalendertag Einer 4 cDCF Telegramm3.4

9 Wetterdaten 39 Kalendertag Einer 8 cDCF Telegramm3.3

10 Wetterdaten 40 Kalendertag Zehner 10 cDCF Telegramm3.2

11 Wetterdaten 41 Kalendertag Zehner 20 cDCF Telegramm3.1

12 Wetterdaten 42 Wochentag 1 cDCF Telegramm3.0

13 Wetterdaten 43 Wochentag 2 cDCF Telegramm2.7

14 Wetterdaten 44 Wochentag 4 cDCF Telegramm2.6

15 Reserveantenne cDCF Telegramm6.3 45 Monat Einer 1 cDCF Telegramm2.5

16 Ank. Zeitumstellung cDCF Telegramm6.2 46 Monat Einer 2 cDCF Telegramm2.4

17 Zeitzonenbit 1 cDCF Telegramm6.1 47 Monat Einer 4 cDCF Telegramm2.3

18 Zeitzonenbit 2 cDCF Telegramm6.0 48 Monat Einer 8 cDCF Telegramm2.2

19 Ank. Schaltsekunde cDCF Telegramm5.7 49 Monat Zehner 10 cDCF Telegramm2.1

20 Telegrammbeginn High 50 Jahr Einer 1 cDCF Telegramm2.0

21 Minuten Einer 1 cDCF Telegramm5.5 51 Jahr Einer 2 cDCF Telegramm1.7

22 Minuten Einer 2 cDCF Telegramm5.4 52 Jahr Einer 4 cDCF Telegramm1.6

23 Minuten Einer 4 cDCF Telegramm5.3 53 Jahr Einer 8 cDCF Telegramm1.5

24 Minuten Einer 8 cDCF Telegramm5.2 54 Jahr Zehner 10 cDCF Telegramm1.4

25 Minuten Zehner 10 cDCF Telegramm5.1 55 Jahr Zehner 20 cDCF Telegramm1.3

26 Minuten Zehner 20 cDCF Telegramm5.0 56 Jahr Zehner 40 cDCF Telegramm1.2

27 Minuten Zehner 40 cDCF Telegramm4.7 57 Jahr Zehner 80 cDCF Telegramm1.0

28 Prufbit 1 cDCF Telegramm4.6 58 Prufbit 329 Stunden Einer 1 cDCF Telegramm4.5 59 keine Austastung

Tabelle 1: Zeittelegramm

Die Synchronisation des Sekundenzahlers erfolgt mit dem Ausbleiben der Absenkung der59. Sekunde. Die nachste Absenkung ist immer Low. In den Bits 1 bis 14 sind seit Novem-ber 2006 Wetterdaten verschlusselt. Bit 15 zeigt durch einen High-Pegel an, dass zurzeitdie Reserveantenne des DCF77-Senders aktiv ist. Im Normalfall ist dieses Bit auf

”Low“

gesetzt. Bit 16 wird eine Stunde bevor die Zeitumstellung von Sommer- auf Winterzeitbzw. umgekehrt erfolgt auf

”high“ gesetzt und mit der Zeitumstellung wieder zuruckge-

setzt. Die Zeitangaben beziehen sich auf die UTC-Zeit4. Bezogen auf die UTC-Zeit eiltdie mitteleuropaische Zeit (MEZ) um eine Stunde vor, wahrend die mitteleuropaischeSommerzeit (MESZ) um 2 Stunden voreilt. Diese Differenz wird in den Zeitzonenbits 17und 18 ausgedruckt. Wahrend der MEZ ist Bit 17 High und Bit 18 Low, wahrend beider Sommerzeit (MESZ) der Abstand zur UTC 2 Stunden betragt und somit Bit 17 Lowund Bit 18 High ist. Bit 19 kundigt eine bevorstehende Schaltsekunde an. Das eigentlicheZeit- und Datumstelegramm ist in den Bits 20 bis 58 codiert. Fur die Einerstellen der Zeitund Datumsinformationen sind jeweils 4 Bit, wahrend fur die Zehnerstellen nur 2 oder3 Bit erforderlich sind. Die Zahlendarstellung der Zeit- und Datumsinformation erfolgtim Binarformat (BCD-Code). Fur die Jahreszahl werden nur die Einer- und Zehnerstelleubertragen. Die Bits 42 bis 44 geben in binarer Schreibweise den Wochentag an (der Wert1 steht fur den Montag, der Wert 7 fur den Sonntag). Das Prufbit 1 erganzt die Bits 21bis 27 auf gerade Paritat, d.h. es werden die High-Bits 21 bis einschließlich 28 addiert,deren Ergebnis muss dann eine gerade Zahl ergeben. Das Prufbit 2 erganzt die Paritatvon Bit 29 bis 34, wahrend Prufbit 3 fur die Paritat der Bits 36 bis 57 zustandig ist. Diese

4UTC steht fur Universal Time Coordinated

3 HARDWARE 5

Prufbits sind ein erstes Uberprufungskriterium fur ein DCF-Empfangsprogramm, welchesdamit zunachst auf einfache Weise die Konformitat der empfangenen Daten uberprufenkann. Fur eine fehlerfreie DCF-Decodierung sind allerdings noch weitere Maßnahmen not-wendig. (Zum Beispiel ein Vergleich der soeben dekodierten Uhrzeit und des Datums mitder Uhrzeit und dem Datum welches mit der vorhergehenden Minute ubertragen wurdeund zusatzlich noch eine mitlaufende Softwareuhr).

In unregelmaßigen Zeitabstanden muss eine Schaltsekunde eingefugt werden. Dies ist da-durch bedingt, dass sich die Erde nicht genau in 24 Stunden um sich selbst dreht. Aufdie koordinierte Weltzeitskala UTC bezogen, wird diese Korrektur zum Ende der letztenStunde des 31. Dezember oder 30. Juni vorgenommen. In Mitteleuropa muss die Schaltse-kunde daher am 1. Januar um 1.00 Uhr MEZ oder am 1. Juli um 2.00 MESZ eingeschobenwerden. Zu den genannten Zeiten werden daher 61 Sekunden gesendet.

3 Hardware

Die Hauptkomponente zur DCF-Dekodierung ist ein bei der Firma Conrad ElectronicGmbH & Co KG erhaltliches DCF-Empfangsmodul (Bestell-Nr.: 64 11 38, Abbildung 4).Dieses Modul enthalt eine Empfangsantenne und einen Demodulator, so dass am Ausgangdes Moduls das ubertragene Zeittelegramm mit einem Mikrocontroller ausgewertet werdenkann.

Abbildung 4: DCF-Empfangsmodul

Der Ausgangsstrom von nur einem Milliampere ist fur die Kontroll-LED (D1) zuwenig.Die nachgeschaltete Transistorstufe (T1) mit den Widerstanden R1 und R2 (Abbildung 5)gleicht diesen Nachteil aus. Der Widerstand R2 dient als Vorwiderstand fur die Leuchtdi-ode (D1). Diese Leuchtdiode signalisiert den empfangenen Datenstrom. Bei einem korrek-ten Empfang blinkt diese Leuchtdiode im Sekundentakt. Dieses Blinken zeigt sozusagenden Ausgangspegel der Anpass-Schaltung an. Das Puls-Pausen-Verhaltnis (Leuchtzeit/-Dunkelzeit der Leuchtdiode D1) entspricht der im Abschnitt 2 genannten Zeiten. Bei etwasUbung kann der Unterschied zwischen Low (100ms Absenkung des Tragers, LED ist 100msdunkel) und High (200ms Absenkung des Tragers, LED ist 200ms dunkel) optisch erkanntwerden.

Der Kondensator C1 dient zur Entkoppelung der Betriebsspannung fur das DCF-Modul(DCF1). Fur diesen Koppelkondensator sollte ein Keramiktyp verwendet werden. Dieser

4 SOFTWARE 6

muss moglichst nahe am DCF-Modul angebracht werden.

Abbildung 5: Anpass-Schaltung

4 Software

Die Aufgabe der PIC-Software besteht bei der DCF-Dekodierung aus mehreren Teilauf-gaben:

1. In kurzen Zeitabstanden (ca. alle 4ms) das vom DCF-Empfangsmodul (DCF1) er-zeugte Signal abtasten. Daraus entweder ein Low, ein High oder eine neue Minuteermitteln. Kann aus den Abtastungen keines dieser drei Falle ermittelt werden, sohandelt es sich um einen Telegrammfehler.

2. Die empfangenen Low- und High-Pegel zwischenspeichern.

3. Bei jeder neuen Minute aus den gespeicherten Werten entsprechend Tabelle 1 (Seite4) die Zeit- und Datumswerte zusammensetzen und in entsprechenden Registernsichern.

4. Das soeben ermittelte Telegramm mit dem Telegramm der vorhergehenden Minutevergleichen. Die soeben ermittelte Minute muss dabei um 1 großer als die vorher-gehende Minute sein, und die soeben ermittelten Werte fur die Stunde, den Tag,den Monat, das Jahr und den Wochentag mussen mit den Werten des vorherge-henden Telegramms ubereinstimmen. Achtung: Bei dieser einfachen Uberprufungwird der Ubergang von z. B. 13:59 auf 14:00 als falsch gewertet, da sich hier dieStunde andert, und auch die Minute um mehr als 1. Wurden hier alle moglichenUbergange berucksichtigt, dann wurde dieses Unterprogramm noch umfangreicherals es ohnehin schon ist. Durch diese Vereinfachung dauert die Synchronisierung imschlimmsten Fall nur eine Minute langer.

5. Parallel zur DCF-Uhr eine reine Softwareuhr erzeugen. Diese Softwareuhr ist gultig,wenn keine korrekte Zeit vom DCF-Empfangsmodul empfangen wird. Mit ande-ren Worten. Die Softwareuhr wird standig mit einer gultig dekodierten

”DCF-Zeit“

synchronisiert. Dies gilt naturlich auch fur die Datumsinformationen.

4 SOFTWARE 7

4.1 Das Dekodierverfahren

Der PIC-I/O-Eingang, an dem das DCF-Empfangsmodul (mit einer Anpass-Schaltung)angeschlossen ist, wird zyklisch (ca. alle 4 ms) vom Unterprogramm DCF Routine abge-fragt. Als Zeitbasis fur den 4-ms-Takt dient der Timer-0-Interrupt. Dieser kann je nachAnwendung entweder so eingestellt werden, dass er alle 4 ms einen Interrupt auslost, oderer wird so eingestellt dass er z. B. alle 500µs oder alle 1ms einen Interrupt erzeugt und einZahlregister zahlt die notwendige Anzahl an Interruptaufrufen bis zu einer Zeitbasis von4 ms. Hier in dieser Dokumentation wird der Einfachheit halber die erstere Variante ver-wendet. Der Aufruf des Unterprogramms DCF Routine erfolgt hier aber nicht von der ISR(Interrupt-Service-Routine), sondern vom Hauptprogramm. Die ISR setzt nur alle 4 msein Flag zur Kennzeichnung, dass das Hauptprogramm das Unterprogramm DCF Routine

aufrufen soll.

Die Aufgabe des Unterprogramms DCF Routine besteht nun darin, aus dem vom DCF-Empfangsmodul empfangenen Datenstrom die Informationen LOW, HIGH und den Minu-tenwechsel (also das Ausbleiben der 59. Sekunde) gemaß dem im Abschnitt 2 (Grundlagenzu DCF) gewonnen Erkenntnisse zu dekodieren. Fur diese Informationen befinden sich imDCF-Statusregister (cDCF Status) entsprechende Flags. (siehe Abschnitt 4.2, BenotigteRegister, Konstanten und Portdefinition).Ein weiteres Register (cDCF Hilfsregister) beinhaltet den Zustand des DCF-Eingangs4 ms vor dem Aufruf des Unterprogramms DCF Routine. Mit Hilfe des aktuellen Zustandsund des Zustands vor 4 ms kann nun erkannt werden, ob sich der Pegel am DCF-Einganggeandert hat.

Das Hauptprogramm pruft nun standig die Flags bDCF Neue Sekunde (wird zusatzlichzu bDCF Low bzw. bDCF High gesetzt, wenn eine gultige Sekunde empfangen wurde) undbDCF Neue Minute, und ruft die Unterprogramme DCF UP Sekunde bzw. DCF UP Minute

auf. Die Aufgabe des Unterprogramms DCF UP Sekunde ist es, die empfangenen Low- undHigh-Pegel in den Register cDCF Telegramm1 bis cDCF Telegramm8 zwischenzuspeichern.Die Aufgabe des Unterprogramms DCF UP Minute ist etwas umfangreicher: Zunachst dieZeit und das Datum aus den in den Registern cDCF Telegramm1 bis cDCF Telegramm8 zwi-schengespeicherten Werten entsprechend Tabelle 4 (Seite 4) zusammensetzen. Anschlie-ßend die soeben gewonnen Zeit- und Datumsinformationen mit den Zeit- und Datums-informationen der vorhergehenden Minute vergleichen. Die Zeit- und Datumswerte dersoeben empfangenen Minute sind nur dann gultig, wenn sich die Minute um maximal 1von der vorhergehenden Minute unterscheidet, wahrend sich die restlichen Zeit- und Da-tumsinformationen mit denen der vorhergehenden Minute nicht unterscheiden. Dies istnur eine einfache Uberprufung, die aber manche richtigen Telegramme als falsch auswer-tet. (Siehe Abschnitt 4.3, Unterprogramme fur die DCF-Dekodierung, ab Seite 11).

Parallel zur Dekodierung des DCF-Eingangs erzeugt das Unterprogramm DCF Innere Uhr

eine reine Softwareuhr. Fur diesen Zweck ist eine genaue 1-Sekunden-Zeitbasis notwendig.Diese Zeitbasis wird von der schon erwahnten Timer-0-ISR (Interrupt Service Routine)zusatzlich zur 4ms-Zeitbasis erzeugt. Auch fur diese Zeitbasis wird in der ISR ein entspre-chendes Flag gesetzt, und das Hauptprogramm ruft das Unterprogramm DCF Innere Uhr

auf, wenn dieses Flag gesetzt ist. Diese zusatzliche Softwareuhr mag auf dem ersten Blick

4 SOFTWARE 8

unnotig erscheinen. Es hat sich aber gezeigt, dass ein DCF-Empfang oft auch uber einelangere Zeit nicht moglich ist. In diesem Fall wurde die Uhr

”stehen“ bleiben. Diese Zeit

wird mit einer zusatzlichen Softwareuhr so uberbruckt, dass der Betrachter der Uhr davonnichts bemerkt.

4.2 Benotigte Register, Konstanten und Portdefinition fur dieDCF-Dekodierung

Register:Fur die DCF-Dekodierung sind neben einigen internen Registern (SFR, Spezielle Funktions-Register) noch eine ganze Menge eigener Register notwendig:

cDCF Status: Statusregister fur die DCF-Dekodierung. Dieses Register beinhaltet folgen-de Bits:

Bit Flagname Funktion

0 bDCF Low gesetzt, wenn Low-Pegel erkannt1 bDCF High gesetzt, wenn High-Pegel erkannt2 bDCF Bitfehler gesetzt, wenn weder High noch Low3 bDCF Fehler gesetzt, wenn ein Fehler erkannt4 bDCF Sync gesetzt, wenn Uhr mit DCF synchronisiert

Tabelle 2: Zusammensetzung von cDCF Status

cDCF Hilfsregister: Hilfsregister fur die DCF-Dekodierung. Dieses Register beinhaltetfolgende Bits:

Bit Flagname Funktion

0 bDCF Port Neu Akt. Zustand DCF-Porteingang1 bDCF Port Alt Vorhergehender Zustand am DCF-Porteingang2 bDCF Neue Sekunde gesetzt, wenn neue Sekunde begonnen3 bDCF Neue Minute gesetzt, wenn neue Minute begonnen

Tabelle 3: Zusammensetzung von cDCF Hilfsregister

cDCF Puls, cDCF Pause: Zahlregister zur Ermittlung der Pulsdauer bzw. Pausendauerbei der DCF-Dekodierung (Anmerkung: Bei diesen beiden Registern handelt es sichum statische Register im Unterprogramm DCF Routine)

Abbildung 6: Puls und Pause

cDCF Telegramm1 - cDCF Telegramm8: In diese Register wird das empfangene, neue DCF-Telegramm im Sekundentakt eingelesen. Beginnt eine neue Minute, so werden dieseRegister ausgewertet und in die entsprechenden Register kopiert, z.B. in das RegistercDCF Minute BCD.

4 SOFTWARE 9

cDCF Minute BCD: Beinhaltet die dekodierte, aktuelle Minute im BCD-Format.

cDCF Stunde BCD: Beinhaltet die dekodierte, aktuelle Stunde im BCD-Format.

cDCF Tag BCD: Beinhaltet den dekodierten, aktuellen Tag im BCD-Format.

cDCF Monat BCD: Beinhaltet den dekodierten, aktuellen Monat im BCD-Format.

cDCF Jahr BCD: Beinhaltet das dekodierte, aktuelle Jahr im BCD-Format, wobei nur dieEiner- und die Zehnerstelle im DCF-Telegramm enthalten sind. Die Hunderter- unddie Tausenderstelle befinden sich nicht im DCF-Telegramm.

cDCF Wochentag: Beinhaltet den dekodierten, aktuellen Wochentag, wobei folgende Ta-belle gilt:

Wert Bedeutung

1 Montag2 Dienstag3 Mittwoch4 Donnerstag5 Freitag6 Samstag7 Sonntag

Tabelle 4: Wochentag

cDCF Zusatzinfos: Beinhaltet weitere, folgende Informationen, die im DCF-Telegrammenthalten sind:

Bit Flagname Funktion

0 bDCF Rerserveantenne Ist dieses Bit gesetzt so wurde die Reserveantenne zum Versendendes DCF-Telegramms verwendet

1 bDCF Zeitumstellung Ist dieses Bit gesetzt, so kundigt es eine Umstellungzwischen Sommer- und Winterzeit an. Dieses Bit wird eine Stundevor der Zeitumstellung gesetzt. Ab der Zeitumstellung enthaltes wieder den Wert 0

2 bDCF Sommerzeit Wahrend der Sommerzeit ist dieses Bit gesetzt3 bDCF Winterzeit Wahrend der Winterzeit ist dieses Bit gesetzt4 bDCF Schaltsekunde Ist dieses Bit gesetzt, so kundigt es eine Schaltsekunde an

Tabelle 5: Zusammensetzung von cDCF Zusatzinfos

cDCF Minute Alt: Beinhaltet die empfangene Minute des DCF-Telegramms, welches mitder vorangegangenen Minute empfangen wurde. Diese wird zur Uberprufung desneuen DCF-Telegramms verwendet.

cDCF Stunde Alt: Beinhaltet die empfangene Stunde des DCF-Telegramms, welches mitder vorangegangenen Minute empfangen wurde. Diese wird zur Uberprufung desneuen DCF-Telegramms verwendet.

cDCF Tag Alt: Beinhaltet den empfangenen Tag des DCF-Telegramms, welcher mit dervorangegangenen Minute empfangen wurde. Dieser wird zur Uberprufung des neuenDCF-Telegramms verwendet.

cDCF Monat Alt: Beinhaltet den empfangenen Monat des DCF-Telegramms, welcher mitder vorangegangenen Minute empfangen wurde. Dieser wird zur Uberprufung desneuen DCF-Telegramms verwendet.

4 SOFTWARE 10

cDCF Jahr Alt: Beinhaltet das empfangene Jahr des DCF-Telegramms, welches mit dervorangegangenen Minute empfangen wurde. Dieses wird zur Uberprufung des neuenDCF-Telegramms verwendet.

cDCF Wochentag Alt: Beinhaltet den empfangenen Wochentag des DCF-Telegramms, wel-cher mit der vorangegangenen Minute empfangen wurde. Dieser wird zur Uber-prufung des neuen DCF-Telegramms verwendet.

cUhr Sekunde: Sekundenzahler der inneren quarzgesteuerten Uhr. (Wird mit jedem gulti-gen DCF-dekodierten Wert synchronisiert).

cUhr Minute: Minutenzahler der inneren quarzgesteuerten Uhr. (Wird mit jedem gultigenDCF-dekodierten Wert synchronisiert).

cUhr Stunde: Stundenzahler der inneren quarzgesteuerten Uhr. (Wird mit jedem gultigenDCF-dekodierten Wert synchronisiert).

cDatum Wochentag: Wochentagszahler der inneren quarzgesteuerten Uhr. (Wird mit je-dem gultigen DCF-dekodierten Wert synchronisiert).

cDatum Tag: Tageszahler der inneren quarzgesteuerten Uhr. (Wird mit jedem gultigenDCF-dekodierten Wert synchronisiert).

cDatum Monat: Monatszahler der inneren quarzgesteuerten Uhr. (Wird mit jedem gulti-gen DCF-dekodierten Wert synchronisiert).

cDatum Jahr: Jahreszahler der inneren quarzgesteuerten Uhr. (Wird mit jedem gultigenDCF-dekodierten Wert synchronisiert).

Konstanten:Bei einem LOW dauert die Absenkung des Tragers zwischen 80ms und 120ms, fur einHIGH dauert die Absenkung des Tragers zwischen 160ms und 240ms (siehe auch Abschnitt2, Grundlagen zu DCF, ab Seite 2). Die Konstanten KONSTDCFLMIN, KONSTDCFLMAX,KONSTDCFHMIN und KONSTDCFHMAX dienen zur Ermittlung eines LOW oder eines HIGH.Das Unterprogramm DCF Routine wird alle 4ms aufgerufen, daher ergeben sich fur dieseKonstanten folgende Werte:

KONSTDCFLMIN: 20 (20 x 4ms = 80ms)KONSTDCFLMAX: 30 (30 x 4ms = 120ms)KONSTDCFHMIN: 40 (40 x 4ms = 160ms)KONSTDCFHMAX: 60 (60 x 4ms = 240ms)

Es kann erforderlich sein, dass bei einer Anwendung die PIC-Taktfrequenz erhoht werdenmuss. In diesem Fall kann es notwendig sein, diese Konstanten anzupassen.

Die Konstante KONSTDCFNEUEMIN wird wur die Erkennung einer neuen Minute benotigt.Zur Erinnerung: Eine neue Minute wird im DCF-Telegramm durch das Ausbleiben der59. Sekunde definiert.

Die Konstanten sind in der Datei DCF.H definiert (Listing 1):

4 SOFTWARE 11

2021 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Konstanten ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/22 /∗ ISR wird a l l e 4 ms aufgeru f en ∗/23 #define KONSTDCFLMIN 2024 #define KONSTDCFLMAX 3025 #define KONSTDCFHMIN 4026 #define KONSTDCFHMAX 602728 #define KONSTDCFNEUEMIN 2502930 /∗ ISR wird a l l e 10 ms aufgeru f en ∗/31 //#de f i n e KONSTDCFLMIN 832 //#de f i n e KONSTDCFLMAX 1233 //#de f i n e KONSTDCFHMIN 1634 //#de f i n e KONSTDCFHMAX 243536 //#de f i n e KONSTDCFNEUEMIN 100

Listing 1: Konstanten fur die DCF-Dekodierung (Auszug aus DCF.H)

Portdefinition:Im Allgemeinen wird bei jeder Anwendung der Eingangspin fur die DCF-Dekodierungan einem anderen Portpin verwendet. Damit dies in der Software nur an einer Stelleberucksichtigt werden muss befindet sich in der Software eine Portdefinition fur den DCF-Eingang (Datei: DCF.H, Listing 2).

1617 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Portbelegung ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/18 #define bDCF Port In PORTA. F4

Listing 2: Portdefinition fur die DCF-Dekodierung (Auszug aus DCF.H)

Achtung:Beim Initialisieren des PIC-Mikrocontroller (bei mir im Unterprogramm Init)muss dieser Portpin als Eingang konfiguriert werden. Siehe Demonstrationsbei-spiel (Abschnitt 5 ab Seite 23).

4.3 Unterprogramme fur die DCF-Dekodierung

Zur DCF-Dekodierung sind 4 Unterprogramme notwendig:

• DCF Init

• DCF Routine

• DCF UP Sekunde

• DCF UP Minute

Weiters das Unterprogramm DCF Innere Uhr. Dieses Unterprogramm sorgt dafur, dass,wenn kein gultiges DCF-Telegramm empfangen werden kann, die Uhrzeit trotzdem jedeSekunde aktualisiert wird. Ist fur eine langere Zeit kein korrekter DCF-Empfang moglich,

4 SOFTWARE 12

so wurden die Minuten, die Stunden, die Tage usw.”stehen“ bleiben, da im Unterpro-

gramm DCF UP Minute nur gultige DCF-Telegramme ubernommen werden.

Ein großes Plus des mikroC-Compilers ist, dass die globalen Register, die in einer C-Datei definiert sind, nicht von Unterprogrammen (oder vom Hauptprogramm) aus ande-ren C-Dateien benutzt werden konnen. Dadurch entsteht eine Art Datenkapselung, und

”ungewollte“ Registermanipulationen werden dadurch vermieden. Der mikroC-Compiler

erzeugt eine Fehlermeldung, falls versucht wird ein globales Register aus einer anderenC-Datei anzusprechen.Bei der DCF-Dekodierung sind aber die Uhrzeit und das Datum, sowie andere nutzli-che Flags und Variablen in solchen Registern abgelegt. Damit vom Hauptprogramm odervon Unterprogrammen der Inhalt dieser Register gelesen werden kann, sind eine Reihevon Unterprogrammen notwendig, die als Ruckgabeparameter den Inhalt des gewunsch-ten Registers an das aufrufende Programm zuruckgeben. Die folgende Liste zeigt dieseUnterprogramme.

• DCF Get Sekunde

• DCF Get Minute

• DCF Get Stunde

• DCF Get Tag

• DCF Get Monat

• DCF Get Jahr

• DCF Get Wochentag

• DCF Get Status

• DCF Is Low

• DCF Is High

• DCF Is Bitfehler

• DCF Is Sync

• DCF Is Fehler

• DCF Get Zusatzinfos

• DCF Is ResAntenne

• DCF Is Zeitumstellung

• DCF Is Sommerzeit

• DCF Is Winterzeit

• DCF Is Schaltsekunde

4 SOFTWARE 13

• DCF Is Neue Sekunde

• DCF Is Neue Minute

Unterprogramm DCF Init:Das Unterprogramm DCF Init hat die Aufgabe die fur die DCF-Dekodierung notwendigenglobalen Register zu initialisieren.

Listing 3 zeigt die Realisierung dieses Unterprogramms.

98 void DCF Init (void )99 {

100 cDCF Status = 0 ;101 cDCF Hi l f s r eg i s t e r = 0 ;102 bDCF Fehler = 1 ;103 bDCF Port Neu = bDCF Port In ;104105 cUhr Sekunde = 0 ;106 cUhr Minute = 0 ;107 cUhr Stunde = 0 ;108 cDatum Wochentag = 0 ;109 cDatum Tag = 0 ;110 cDatum Monat = 0 ;111 cDatum Jahr = 0 ;112113 cDCF Minute Alt = 99 ;114 cDCF Stunde Alt = 99 ;115 cDCF Tag Alt = 99 ;116 cDCF Monat Alt = 99 ;117 cDCF Jahr Alt = 99 ;118 cDCF Wochentag Alt = 99 ;119 }

Listing 3: Unterprogramm DCF Init (Auszug aus DCF.C)

Unterprogramm DCF Routine:Das Unterprogramm DCF Routine ist fur die DCF-Dekodierung die wichtigste Kompo-nente und muss ca. alle 4 ms aufgerufen werden.

Die Beschreibung dieses Unterprogrammes erfolgt mit Hilfe eines Flussdiagrammes (Ab-bildung 7). Die Aufgabe des Unterprogramms DCF Routine besteht darin aus den Ab-tastungen des DCF-Eingangspins, die alle 4ms erfolgen, herauszufinden, ob ein Low, einHigh oder ein Minutenwechsel gesendet wurde. Dazu wird bei jedem Aufruf des Unterpro-gramms DCF Routine entweder das statische Zahlregister cDCF Puls oder das statischeZaehlregister cDCF Pause um 1 erhoht (inkrementiert), wenn sich der Pegel vom DCF-Eingang zum vorhergehenden Aufruf dieses Unterprogramms nicht veraendert hat. Ist derDCF-Eingang Low (also logisch 0), so wird das Zahlregister cDCF Puls um 1 erhoht, istder DCF-Eingang High (also logisch 1), so wird das Zahlregister cDCF Pause um 1 erhoht.Beide Zahlregister konnen maximal den Wert 255 aufnehmen, was einer Zeit von 1020 ms(oder 1,02 Sekunden) entspricht (= 255 x 4ms).Unterscheidet sich der aktuelle Pegel des DCF-Eingangs mit dem Pegel vom vorherge-henden Aufruf, so spricht man von einer Flanke, wobei hier zwischen einer fallenden undeiner steigenden Flanke unterschieden werden muss. Bei einer steigenden Flanke (der ak-tuelle Pegel des DCF-Eingangs ist logisch 1), wird das statische Zahlregister cDCF Pause

geloscht. Anschließend erfolgt eine Auswertung des statischen Zahlregisters cDCF Puls.

4 SOFTWARE 14

Abbildung 7: Unterprogramm DCF Routine (Flussdiagramm)

Beinhaltet dieses Zahlregister einen Wert zwischen den Konstanten KONSTDCFHMIN undKONSTDCFHMAX, so wurde ein High des DCF-Telegramms ermittelt. Im DCF-Statusregister(cDCF Status) werden daher die Flags bDCF High und bDCF Neue Sekunde gesetzt. DasFlag bDCF Neue Sekunde dient als Zeichen einer neu empfangenen und gultigen Sekunde.Beinhaltet das Zahlregister cDCF Puls einen Wert zwischen den Konstanten KONSTDCFLMIN

und KONSTDCFLMAX, so wurde ein Low des DCF-Telegramms ermittelt. Im DCF-Status-register (cDCF Status) werden daher die Flags bDCF Low und bDCF Neue Sekunde ge-setzt. Das Flag bDCF Neue Sekunde dient auch hier als Zeichen einer neu empfangenenund gultigen Sekunde. Beinhaltet das statische Zahlregister cDCF Puls einen Wert derweder zwischen den Konstanten KONSTDCFHMIN und KONSTDCFHMAX noch zwischen denKonstanten KONSTDCFLMIN und KONSTDCFLMAX liegt, so handelt es sich um einen Ubertra-gungsfehler. In diesem Fall werden die Fehlerflags bDCF Fehler und bDCF Bitfehler imDCF-Statusregister (cDCF Status) gesetzt. Das Flag bDCF Neue Sekunde wird hier abernicht gesetzt, da es sich in diesem Fall um keine gultige Sekunde handelt. Das FehlerflagbDCF Fehler wird erst bei der Erkennung einer neuen Minute wieder geloscht.Bei einer fallenden Flanke (der aktuelle Pegel des DCF-Eingangs ist logisch 0) wird nurdas statische Zahlregister cDCF Puls geloscht.Entsprechend dem im Abschnitt 2 beschriebenen Protokoll erfolgt in der 59. Sekundekeine Absenkung des Tragers. Da es also in der 59. Sekunde keine fallende Flanke gibt,gibt es auch keine steigende Flanke. Das Zahlregister cDCF Pause

”lauft uber“, da es

nur einen Zahlbereich von 0 bis 255 besitzt. Dieser Uberlauf wird hier ausgenutzt. ZurBestimmung einer neuen Minute bzw. zur Bestimmung des Telegrammbeginns. Ist dasFehlerflag bDCF Fehler gesetzt, so wird es nun geloscht. War es nicht gesetzt, so wird das

4 SOFTWARE 15

Flag bDCF Neue Minute im DCF-Hilfsregister (cDCF Hilfsregister) gesetzt.

Im Flussdiagramm (Abbildung 7) erfolgt in den grau hinterlegten Bereichen das Set-zen oder Rucksetzen der zur weiteren Verwendung notwendigen Ubergabeflags im DCF-Statusregister (cDCF Status). Die Unterprogramme DCF UP Sekunde und DCF UP Minute

greifen auf diese Flags zu.

Listing 4 zeigt die Realisierung dieses etwas umfangreicheren Unterprogramms.

180 void DCF Routine (void )181 {182 stat ic char cDCF Puls = 0 ; // Impul s ze i t des DCF−Impulses183 stat ic char cDCF Pause = 0 ; // Ze i t zwischen zwei DCF−Impulsen184185186 bDCF Port Alt = bDCF Port Neu ;187 bDCF Port Neu = bDCF Port In ;188189 i f ( bDCF Port Neu == bDCF Port Alt )190 {191 // Der Pegel am Portpin ( bDCF Port In ) hat s i ch n i cht veraender t192 i f ( bDCF Port Neu )193 {194 cDCF Pause++;195 i f ( cDCF Pause > KONSTDCFNEUEMIN)196 {197 // Ueber lauf −> Neue Minute198 i f ( bDCF Fehler )199 {200 // Wenn Feh l e r f l a g ( bDCF Fehler ) g e s e t z t d i e s e s nun loeschen201 bDCF Fehler = 0 ;202 }203 else

204 {205 // Anforderungs f l ag f u e r ”Neue Minute”206 bDCF Neue Minute = 1 ;207 }208 }209 }210 else

211 {212 cDCF Puls++;213 }214 }215 else

216 {217 // Der Pegel am Portpin ( bDCF Port In ) hat s i ch veraender t218 i f ( bDCF Port Neu )219 {220 // s t e i g ende Flanke221 cDCF Pause = 0 ;222223 // Pruefen , ob e in High empfangen wurde224 i f ( ( cDCF Puls > KONSTDCFHMIN) && ( cDCF Puls < KONSTDCFHMAX) )225 {226 bDCF High = 1 ;227 bDCF Low = 0 ;228 bDCF Bitfehler = 0 ;229 bDCF Neue Sekunde = 1 ;230 }231232 // Pruefen , ob e in Low empfangen wurde233 else i f ( ( cDCF Puls > KONSTDCFLMIN) && ( cDCF Puls < KONSTDCFLMAX) )234 {235 bDCF High = 0 ;236 bDCF Low = 1 ;

4 SOFTWARE 16

237 bDCF Bitfehler = 0 ;238 bDCF Neue Sekunde = 1 ;239 }240 else

241 {242 // Fehler243 bDCF Bitfehler = 1 ;244 bDCF Fehler = 1 ;245 bDCF High = 0 ;246 bDCF Low = 0 ;247 }248 }249 else

250 {251 // f a l l e n d e Flanke252 cDCF Puls = 0 ;253 }254 }255 }

Listing 4: Unterprogramm DCF Routine (Auszug aus DCF.C)

Unterprogramm DCF UP Sekunde:Das Unterprogramm DCF UP Sekunde hat die Aufgabe, je nachdem ob das Bit bDCF Low

oder das Bit bDCF High gesetzt ist dieses Bit dem Telegramm (Register cDCF Telegramm1

bis cDCF Telegramm8) hinzuzufugen.

Vorgehensweise:

Ist das Flag bDCF Low (im Register cDCF Status) gesetzt das Carryflag (im SFR5 STATUS)loschen. Ist das Flag bDCF High (ebenfalls im Register cDCF Status) gesetzt, das Carryflagsetzten. Dieses Carryflag nun dem Telegramm hinzufugen. Dieser Vorgang erfolgt mit ei-nem so genannten Schiebebefehl. Dabei werden alle Bits des Registers cDCF Telegramm1

auf die nachst hohere Position verschoben. (Bit 6 wandert ins Bit 7, Bit 5 wandertins Bit 6 usw. Bit 0 wandert ins Bit 1). Der Inhalt vom Carryflag wandert ins Bit 0.Der Inhalt von Bit 7 wird ins Carryflag geschoben. Bei den Register cDCF Telegramm2

bis cDCF Telegramm6 erfolgt der selbe Vorgang. (Der Inhalt von Bit 7 des RegisterscDCF Telegramm1 wird ins Carry geschoben, und das Carry aber weiter in das Bit 0des Registers cDCF Telegramm2). Achtung: Diese Schiebebefehle sind nur als Assembler-Anweisungen verfugbar. Daher sind diese Befehle in einem asm-Block (Zeilen 306 bis315).

Anmerkung:

Die beiden Flags bDCF Low und bDCF High konnen nie gleichzeitig gesetzt sein. Es istnur moglich, dass entweder nur bDCF Low oder nur bDCF High gesetzt ist, aber nie beidegleichzeitig.

Wichtig:Dieses Unterporgramm wird durch ein gesetztes Botschaftsflag aufgerufen. DiesesBotschaftsflag muss daher wieder geloscht werden (Zeile 319).

5SFR steht fur Special Function Register. Diese Register haben vom Mikrocontroller-Hersteller klardefinierte Aufgaben, und sind im Datenblatt des Mikrocontrollers beschrieben

4 SOFTWARE 17

Listing 5 zeigt die Realisierung dieses Unterprogramms.

291 void DCF UP Sekunde (void )292 {293 i f ( (bDCF Low) | | (bDCF High) )294 {295 i f (bDCF Low)296 {297 // Carry = 0298 STATUS. F0 = 0 ;299 }300 else

301 {302 // Carry = 1 ;303 STATUS. F0 = 1 ;304 }305306 asm {307 RLF cDCF Telegramm1 , 1308 RLF cDCF Telegramm2 , 1309 RLF cDCF Telegramm3 , 1310 RLF cDCF Telegramm4 , 1311 RLF cDCF Telegramm5 , 1312 RLF cDCF Telegramm6 , 1313 // RLF cDCF Telegramm7 , 1314 // RLF cDCF Telegramm8 , 1315 }316 }317318 // Anforderungs f l ag l oes chen319 bDCF Neue Sekunde = 0 ;320 }

Listing 5: Unterprogramm DCF UP Sekunde (Auszug aus DCF.C)

Unterprogramm DCF UP Minute:Das Unterprogramm DCF UP Minute hat folgende Aufgaben:

1. Datum, Uhrzeit und die Zusatzinformationen aus den Registern cDCF Telegramm1

bis cDCF Telegramm6 zusammensetzen.

2. Das so eben ermittelte Telegramm mit dem Telegramm der vorhergehenden Minutevergleichen. Die so eben ermittelte Minute muss dabei um 1 großer als die vorherge-hende Minute sein, und die so eben ermittelten Werte fuer die Stunde, den Tag, denMonat, das Jahr und den Wochentag mussen mit den Werten des vorhergehendenTelegramms ubereinstimmen. ACHTUNG: Bei dieser einfachen Uberprufung wirdder Ubergang von z. B. 13:59 auf 14:00 als falsch gewertet, da sich hier die Stundeandert, und auch die Minute um mehr als 1. Wurden hier alle moglichen Ubergangeberucksichtigt, dann wurde dieses Unterprogramm noch umfangreicher als es oh-nehin schon ist werden. Durch diese Vereinfachung dauert die Synchronisierung imungunstigsten Fall nur eine Minute langer.

3. Das alte Datum bzw. die alte Uhrzeit (von der vorhergehenden Minute) durch dasneue Datum bzw. die Uhrzeit ersetzen. Dies ist fur die Uberprufung des nachstenTelegramms notwendig.

4. Wenn das neu empfangene Datum bzw. die neu empfangene Uhrzeit gultig ist, dieBCD-kodierten Datums- bzw. Uhrzeitkomponenten in eine binare Form umwandeln

4 SOFTWARE 18

und damit die mitlaufende Uhr synchronisieren. Das Flag bDCF Sync im RegistercDCF Status setzen. Dieses gesetzte Flag kennzeichnet, dass die mitlaufende Uhrmit der DCF-Uhr synchronisiert ist.

Wichtig:Dieses Unterporgramm wird durch ein gesetztes Botschaftsflag aufgerufen. DiesesBotschaftsflag muss daher wieder geloscht werden (Zeile 455).

Listing 6 zeigt die Realisierung dieses etwas umfangreicheren Unterprogramms.

355 void DCF UP Minute (void )356 {357 // Jahr zusammensetzen (BCD−Format )358 cDCF Jahr BCD = 0 ;359 i f ( cDCF Telegramm1 . F1) cDCF Jahr BCD . F7 = 1 ;360 i f ( cDCF Telegramm1 . F2) cDCF Jahr BCD . F6 = 1 ;361 i f ( cDCF Telegramm1 . F3) cDCF Jahr BCD . F5 = 1 ;362 i f ( cDCF Telegramm1 . F4) cDCF Jahr BCD . F4 = 1 ;363 i f ( cDCF Telegramm1 . F5) cDCF Jahr BCD . F3 = 1 ;364 i f ( cDCF Telegramm1 . F6) cDCF Jahr BCD . F2 = 1 ;365 i f ( cDCF Telegramm1 . F7) cDCF Jahr BCD . F1 = 1 ;366 i f ( cDCF Telegramm2 . F0) cDCF Jahr BCD . F0 = 1 ;367368 // Monat zusammensetzen (BCD−Format )369 cDCF Monat BCD = 0 ;370 i f ( cDCF Telegramm2 . F1) cDCF Monat BCD . F4 = 1 ;371 i f ( cDCF Telegramm2 . F2) cDCF Monat BCD . F3 = 1 ;372 i f ( cDCF Telegramm2 . F3) cDCF Monat BCD . F2 = 1 ;373 i f ( cDCF Telegramm2 . F4) cDCF Monat BCD . F1 = 1 ;374 i f ( cDCF Telegramm2 . F5) cDCF Monat BCD . F0 = 1 ;375376 // Wochentag zusammensetzen (BCD−Format )377 cDCF Wochentag = 0 ;378 i f ( cDCF Telegramm2 . F6) cDCF Wochentag . F2 = 1 ;379 i f ( cDCF Telegramm2 . F7) cDCF Wochentag . F1 = 1 ;380 i f ( cDCF Telegramm3 . F0) cDCF Wochentag . F0 = 1 ;381382 // Tag zusammensetzen (BCD−Format )383 cDCF Tag BCD = 0 ;384 i f ( cDCF Telegramm3 . F1) cDCF Tag BCD . F5 = 1 ;385 i f ( cDCF Telegramm3 . F2) cDCF Tag BCD . F4 = 1 ;386 i f ( cDCF Telegramm3 . F3) cDCF Tag BCD . F3 = 1 ;387 i f ( cDCF Telegramm3 . F4) cDCF Tag BCD . F2 = 1 ;388 i f ( cDCF Telegramm3 . F5) cDCF Tag BCD . F1 = 1 ;389 i f ( cDCF Telegramm3 . F6) cDCF Tag BCD . f0 = 1 ;390391 // Stunde zusammensetzen (BCD−Format )392 cDCF Stunde BCD = 0 ;393 i f ( cDCF Telegramm4 . F0) cDCF Stunde BCD . F5 = 1 ;394 i f ( cDCF Telegramm4 . F1) cDCF Stunde BCD . F4 = 1 ;395 i f ( cDCF Telegramm4 . F2) cDCF Stunde BCD . F3 = 1 ;396 i f ( cDCF Telegramm4 . F3) cDCF Stunde BCD . F2 = 1 ;397 i f ( cDCF Telegramm4 . F4) cDCF Stunde BCD . F1 = 1 ;398 i f ( cDCF Telegramm4 . F5) cDCF Stunde BCD . F0 = 1 ;399400 // Minute zusammensetzen (BCD−Format )401 cDCF Minute BCD = 0 ;402 i f ( cDCF Telegramm4 . F7) cDCF Minute BCD . F6 = 1 ;403 i f ( cDCF Telegramm5 . F0) cDCF Minute BCD . F5 = 1 ;404 i f ( cDCF Telegramm5 . F1) cDCF Minute BCD . F4 = 1 ;405 i f ( cDCF Telegramm5 . F2) cDCF Minute BCD . F3 = 1 ;406 i f ( cDCF Telegramm5 . F3) cDCF Minute BCD . F2 = 1 ;407 i f ( cDCF Telegramm5 . F4) cDCF Minute BCD . F1 = 1 ;

4 SOFTWARE 19

408 i f ( cDCF Telegramm5 . F5) cDCF Minute BCD . F0 = 1 ;409410 // Zusa t z i n f o s zusammensetzen411 cDCF Zusatzinfos = 0 ;412 i f ( cDCF Telegramm5 . F7) cDCF Zusatzinfos . F4 = 1 ;413 i f ( cDCF Telegramm6 . F0) cDCF Zusatzinfos . F3 = 1 ;414 i f ( cDCF Telegramm6 . F1) cDCF Zusatzinfos . F2 = 1 ;415 i f ( cDCF Telegramm6 . F2) cDCF Zusatzinfos . F1 = 1 ;416 i f ( cDCF Telegramm6 . F3) cDCF Zusatzinfos . F0 = 1 ;417418 // Neues Telegramm mit dem a l t en Telegramm ver g l e i ch en419 bDCF Fehler = 0 ; // zue r s t F eh l e r f l a g l oes chen420 i f (cDCF Minute BCD − cDCF Minute Alt − 1) bDCF Fehler = 1 ; // Minuten pruefen421 i f ( cDCF Stunde BCD − cDCF Stunde Alt ) bDCF Fehler = 1 ; // Stunden pruefen422 i f (cDCF Tag BCD − cDCF Tag Alt ) bDCF Fehler = 1 ; // Tag pruefen423 i f (cDCF Monat BCD − cDCF Monat Alt ) bDCF Fehler = 1 ; // Monat pruefen424 i f (cDCF Jahr BCD − cDCF Jahr Alt ) bDCF Fehler = 1 ; // Jahr pruefen425 i f ( cDCF Wochentag − cDCF Wochentag Alt ) bDCF Fehler = 1 ; // Wochentag pruefen426427 // Al tes Telegramm durch das neue Telegramm er s e t z en428 cDCF Minute Alt = cDCF Minute BCD ;429 cDCF Stunde Alt = cDCF Stunde BCD ;430 cDCF Tag Alt = cDCF Tag BCD ;431 cDCF Monat Alt = cDCF Monat BCD ;432 cDCF Jahr Alt = cDCF Jahr BCD ;433 cDCF Wochentag Alt = cDCF Wochentag ;434435 // Wenn DCF−Telegramm kor r ekt f r e i l a u f e n d e Uhr und Datum mit der DCF−dekod i e r ten436 // Uhrzei t (und dem Datum) laden437 i f ( bDCF Fehler == 0)438 {439 cUhr Stunde = Bcd2Dec ( cDCF Stunde BCD) ;440 cUhr Minute = Bcd2Dec ( cDCF Minute BCD) ;441 cUhr Sekunde = 0 ;442 cDatum Tag = Bcd2Dec (cDCF Tag BCD) ;443 cDatum Monat = Bcd2Dec (cDCF Monat BCD) ;444 cDatum Jahr = Bcd2Dec ( cDCF Jahr BCD) ;445 cDatum Wochentag = cDCF Wochentag ;446447 bDCF Sync = 1 ;448 }449 else

450 {451 bDCF Fehler = 0 ;452 }453454 // Anforderungs f l ag l oes chen455 bDCF Neue Minute = 0 ;456 }

Listing 6: Unterprogramm DCF UP Minute (Auszug aus DCF.C)

Unterprogramm DCF Innere Uhr:Fur den Fall dass kein gultiges DCF-Telegramm empfangen werden kann sorgt das Un-terprogramm DCF Innere Uhr dafur, dass die Uhrzeit trotzdem jede Sekunde aktualisiertwird. Ist fur eine langere Zeit kein korrekter DCF-Empfang moglich, so wurden die Minu-ten, die Stunden, die Tage usw.

”stehen“ bleiben, da ja im Unterprogramm DCF UP Minute

nur gultige DCF-Telegramme ubernommen werden. Dieses Unterprogramm wird also par-allel zu den Unterprogrammen fur die DCF-Dekodierung aufgerufen.

Vorgehensweise:

Die Sekunden (Register cUhr Sekunde) um 1 erhohen. Beinhaltet dieses Register nun denWert 60, so beginnt eine neue Minute. Daher die Sekunden loschen und die Minuten (Re-gister cUhr Minute) um 1 erhohen. Beinhaltet dieses Register nun den Wert 60, so beginnt

4 SOFTWARE 20

eine neue Stunde. Daher die Minuten loschen und die Stunden (Register cUhr Stunde) um1 erhohen. Beinhaltet dieses Register nun den Wert 24, so beginnt ein neuer Tag. Daherdie Stunden loschen. Ist das Mitzahlen des Datums notwendig, so muss nun ein Registerfur den Tag (z.B. cDatum Tag) um 1 erhoht werden und dieses uberpruft werden, wobeidiese Prufung nun nicht mehr so einfach ist, da ja jeder Monat unterschiedlich viele Tagebesitzt. Erschwerend kommt auch noch hinzu, dass auch die Schaltjahre miteinbezogenwerden mussen!

Wichtig:Dieses Unterprogramm muss jede Sekunde (z.B. vom Hauptprogramm) aufgeru-fen werden.

Listing 7 zeigt die Realisierung dieses Unterprogramms.

492 void DCF Innere Uhr (void )493 {494 cUhr Sekunde++; // Sekundenz ahler um 1 erhoehen495496 i f ( cUhr Sekunde == 60)497 {498 cUhr Sekunde = 0 ;499 cUhr Minute++;500501 i f ( cUhr Minute == 60)502 {503 cUhr Minute = 0 ;504 cUhr Stunde++;505506 i f ( cUhr Stunde == 24)507 {508 cUhr Stunde = 0 ;509 cDatum Tag++;510 cDatum Wochentag++;511512 i f ( cDatum Wochentag == 7)513 {514 cDatum Wochentag = 0 ;515 }516 }517 }518 }519 }

Listing 7: Unterprogramm DCF Innere Uhr (Auszug aus DCF.C)

Unterprogramme zum Lesen von Uhrzeit, Datum und diversen Zusatzinfor-mationen:Die Uhrzeit, das Datum, sowie andere nutzliche Informationen sind in globalen Registerngesichert. Diese globalen Register konnen nur vom Quellcode in der Datei DCF.C verandertund gelesen werden. Das Hauptprogramm, oder andere Unterprogramme benotigen aberdiese Informationen. Daher sind einige Unterprogramme notwendig, die als Ruckgabe-parameter nur den Inhalt dieser Register beinhalten. Durch diesen Mechanismus wirdverhindert, dass Programmteile Datenregister (ungewollt) verandern. Dieser Mechanis-mus wir in der Informatik auch Datenkapselung genannt.

4 SOFTWARE 21

Die Listings 8 bis 26 zeigen diese sehr einfachen Unterprogramme.

535 char DCF Get Sekunde (void )536 {537 return ( cUhr Sekunde ) ;538 }

Listing 8: Unterprogramm DCF Get Sekunde (Auszug aus DCF.C)

554 char DCF Get Minute (void )555 {556 return ( cUhr Minute ) ;557 }

Listing 9: Unterprogramm DCF Get Minute (Auszug aus DCF.C)

573 char DCF Get Stunde (void )574 {575 return ( cUhr Stunde ) ;576 }

Listing 10: Unterprogramm DCF Get Stunde (Auszug aus DCF.C)

592 char DCF Get Tag (void )593 {594 return ( cDatum Tag) ;595 }

Listing 11: Unterprogramm DCF Get Tag (Auszug aus DCF.C)

611 char DCF Get Monat (void )612 {613 return ( cDatum Monat ) ;614 }

Listing 12: Unterprogramm DCF Get Monat (Auszug aus DCF.C)

630 char DCF Get Jahr (void )631 {632 return ( cDatum Jahr ) ;633 }

Listing 13: Unterprogramm DCF Get Jahr (Auszug aus DCF.C)

649 char DCF Get Wochentag (void )650 {651 return ( cDatum Wochentag ) ;652 }

Listing 14: Unterprogramm DCF Get Wochentag (Auszug aus DCF.C)

672 char DCF Get Status (void )673 {674 return ( cDCF Status ) ;675 }

Listing 15: Unterprogramm DCF Get Status (Auszug aus DCF.C)

692 char DCF Is Low (void )693 {694 return (bDCF Low) ;695 }

Listing 16: Unterprogramm DCF Is Low (Auszug aus DCF.C)

4 SOFTWARE 22

712 char DCF Is High (void )713 {714 return (bDCF High) ;715 }

Listing 17: Unterprogramm DCF Is High (Auszug aus DCF.C)

737 char DCF Is Bi t f eh l e r (void )738 {739 return ( bDCF Bitfehler ) ;740 }

Listing 18: Unterprogramm DCF Is Bitfehler (Auszug aus DCF.C)

762 char DCF Is Fehler (void )763 {764 return ( bDCF Fehler ) ;765 }

Listing 19: Unterprogramm DCF Is Fehler (Auszug aus DCF.C)

782 char DCF Is Sync (void )783 {784 return (bDCF Sync ) ;785 }

Listing 20: Unterprogramm DCF Is Sync (Auszug aus DCF.C)

806 char DCF Get Zusatzinfos (void )807 {808 return ( cDCF Zusatzinfos ) ;809 }

Listing 21: Unterprogramm DCF Get Zusatzinfos (Auszug aus DCF.C)

827 char DCF Is ResAntenne (void )828 {829 return ( bDCF Rerserveantenne ) ;830 }

Listing 22: Unterprogramm DCF Is ResAntenne (Auszug aus DCF.C)

848 char DCF Is Zei tumstel lung (void )849 {850 return ( bDCF Zeitumstellung ) ;851 }

Listing 23: Unterprogramm DCF Is Zeitumstellung (Auszug aus DCF.C)

867 char DCF Is Sommerzeit (void )868 {869 return ( bDCF Sommerzeit ) ;870 }

Listing 24: Unterprogramm DCF Is Sommerzeit (Auszug aus DCF.C)

906 char DCF Is Winterze i t (void )907 {908 return ( bDCF Winterzeit ) ;909 }

Listing 25: Unterprogramm DCF Is Winterzeit (Auszug aus DCF.C)

5 DEMONSTRATIONSBEISPIEL 23

906 char DCF Is Schaltsekunde (void )907 {908 return ( bDCF Schaltsekunde ) ;909 }

Listing 26: Unterprogramm DCF Is Schaltsekunde (Auszug aus DCF.C)

Unterprogramme zum Lesen der Botschaftsflags fur die Abarbeitung der Un-terprogramme DCF UP Sekunde und DCF UP Minute:Die fur die DCF-Dekodierung wichtigen Unterprogramme DCF UP Sekunde (Listing 5,Seite 17) und DCF UP Minute (Listing 6, Seite 18) werden nur bei einer vollen Sekunde bzw.bei einer vollen Minute abgearbeitet. Die zwei Botschaftsflags bDCF Neue Sekunde undbDCF Neue Minute mussen daher mit Hilfe der Unterprogramme DCF Is Neue Sekunde

(Listing 27) und DCF Is Neue Minute (Listing 28) im Hauptprogramm abgefragt werden.Denn auch hier gilt das Prinzip der Datenkapselung, da diese zwei Botschaftsflags imUnterprogramm DCF Routine (Listing 4, Seite 15, in der Datei DCF.C) gesetzt werden.Anmerkung: Diese beiden Botschaftsflags werden automatisch in den UnterprogrammenDCF UP Sekunde bzw. DCF UP Minute zuruckgesetzt.

925 char DCF Is Neue Sekunde (void )926 {927 return ( bDCF Neue Sekunde ) ;928 }

Listing 27: Unterprogramm DCF Is Neue Sekunde (Auszug aus DCF.C)

944 char DCF Is Neue Minute (void )945 {946 return ( bDCF Neue Minute) ;947 }

Listing 28: Unterprogramm DCF Is Neue Minute (Auszug aus DCF.C)

Das Demonstrationsbeispiel (im folgenden Abschnitt) zeigt dies an einem konkreten, prak-tischen Beispiel.

5 Demonstrationsbeispiel

Das folgende Beispiel dient nur zur Demonstration. Es zeigt eine mogliche Einbindungder zuvor beschriebenen Unterprogramme. Bei diesem Demonstrationsbeispiel werden dieUhrzeit und das Datum abwechselnd (alle 4 Sekunden) auf 7-Segment-Anzeigen darge-stellt. Weiters wird der Wochentag (Montag bis Samstag) mit Hilfe von Leuchtdiodenangezeigt. Die Statusinformationen, also ob gerade ein Low, ein High oder ein ungultigesBit empfangen wurde, werden ebenfalls mit Leuchtdioden angezeigt (siehe Titelbild).

5.1 Schaltung (Hardware)

Die Abbildung 8 zeigt die Schaltung fur dieses Demonstrationsbeispiel.

Die Schaltung besteht aus einem Mikrocontroller (IC1) vom Typ PIC16F874, der imAbschnitt 3 (ab Seite 5) besprochenen Anpass-Schaltung, sechs 7-Segment-Anzeigen (LD1

5 DEMONSTRATIONSBEISPIEL 24

Abbildung 8: Demonstrationsbeispiel (Schaltung)

bis LD6) mit den zugehorigen Dekodern (IC3 bis IC8) fur die Anzeige der Uhrzeit unddes Datums, sowie einigen Leuchtdioden fur die Statusanzeigen (D2 bis D6) sowie zurAnzeige des Wochentages (D7 bis D13) und einer einfachen Spannungsversorgung miteinem 5-V-Fixspannungsregler (IC9) vom Typ 7805.

Bei diesem Demonstrationsbeispiel werden sehr viele Portpins benotigt. Daher fiel dieWahl fur den Mikrocontroller auf den PIC16F874, der insgesamt 33 Portpins besitzt, diewie Abbildung 8 zeigt auch alle benotigt werden.Fur 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. Zusatzlich kann mit dem Taster S2 ein Reset jederzeit ausgelost werden.Der Kondensator C5 dient zur Entkoppelung der Betriebsspannung fur den Mikrocontrol-ler IC1. Fur diesen Koppelkondensator sollte ein Keramiktyp verwendet werden. Diesermuss moglichst nahe beim Mikrocontroller angebracht werden.

Der Wochentag ist gemaß dem DCF-Protokoll binar kodiert (der Wert 1 entspricht demMontag und der Wert 7 entspricht dem Sonntag, siehe auch Abschnitt 2 ab Seite 2). Damitfur jeden Wochentag eine eigene Leuchtdiode leuchtet ist ein Binar-zu-Oktal-Dekodernotwendig. Hier wird der Typ 74LS138 (IC2) verwendet.

5 DEMONSTRATIONSBEISPIEL 25

Die Kondensatoren C10 bis C13 sind Koppelkondensatoren fur die Dekoder-ICs IC2 bisIC8.

Die Stromversorgung besteht hier aus einer sehr einfachen Standardlosung. Ein Fest-spannungsregler (IC9) vom Typ 7805 ubernimmt mit den Kondensatoren C6 bis C9 dieSpannungsregelung. Die Diode D14 dient hier als Verpolungsschutz, und die LeuchtdiodeD15 dient zusammen mit dem Strombegrenzungswiderstand R60 als Spannungskontrolle.

5.2 Stuckliste

Nr. Bezeichnung St. Lief. Bestell-Nr. Alt. Lief. Bestell-Nr.

Widerstand 0 Ohm 1 Conrad 40 37 09 Farnell 933-9027Widerstand 0 Ohm SMD 1206 13 Conrad 40 22 22 Farnell 933-6974

R1, R3, R58 Widerstand 10k 3 Conrad 40 82 20 Farnell 934-1110R2, R4 - R15, R60 Widerstand 1k 14 Conrad 40 81 66 FarnellR16 - R57 Widerstand 220 42 Conrad 40 80 85 FarnellR59 Widerstand 270 1 Conrad 40 80 93 Farnell 934-1633C1, C5, C7, C8, C10 Keramikkondensator 100nF RM5.08 5 Conrad 45 33 58C2, C6 Mini-Elko 10µF/25V 2 Conrad 46 05 24C3, C4 Keramikkondensator 22pF RM2.54 2 Conrad 45 71 67C9 Tantal 1µF/35V 1 Conrad 48 16 70C11 - C13 Keramikkondensator 220nF RM5.08 3 Conrad 45 33 66D1, D5 - D13 Low-current-LED 5mm gelb 10 Conrad 18 02 24 Farnell 114-2565D2 Low-current-LED 5mm grun 1 Conrad 18 02 22 Farnell 114-2561D3, D4 Low-current-LED 5mm rot 2 Conrad 18 02 23 Farnell 114-2563D14 Diode 1N4001 1 Conrad 16 22 13D15 Low-current-LED 3mm grun 1 Conrad 18 02 18 Farnell 114-2509LD1 - LD6 7-Segment-Anzeige (Typ: SA10-21EWA) 6 Conrad 16 01 27 Farnell 116-8620T1 Transistor BC547B 1 Conrad 15 50 12IC1 Mikrocontroller PIC16F874(A) 1 Farnell 976-1152 Conrad 16 50 91IC2 74LS138 1 Conrad 16 94 63IC3 - IC8 74LS47 6 Conrad 16 91 96IC9 Spannungsregler 7805 1 Conrad 17 92 05X1 Quarz 4,096 MHz 1 Conrad 16 86 29DCF1 DCF-Empfangsmodul 1 Conrad 64 11 38IC2 - IC8 IC-Prazisionssockel 16polig 7 Conrad 18 96 26IC1 IC-Prazisionssockel 40polig 1 Conrad 18 96 77LD1 - LD6 Buchsenleiste 5polig 12 Conrad 74 04 38K1 Anschlussklemme 2polig 1 Conrad 72 99 49S1 Schiebeschalter 1 Conrad 70 80 46S2 Taster 1 Conrad 70 04 60IC9 Aufsteckkuhlkorper 1 Conrad 18 85 73

Platine Basismaterial (200 x 150mm) 1 Conrad 52 97 29Zylinderkopfschraube M2.5x10 2Mutter M2.5 2Abstandsrollen 5mm 2Abstandsbolzen M3x10 4Mutter M3 4Kabelbinder 100mm 2

Tabelle 6: Demonstrationsbeispiel (Stuckliste, Stand: August 2009)

5 DEMONSTRATIONSBEISPIEL 26

5.3 Layout und Bestuckungsplan

Die Abbildung 9 zeigt das Layout fur dieses Demonstrationsbeispiel. Es ist im Maßstab1:1 und wie ublich spiegelverkehrt.

Abbildung 9: Demonstrationsbeispiel (Layout)

Der Bestuckungsplan ist in Abbildung 10 zu sehen. Der Nachbau sollte keine Problemebereiten. Bei der Bestuckung beginnt man ublicherweise mit den niedrigen Bauteilen.

Achtung:Auf der Lotseite befinden sich 13 0-Ohm-SMD-Widerstande. Diese durfen bei der Bestuckungnicht vergessen werden.Neben dem Widerstand R59 befindet sich ein 0-Ohm-Widerstand (siehe auch Stuckliste).Alternativ kann auch ein Stuck Draht verwendet werden.

5 DEMONSTRATIONSBEISPIEL 27

Abbildung 10: Demonstrationsbeispiel (Bestuckungsplan, Bauteilseite)

5.4 Software

Der Quellcode fur den PIC-Mikrocontroller ist zur besseren Ubersicht in mehrere Dateienaufgeteilt:

• DCF Demo.c beinhaltet das Hauptprogramm, die Interrupt-Service-Routine (ISR)und die Unterprogramme zur Initialisierung des Mikrocontrollers (PIC16F874) undzur Anzeige der Uhrzeit sowie des Datums.

• DCF.C beinhaltet die Unterprogramme zur DCF-Dekodierung gemaß Abschnitt 4.

• DCF.H ist die Headerdatei zu DCF.C und beinhaltet die Portdefinition, sowie Kon-stanten fur die DCF-Dekodierung die bei jeder Anwendung uberpruft und ggf. an-gepasst werden mussen.

5 DEMONSTRATIONSBEISPIEL 28

Datei DCF Demo.c:

1 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/2 /∗ DCF − Demonstrat i on sbe i sp i e l ∗/3 /∗ ∗/4 /∗ ex t e r ne r Takt (4 ,096 MHz) ∗/5 /∗ ∗/6 /∗ Compiler : mikroC ∗/7 /∗ ∗/8 /∗ Entwickler : Ste f an Buchgeher ∗/9 /∗ Entwicklungsbeginn der Sof tware : 26 . September 2009 ∗/

10 /∗ Funkt i ons f aeh i g s e i t : 26 . September 2009 ∗/11 /∗ Letzte Bearbei tung : 23 . Maerz 2010 ∗/12 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/1314 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Include−Dateien ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/15 #include ”DCF.H”

161718 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Strukturen ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/19 /∗ ke ine Strukturen verwendet ∗/202122 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Externe Reg i s t e r ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/23 /∗ ke ine externen Reg i s t e r ∗/242526 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Bi ts in den externen Reg i s te rn ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/27 /∗ ke ine externen Reg i s t e r ∗/282930 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Globale Reg i s t e r ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/31 char cFlagISRHP ;32 char cZaeh l e rZe i tbas i s100ms ;33 char cZaeh l e rZe i tba s i s 1 s ek ;343536 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Bi ts in den g loba l en Reg i s te rn ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/37 /∗ Reg i s t e r FlagISRHP ∗/38 #define bFlagZei tbas i s4ms cFlagISRHP . F039 #define bFlagZei tbas i s100ms cFlagISRHP . F140 #define bF l agZe i tba s i s 1 s ek cFlagISRHP . F2414243 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Portbelegung ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/44 /∗ Siehe DCF.H ∗/4546 /∗ 7−Segment−Anzeigen ∗/47 #define Stunde Tag BCD PORTB48 #define Minute Monat BCD PORTD49 #define Sekunde Jahr BCD PORTC5051 /∗ Wochentag ∗/52 #define Wochentag PORTE5354 /∗ Statusanze i g e ∗/55 #define Statusanze i ge Lo PORTA. F056 #define Statusanze i ge Hi PORTA. F157 #define S t a t u s an z e i g e B i t f e h l e r PORTA. F258 #define Sta tu s anze i g e Feh l e r PORTA. F359 #define Statusanze i ge Sync PORTA. F5606162 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Konstanten ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/63 /∗ Konstanten f u e r d i e Ze i tbasen ∗/64 #define KONSTZEITBASIS100MS 2565 #define KONSTZEITBASIS1SEK 10666768 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Tabel l en ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/69 /∗ ke ine Tabel l en ∗/70

5 DEMONSTRATIONSBEISPIEL 29

7172 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Funktionsprototypen ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/73 void I n i t (void ) ;74 void Anzeige Demo (void ) ;757677 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ISR − Timer0 ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/7879 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/80 /∗ In t e r r up t Se r v i c e Routine : ∗/81 /∗ ∗/82 /∗ Aufruf : ∗/83 /∗ a l l e 4 ms ∗/84 /∗ ∗/85 /∗ Aufgaben : ∗/86 /∗ + Zei tbasen f u e r 4 Mi l l i s ekunde , 100 Mi l l i s ekunde und 1 Sekunde erzeugen ∗/87 /∗ + Das Timer−Inter rupt−Flag T0IF wieder l oes chen ∗/88 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/89 void i n t e r r up t (void ) // In t e r r up t r ou t i n e90 {91 bFlagZei tbas i s4ms = 1 ;9293 cZaeh l e rZe i tbas i s100ms−−;94 i f ( cZaeh l e rZe i tbas i s100ms == 0) // Bo t s c h a f t s f l a g f u e r 100ms−Ze i t b a s i s s e tzen95 {96 bFlagZei tbas i s100ms = 1 ;97 cZaeh l e rZe i tbas i s100ms = KONSTZEITBASIS100MS ; // Za eh l r e g i s t e r f u e r 100−ms−98 // Z e i t b a s i s neu laden99 cZaeh l e rZe i tba s i s 1 s ek −−;

100 i f ( cZaeh l e rZe i tba s i s 1 s e k == 0) // Bo t s c h a f t s f l a g f u e r 1sek−Ze i t b a s i s s e tzen101 {102 bF l agZe i tba s i s 1 s ek = 1 ;103 cZaeh l e rZe i tba s i s 1 s e k = KONSTZEITBASIS1SEK; // Za eh l r e g i s t e r f u e r 1−Sek−104 } // Z e i t b a s i s neu laden105 }106 INTCON. T0IF = 0 ; // Timer−Inter rupt−Flag T0IF wieder l oes chen107 }108109110 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Unterprogramme und Funktionen ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/111112 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/113 /∗ I n i t : ∗/114 /∗ ∗/115 /∗ Aufgabe : ∗/116 /∗ I n i t i a l i s i e r u n g des Prozes sor : ∗/117 /∗ + Timer 0 (TMR0) loes chen ∗/118 /∗ + Timer 0−ISR s o l l a l l e 4ms aufgeru f en werden , daher den Vo r t e i l e r mit 1 : 16 ∗/119 /∗ l aden ( be i einem 4,096−MHz−Takt ) ∗/120 /∗ 4 ∗ 256 ∗ VT 4 ∗ 256 ∗ 16 ∗/121 /∗ ISR−Aufruf [ us ] = −−−−−−−−−−−−− = −−−−−−−−−−−− = 4000 us = 4 ms ∗/122 /∗ f [MHz] 4 ,096 ∗/123 /∗ + Ports d e f i n i e r e n ∗/124 /∗ + Port A: Pin RA4 = Eingang (DCF) , a l l e anderen Pins : Ausgang ∗/125 /∗ + Port B, C, D und E: a l l e Portpins : Ausgang ∗/126 /∗ + ADC deak t i v i e r en ∗/127 /∗ + Zaeh l r e g i s t e r f u e r Z e i t b a s i s i n i t i a l i s i e r e n ∗/128 /∗ + Inte r r up t f r e i g eben ( Timer0 f r e i g eben durch Setzen von GIE und T0IE im ∗/129 /∗ INTCON−Reg i s t e r ) ∗/130 /∗ ∗/131 /∗ Uebergabeparameter : ∗/132 /∗ ke i n e r ∗/133 /∗ ∗/134 /∗ Rueckgabeparameter : ∗/135 /∗ ke i n e r ∗/136 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/137 void I n i t (void )138 {139 // Timer−0−In t e r r up t kon f i gu r i e r en140 TMR0 = 0 ; // Timer 0 auf 0 v o r e i n s t e l l e n141 OPTION REG = 0b10000011 ; // Option−Reg i s t e r (Bank 1)

5 DEMONSTRATIONSBEISPIEL 30

142 /∗ +−−−−−−−−−−−−−−−− Bit 7 (nRBPU) : Pul l−Up−Widerstaende am Port B143 | | | | | | | 0 : Pul l−Up a k t i v i e r t144 | | | | | | | −> 1 : Pul l−Up deak t i v i e r t145 +−−−−−−−−−−−−−−−− Bit 6 (INTEDG) : In t e r r up t Edge S e l e c t Bit146 | | | | | | −> 0 : In t e r r up t on f a l l i n g edge o f RB0/INT pin147 | | | | | | 1 : In t e r r up t on r i s i n g edge o f RB0/INT pin148 +−−−−−−−−−−−−−−− Bit 5 (T0CS) : Timer 0 Clock sour ce S e l e c t Bit149 | | | | | −> 0 : Trans i t i on on RA4/T0CKI pin150 | | | | | 1 : In t e r na l i n s t r u c t i o n cyc l e c l ock (CLKOUT)151 +−−−−−−−−−−−−−− Bit 4 (T0SE) : TMR0 Source Edge S e l e c t b i t152 | | | | −> 0 : Increment on low−to−high t r an i t i o n153 | | | | 1 : Increment on high−to−low t r an i t i o n154 +−−−−−−−−−−−− Bit 3 (PSA) : P r e s ca l e r Assignment b i t155 | | | −> 0 : P r e s ca l e r i s as s i gned to the TIMER0 module156 | | | 1 : P r e s ca l e r i s as s i gned to the WDT157 +++−−−−−−−−− Bit 2−0 (PS2 : PS0) : P r e s ca l e r Rate S e l e c t b i t s158 Bit Value TMR0 Rate WDT Rate159 000 : 1 : 2 1 : 1160 001 : 1 : 4 1 : 2161 010 : 1 : 8 1 : 4162 −> 011 : 1 : 16 1 : 8163 100 : 1 : 32 1 : 16164 101 : 1 : 64 1 : 32165 110 : 1 :128 1 : 64166 111 : 1 :256 1:128167 ∗/168169 // Ports kon f i gu r i e r en170 TRISA = 0b00010000 ; // R i ch tung s r eg i s t e r Port A ( 0 : Ausgang , 1 : Eingang )171 /∗ ++−−−−−−−−−−−−−−−−−−−− Bit 7−6 Reserve172 +−−−−−−−−−−−−−−−−−−− Bit 5 Port RA5: h i e r Ausgang ( Status : DCF−Sync )173 +−−−−−−−−−−−−−−−−−− Bit 4 Port RA4: h i e r Eingang (DCF−Eingang )174 +−−−−−−−−−−−−−−−−− Bit 3 Port RA3: h i e r Ausgang ( Status : DCF−Fehler )175 +−−−−−−−−−−−−−−−− Bit 2 Port RA2: h i e r Ausgang ( Status : DCF−B i t f e h l e r )176 +−−−−−−−−−−−−−−− Bit 1 Port RA1: h i e r Ausgang ( Status : DCF−High )177 +−−−−−−−−−−−−−− Bit 0 Port RA0: h i e r Ausgang ( Status : DCF−Low)178 ∗/179180 TRISB = 0b00000000 ; // R i ch tung s r eg i s t e r Port B ( 0 : Ausgang , 1 : Eingang )181 /∗ +−−−−−−−−−−−−−−−−−−−−− Bit 7 Port RB7 : h i e r Ausgang ( Stunde /Tag 7)182 +−−−−−−−−−−−−−−−−−−−− Bit 6 Port RB6 : h i e r Ausgang ( Stunde /Tag 6)183 +−−−−−−−−−−−−−−−−−−− Bit 5 Port RB5 : h i e r Ausgang ( Stunde /Tag 5)184 +−−−−−−−−−−−−−−−−−− Bit 4 Port RB4 : h i e r Ausgang ( Stunde /Tag 4)185 +−−−−−−−−−−−−−−−−− Bit 3 Port RB3 : h i e r Ausgang ( Stunde /Tag 3)186 +−−−−−−−−−−−−−−−− Bit 2 Port RB2 : h i e r Ausgang ( Stunde /Tag 4)187 +−−−−−−−−−−−−−−− Bit 1 Port RB1 : h i e r Ausgang ( Stunde /Tag 1)188 +−−−−−−−−−−−−−− Bit 0 Port RB0 : h i e r Ausgang ( Stunde /Tag 0)189 ∗/190191 TRISC = 0b00000000 ; // R i ch tung s r eg i s t e r Port C ( 0 : Ausgang , 1 : Eingang )192 /∗ +−−−−−−−−−−−−−−−−−−−−− Bit 7 Port RC7 : h i e r Ausgang ( Sekunde/Jahr 7)193 +−−−−−−−−−−−−−−−−−−−− Bit 6 Port RC6 : h i e r Ausgang ( Sekunde/Jahr 6)194 +−−−−−−−−−−−−−−−−−−− Bit 5 Port RC5 : h i e r Ausgang ( Sekunde/Jahr 5)195 +−−−−−−−−−−−−−−−−−− Bit 4 Port RC4 : h i e r Ausgang ( Sekunde/Jahr 4)196 +−−−−−−−−−−−−−−−−− Bit 3 Port RC3 : h i e r Ausgang ( Sekunde/Jahr 3)197 +−−−−−−−−−−−−−−−− Bit 2 Port RC2 : h i e r Ausgang ( Sekunde/Jahr 2)198 +−−−−−−−−−−−−−−− Bit 1 Port RC1 : h i e r Ausgang ( Sekunde/Jahr 1)199 +−−−−−−−−−−−−−− Bit 0 Port RC0 : h i e r Ausgang ( Sekunde/Jahr 0)200 ∗/201202 TRISD = 0b00000000 ; // R i ch tung s r eg i s t e r Port D ( 0 : Ausgang , 1 : Eingang )203 /∗ +−−−−−−−−−−−−−−−−−−−−− Bit 7 Port RD7 : h i e r Ausgang ( Minute/Monat 7)204 +−−−−−−−−−−−−−−−−−−−− Bit 6 Port RD6 : h i e r Ausgang ( Minute/Monat 6)205 +−−−−−−−−−−−−−−−−−−− Bit 5 Port RD5 : h i e r Ausgang ( Minute/Monat 5)206 +−−−−−−−−−−−−−−−−−− Bit 4 Port RD4 : h i e r Ausgang ( Minute/Monat 4)207 +−−−−−−−−−−−−−−−−− Bit 3 Port RD3 : h i e r Ausgang ( Minute/Monat 3)208 +−−−−−−−−−−−−−−−− Bit 2 Port RD2 : h i e r Ausgang ( Minute/Monat 2)209 +−−−−−−−−−−−−−−− Bit 1 Port RD1 : h i e r Ausgang ( Minute/Monat 1)210 +−−−−−−−−−−−−−− Bit 0 Port RD0 : h i e r Ausgang ( Minute/Monat 0)211 ∗/212

5 DEMONSTRATIONSBEISPIEL 31

213 TRISE = 0b00000000 ; // R i ch tung s r eg i s t e r Port D ( 0 : Ausgang , 1 : Eingang )214 /∗ ++++−−−−−−−−−−−−−−−−−− Bit 7−4: P a r a l l e l S lave Port Status /Control B i t s215 +−−−−−−−−−−−−−−−−− Bit 3 Reserve216 +−−−−−−−−−−−−−−−− Bit 2 Port RD2 : h i e r Ausgang (Wochentag 2)217 +−−−−−−−−−−−−−−− Bit 1 Port RD1 : h i e r Ausgang (Wochentag 1)218 +−−−−−−−−−−−−−− Bit 0 Port RD0 : h i e r Ausgang (Wochentag 0)219 ∗/220221 PORTA = 0 ;222 PORTB = 0 ;223 PORTC = 0 ;224 PORTD = 0 ;225 PORTE = 0 ;226227 // ADC kon f i gu r i e r en ( Hier : d eak t i v i e r en )228 ADCON0 = 0b01000000 ; // ADC−Control−Reg i s t e r 0 (Bank 1)229 /∗ ++−−−−−−−−−−−−−−−−−−− Bit 7−6 (ADCS1:ADCS0) : A/D Conersion Clock S e l e c t230 | | | | | | b i t s231 | | | | | | 00 : Fosc/2 ( be i f o s z : 0 − 1 .25 MHz)232 | | | | | | −> 01 : Fosc/8 ( be i f o s z : 1 . 25 − 5 MHz)233 | | | | | | 10 : Fosc / 3 2 . . ( be i f o s z : 5 − 20 MHz)234 | | | | | | 11 : Frc ( be i RC−Os z i l l a t o r )235 +++−−−−−−−−−−−−−−−− Bit 5−3 (CHS2 :CHS0) : Analog Channel S e l e c t b i t s236 | | | −> 000 : channel 0 (RA0/AN0)237 | | | 001 : channel 1 (RA1/AN1)238 | | | 010 : channel 2 (RA2/AN2)239 | | | 011 : channel 3 (RA3/AN3)240 | | | 100 : channel 4 (RA5/AN4)241 | | | 101 : channel 5 (RE0/AN5)242 | | | 110 : channel 6 (RE1/AN6)243 | | | 111 : channel 7 (RE2/AN7)244 +−−−−−−−−−−−−−−− Bit 2 (GO/DONE) : A/D Conversion Status Bit245 | | IF ADON = 1 :246 | | −> 0 : A/D conver s i on not in p r og r e s s247 | | 1 : A/D conver s i on in p r og r e s s248 +−−−−−−−−−−−−−− Bit 1 Reserve249 +−−−−−−−−−−−−− Bit 0 (ADON) : A/D On Bit250 −> 0 : A/D conver ter module i s shut−o f f251 1 : A/D conver ter module i s operat ing252 ∗/253254 ADCON1 = 0b00000111 ; // ADC−Control−Reg i s t e r 1 (Bank 1)255 /∗ +−−−−−−−−−−−−−−−−−−−− Bit 7 (ADFM) : A/D Resul t Formated S e l e c t b i t s256 | | | | | | | −> 0 : Le f t j u s t i f i e d :257 | | | | | | | i n ADRESH: Bit 9 b i s Bit 2258 | | | | | | | i n ADRESL: Bit 1 , Bit 0 , Rest 0259 | | | | | | | 1 : Right j u s t i f i e d :260 | | | | | | | i n ADRESH: 0 0 0 0 0 0 Bit 9 Bit 8261 | | | | | | | i n ADRESL: Bit 7 b i s Bit 0262 +++−−−−−−−−−−−−−−−−− Bit 6−4 Reserve263 ++++−−−−−−−−−−−−− Bit 3−0 (PCFG3:PCFG0) : A/D Port Conf i gurat i on264 Control b i t s265 RE2 RE1 RE0 RA5 RA3 RA2 RA1 RA0 Vref+ Vref−266 0000: A A A A A A A A Vdd Vss267 0001: A A A A Vref+ A A A RA3 Vss268 0010: D D D A A A A A Vdd Vss269 0011: D D D A Vref+ A A A RA3 Vss270 0100: D D D D A D A A Vdd Vss271 0101: D D D D Vref+ D A A RA3 Vss272 −> 011x : D D D D D D D D Vdd Vss273 1000: A A A A Vref+ Vref− A A RA3 RA2274 1001: D D A A A A A A Vdd Vss275 1010: D D A A Vref+ A A A RA3 Vss276 1011: D D A A Vref+ Vref− A A RA3 RA2277 1100: D D D A Vref+ Vref− A A RA3 RA2278 1101: D D D D Vref+ Vref− A A RA3 RA2279 1110: D D D D D D D A Vdd Vss280 1111: D D D D Vref+ Vref− D A RA3 RA2281 ∗/282283 // Za eh l r e g i s t e r f u e r Z e i t b a s i s i n i t i a l i s i e r e n

5 DEMONSTRATIONSBEISPIEL 32

284 cZaeh l e rZe i tbas i s100ms = KONSTZEITBASIS100MS ; // Za eh l r e g i s t e r f u e r 100−ms−Ze i t b a s i s285 // i n i t i a l i s i e r e n286 cZaeh l e rZe i tba s i s 1 s e k = KONSTZEITBASIS1SEK; // Za eh l r e g i s t e r f u e r 1−Sek−Ze i t b a s i s287 // i n i t i a l i s i e r e n288289 // In t e r r up t f r e i g eben290 INTCON = 0b10100000 ; // Inter rupt−Control−Reg i s t e r (Bank 1)291 /∗ +−−−−−−−−−−−−−−−−−−−− Bit 7 (GIE) : Global In t e r r up t Enable b i t292 | | | | | | | 0 : D i sab l e s a l l i n t e r r up t s293 | | | | | | | −> 1 : Enables a l l unmasked i n t e r r up t s294 +−−−−−−−−−−−−−−−−−−− Bit 6 (PEIE) : Pe r i phe r a l In t e r r up t Enable b i t295 | | | | | | −> 0 : D i sab l e s a l l p e r i phe r a l i n t e r r up t s296 | | | | | | 1 : Enables a l l unmasked pe r i phe r a l i n t e r r up t s297 +−−−−−−−−−−−−−−−−−− Bit 5 (T0IE) : Timer 0 Overf low In t e r r up t Enable Bit298 | | | | | 0 : Disabled299 | | | | | −> 1 : Enabled300 +−−−−−−−−−−−−−−−−− Bit 4 (INTE) : RB0/INT External In t e r r up t Enable Bit301 | | | | −> 0 : Disabled302 | | | | 1 : Enabled303 +−−−−−−−−−−−−−−−− Bit 3 (RPIE) : RB Port Change In t e r r up t Enable Bit304 | | | −> 0 : Disabled305 | | | 1 : Enabled306 +−−−−−−−−−−−−−−− Bit 2 (T0IF ) : Timer 0 Overf low In t e r r up t Flag b i t307 | | −> 0 : TMR0 r e g i s t e r did not over f l ow308 | | 1 : TMR0 r e g i s t e r has over f l owed309 +−−−−−−−−−−−−−− Bit 1 (INTF) : RB0/INT External In t e r r up t Flag b i t310 | −> 0 : RB0/INT exte r na l i n t e r r up t did not occur311 | 1 : RB0/INT exte r na l i n t e r r up t occurred312 +−−−−−−−−−−−−− Bit 0 (RBIF) : RB Port Change In t e r r up t Flag b i t313 −> 0 : None o f RB7 :RB4 pins have changed s ta t e314 1 : One o f the RB7 :RB4 pins changed s ta t e315 ∗/316 }317318319 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/320 /∗ Anzeige Demo : ∗/321 /∗ ∗/322 /∗ Aufgabe : ∗/323 /∗ Al l e v i e r Sekunden abwechselnd d i e Uhrzei t und das Datum an den 7−Segment− ∗/324 /∗ Anzeigen ausgeben . Weiters den Wochentag permanent ausgeben . ∗/325 /∗ ∗/326 /∗ Vorgehensweise : ∗/327 /∗ + Den Wert der Sekunde mit dem Unterprogramm DCF Get Sekunde l e s en ∗/328 /∗ + Die ”4−Sekunden−Ze i t b a s i s ” l a e s s t s i ch sehr l e i c h t erzeugen , da d i e s genau dem ∗/329 /∗ Bit mit der Wer t i gke i t 2 en s tp r i ch t (2ˆ2 = 4) . D. h . so l ange Bi t 2 von der ∗/330 /∗ Sekunde ( Reg i s t e r cSekunde ) g e s e t z t i s t d i e Uhrzei t mit den Unterprogrammen ∗/331 /∗ Datum DCF Get Stunde und DCF Get Minute l e s en , i n einen BCD−Wert umwandeln und ∗/332 /∗ am daf ur vorgesehenen Port ausgeben . Die Sekunde e b e n f a l l s i n e inen BCD−Wert ∗/333 /∗ umwandeln und am Port ausgeben . ∗/334 /∗ Das s e l b e g i l t f u e r das Datum, wenn Bit 2 ( von der Sekunde ) n i cht g e s e t z t i s t . ∗/335 /∗ ∗/336 /∗ Uebergabeparameter : ∗/337 /∗ ke i n e r ∗/338 /∗ ∗/339 /∗ Rueckgabeparameter : ∗/340 /∗ ke i n e r ∗/341 /∗ ∗/342 /∗ Anmerkung : ∗/343 /∗ Fuer d i e BCD−Umwandlung (Unterprogramm Dec2Bcd ) s t e l l t der mikroC−Compiler ∗/344 /∗ gee i gne t e Unterprogramme zur Verfuegung , so dass d i e Aufgabe n i cht s e l b s t ∗/345 /∗ programmiert werden muss . ∗/346 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/347 void Anzeige Demo (void )348 {349 char cSekunde ;350351352 cSekunde = DCF Get Sekunde ( ) ;353 i f ( cSekunde . F2)354 {

5 DEMONSTRATIONSBEISPIEL 33

355 // Ausgabe der Uhrzei t356 Stunde Tag BCD = Dec2Bcd (DCF Get Stunde ( ) ) ;357 Minute Monat BCD = Dec2Bcd (DCF Get Minute ( ) ) ;358 Sekunde Jahr BCD = Dec2Bcd ( cSekunde ) ;359 }360 else

361 {362 // Ausgabe des Datums363 Stunde Tag BCD = Dec2Bcd (DCF Get Tag ( ) ) ;364 Minute Monat BCD = Dec2Bcd (DCF Get Monat ( ) ) ;365 Sekunde Jahr BCD = Dec2Bcd (DCF Get Jahr ( ) ) ;366 }367368 // Ausgabe des Wochentages369 Wochentag = DCF Get Wochentag ( ) ;370 }371372373 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Hauptprogramm ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/374375 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/376 /∗ Aufgaben des Hauptprogramms : ∗/377 /∗ + Cont r o l l e r i n i t i a l i s i e r e n ( Unterprogramm In i t ) ∗/378 /∗ + Reg i s t e r f u e r d i e DCF−Dekodierung i n i t i a l i s i e r e n ( Unterprogramm DCF Init ) ∗/379 /∗ + Taet i gke i ten /Unterprogramme , d i e a l l e z y k l i s c h durchge fuehr t werden muessen : ∗/380 /∗ + a l l e 4ms : Unterprogramm zur DCF−Dekodierung ( DCF Routine ) aus fuehren ∗/381 /∗ + a l l e 100ms : Den Status der DCF−Dekodierung am Port A ausgeben und , wenn d i e ∗/382 /∗ di e DCF−Uhr s yn ch r on i s i e r t i s t d i e a k t u e l l e Uhrzei t und das a k tu e l l e Datum ∗/383 /∗ an den Ports B, C und D ausgeben (Unterprogramm : Anzeige Demo ) ∗/384 /∗ + a l l e Sekunde : ” inner e Uhr” mit dem Unterprogramm DCF Innere Uhr aus fuehren ∗/385 /∗ + wenn das Bo t s c h a f t s f l a g DCF Is Neue Sekunde g e s e t z t i s t , das Unterprogramm ∗/386 /∗ DCF UP Sekunde aus fuehren ∗/387 /∗ + wenn das Bo t s c h a f t s f l a g DCF Is Neue Minute g e s e t z t i s t , das Unterprogramm ∗/388 /∗ DCF UP Minute aus fuehren ∗/389 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/390 void main (void )391 {392 // Cont r o l l e r i n i t i a l i s i e r e n393 I n i t ( ) ;394395 // Reg i s t e r f u e r d i e DCF−Dekodierung i n i t i a l i s i e r e n396 DCF Init ( ) ;397398 // End l o s s c h l e i f e399 while (1)400 {401 // Al l e 4ms :402 i f ( bFlagZei tbas i s4ms )403 {404 // DCF−Routine aus fuehren405 DCF Routine ( ) ;406407 // Bo t s c h a f t s f l a g ( f u e r 4ms−Ze i t b a s i s ) zuruecksetzen408 bFlagZei tbas i s4ms = 0 ;409 }410411 // Al l e 100ms :412 i f ( bFlagZei tbas i s100ms )413 {414 Statusanze i ge Lo = DCF Is Low ( ) ;415 Statusanze i g e Hi = DCF Is High ( ) ;416 S t a t u s an z e i g e B i t f e h l e r = DCF Is Bi t f eh l e r ( ) ;417 S ta tu s anze i g e Feh l e r = DCF Is Fehler ( ) ;418 Statusanze i ge Sync = DCF Is Sync ( ) ;419420 // Wenn DCF−Uhr s y n c r o n i s i e r t i s t421 i f ( DCF Is Sync ( ) )422 {423 Anzeige Demo ( ) ;424 }425

5 DEMONSTRATIONSBEISPIEL 34

426 // Bo t s c h a f t s f l a g ( f u e r 100ms−Ze i t b a s i s ) zuruecksetzen427 bFlagZei tbas i s100ms = 0 ;428 }429430 // Jede Sekunde :431 i f ( bF l agZe i tba s i s 1 s ek )432 {433 // Innere−Uhr (DCF) aus f uhren434 DCF Innere Uhr ( ) ;435436 // Bo t s c h a f t s f l a g ( f u e r 1−Sek−Ze i t b a s i s ) zuruecksetzen437 bF l agZe i tba s i s 1 s ek = 0 ;438 }439440 // Bo t s c h a f t s f l a g DCF Is Neue Sekunde g e s e t z t ?441 i f ( DCF Is Neue Sekunde ( ) ) DCF UP Sekunde ( ) ;442443 // Bo t s c h a f t s f l a g DCF Is Neue Minute g e s e t z t ?444 i f ( DCF Is Neue Minute ( ) ) DCF UP Minute ( ) ;445 }446 }

Datei DCF.C:

1 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/2 /∗ Unterprogramme zur DCF−Dekodierung in C ∗/3 /∗ ∗/4 /∗ Compiler : mikroC ∗/5 /∗ ∗/6 /∗ Entwickler : Ste f an Buchgeher ∗/7 /∗ Entwicklungsbeginn der Sof tware : 26 . September 2009 ∗/8 /∗ Funkt i ons f aeh i g s e i t : 26 . September 2009 ∗/9 /∗ Letzte Bearbei tung : 14 . Oktober 2009 ∗/

10 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/1112 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Include−Dateien ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/13 #include ”DCF.H”

141516 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Globale Reg i s t e r ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/17 char cDCF Status ; // DCF−S t a t u s r e g i s t e r18 char cDCF Hi l f s r eg i s t e r ; // H i l f s r e g i s t e r19 char cDCF Telegramm1 ; // in d i e s e Reg i s t e r wird das DCF−Telegramm20 char cDCF Telegramm2 ; // im Sekunden−Takt e i n g e l e s e n . Beginnt e i n e21 char cDCF Telegramm3 ; // neue Minute , so werden d i e s e Reg i s t e r22 char cDCF Telegramm4 ; // ausgewertet , und in d i e entsprechenden23 char cDCF Telegramm5 ; // DCF−Zei t−Datums−Reg i s t e r kop i e r t ( z .B. in das24 char cDCF Telegramm6 ; // Reg i s t e r cDCF Minute BCD25 // char cDCF Telegramm7 ; //26 // char cDCF Telegramm8 ; //27 char cDCF Minute BCD ; // Be inha l te t d i e akt . dekod i e r te Minute (BCD−Format )28 char cDCF Stunde BCD ; // Be inha l te t d i e akt . dekod i e r te Stunde (BCD−Format )29 char cDCF Tag BCD ; // Be inha l te t den akt . dekod i e r ten Tag (BCD−Format )30 char cDCF Monat BCD ; // Be inha l te t den akt . dekod i e r ten Monat (BCD−Format )31 char cDCF Jahr BCD ; // Be inha l te t das akt . dekod i e r te Jahr (BCD−Format )32 char cDCF Wochentag ; // Be inha l te t den akt . dekod i e r ten Wochentag33 // (1=Montag , 2=Dienstag , usw . , 7=Sonntag )34 char cDCF Zusatzinfos ; // Be inha l te t Zusatz in f ormat ionen (Sommer/Winterze i t ,35 // Reserveantenne usw . )36 char cDCF Minute Alt ; // in den Reg i s te rn cDCF xxx Alt be f i nden s i ch d i e37 char cDCF Stunde Alt ; // Uhrzei t und Datumsinfos der vorangegangenen Minute .38 char cDCF Tag Alt ; // Diese werden zur Ueberpruefung des neuen DCF−39 char cDCF Monat Alt ; // Telegramms benoet i g t40 char cDCF Jahr Alt ;41 char cDCF Wochentag Alt ;4243 char cUhr Sekunde ; // Sekundenzaehler der inner en quarzges teuer ten Uhr44 char cUhr Minute ; // Minutenzaehler der inner en quarzges teuer t en Uhr , wird45 // mit jedem gue l t i g en DCF−dekod . Wert s yn ch r on i s i e r t46 char cUhr Stunde ; // Stundenzaehler der inner en quarzges teuer t en Uhr , wird

5 DEMONSTRATIONSBEISPIEL 35

47 // mit jedem gue l t i g en DCF−dekod . Wert s yn ch r on i s i e r t48 char cDatum Wochentag ; // Wochentagszaehler der inner en quarzges teuer t en Uhr ,49 // wird mit jedem gue l t i g en DCF−dekod . Wert synch .50 char cDatum Tag ; // Tageszaeh l e r der inner en quarzges teuer ten Uhr , wird51 // mit jedem gue l t i g en DCF−dekod . Wert s yn ch r on i s i e r t52 char cDatum Monat ; // Monatszaehler der inner en quarzges teuer ten Uhr , wird53 // mit jedem gue l t i g en DCF−dekod . Wert s yn ch r on i s i e r t54 char cDatum Jahr ; // Jah r e s za eh l e r der inner en quarzges teuer ten Uhr , wird55 // mit jedem gue l t i g en DCF−dekod . Wert s yn ch r on i s i e r t565758 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Bi ts in den g loba l en Reg i s te rn ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/59 /∗ Reg i s t e r cDCF Status ∗/60 #define bDCF Low cDCF Status . F0 // gesetzt , wenn Low−Signa l erkannt61 #define bDCF High cDCF Status . F1 // gesetzt , wenn High−Signa l erkannt62 #define bDCF Bitfehler cDCF Status . F2 // gesetzt , wenn weder High noch Low63 #define bDCF Fehler cDCF Status . F3 // gesetzt , wenn e in Fehler erkannt64 #define bDCF Sync cDCF Status . F4 // gesetzt , wenn Uhr mit DCF s yn ch r on i s i e r t6566 /∗ Reg i s t e r cDCF Hi l f s r eg i s t e r ∗/67 #define bDCF Port Neu cDCF Hi l f s r eg i s t e r . F0 // Akt . Zustand DCF−Porte ingang68 #define bDCF Port Alt cDCF Hi l f s r eg i s t e r . F1 // Vorhergehender Zustand am DCF−69 // Porte ingang70 #define bDCF Neue Sekunde cDCF Hi l f s r eg i s t e r . F2 // gesetzt , wenn neue Sekunde begonnen71 #define bDCF Neue Minute cDCF Hi l f s r eg i s t e r . F3 // gesetzt , wenn neue Minute begonnen7273 /∗ Reg i s t e r cDCF Zusatzinfos ∗/74 #define bDCF Rerserveantenne cDCF Zusatzinfos . F0 // Reserveantenne75 #define bDCF Zeitumstellung cDCF Zusatzinfos . F1 // Vorankuendigung der76 // Sommer/Winterze i t−Umstel lung77 #define bDCF Sommerzeit cDCF Zusatzinfos . F2 // Sommerzeit78 #define bDCF Winterzeit cDCF Zusatzinfos . F3 // Winter ze i t79 #define bDCF Schaltsekunde cDCF Zusatzinfos . F4 // Vorankuendigung e i n e r z u s a e t z l i c h e80 // Schal tsekunde818283 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Unterprogramme und Funktionen ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/8485 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/86 /∗ DCF Init : ∗/87 /∗ ∗/88 /∗ Aufgabe : ∗/89 /∗ Diverse ( g l oba l e ) Reg i s t e r f u e r d i e DCF−Dekodierung und f r e i l a u f e n d e Uhr ∗/90 /∗ i n i t i a l i s i e r e n . ∗/91 /∗ ∗/92 /∗ Uebergabeparameter : ∗/93 /∗ ke i n e r ∗/94 /∗ ∗/95 /∗ Rueckgabeparameter : ∗/96 /∗ ke i n e r ∗/97 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/98 void DCF Init (void )99 {

100 cDCF Status = 0 ;101 cDCF Hi l f s r eg i s t e r = 0 ;102 bDCF Fehler = 1 ;103 bDCF Port Neu = bDCF Port In ;104105 cUhr Sekunde = 0 ;106 cUhr Minute = 0 ;107 cUhr Stunde = 0 ;108 cDatum Wochentag = 0 ;109 cDatum Tag = 0 ;110 cDatum Monat = 0 ;111 cDatum Jahr = 0 ;112113 cDCF Minute Alt = 99 ;114 cDCF Stunde Alt = 99 ;115 cDCF Tag Alt = 99 ;116 cDCF Monat Alt = 99 ;117 cDCF Jahr Alt = 99 ;

5 DEMONSTRATIONSBEISPIEL 36

118 cDCF Wochentag Alt = 99 ;119 }120121122 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/123 /∗ DCF Routine : ∗/124 /∗ ∗/125 /∗ Das Unterprogramm DCF Routine i s t f u r d i e DCF−Dekodierung d i e w i ch t i g s t e Komponente . ∗/126 /∗ ∗/127 /∗ Diese Routine wird ca . a l l e 4 ms aufgeru f en ∗/128 /∗ ∗/129 /∗ Aufgabe und Vorgehensweise : ∗/130 /∗ Die Aufgabe des Unterprogramms DCF Routine bes teht dar in aus den Abtastungen ∗/131 /∗ herauszuf inden , ob e in Low , e in High oder e in Minutenwechsel gesendet wurde . ∗/132 /∗ Dazu wird be i jedem Aufruf des Unterprogramms DCF Routine entweder das s t a t i s c h e ∗/133 /∗ Za eh l r e g i s t e r cDCF Puls oder das s t a t i s c h e Za eh l r e g i s t e r cDCF Pause um 1 erhoeht ∗/134 /∗ ( inkr ement i e r t ) , wenn s i ch der Pegel vom DCF−Eingang zum vorhergehenden Aufruf ∗/135 /∗ d i e s e s Unterprogramms ni cht veraender t hat . I s t der DCF−Eingang Low ( a l s o l o g i s c h ∗/136 /∗ 0) , so wird das Za eh l r e g i s t e r cDCF Puls um 1 erhoeht , i s t der DCF−Eingang High ∗/137 /∗ ( a l s o l o g i s c h 1) , so wird das Za eh l r e g i s t e r cDCF Pause um 1 erhoeht . Beide Zaehl− ∗/138 /∗ r e g i s t e r koennen maximal den Wert 255 aufnehmen , was e i n e r Z e i t von 1020 ms ( oder ∗/139 /∗ 1 ,02 Sekunden ) en t sp r i ch t (= 255 ∗ 4ms) . ∗/140 /∗ Unter s che idet s i ch der a k tu e l l e Pegel des DCF−Eingangs mit dem Pegel vom vorher− ∗/141 /∗ gehenden Aufruf , so s p r i c h t man von e i n e r Flanke , wobei h i e r zwischen e i n e r ∗/142 /∗ f a l l enden und e i n e r s te i genden Flanke unter s ch i eden werden muss . Bei e i n e r ∗/143 /∗ s te i genden Flanke ( der a k tu e l l e Pegel des DCF−Eingangs i s t l o g i s c h 1) , wird das ∗/144 /∗ s t a t i s c h e Za eh l r e g i s t e r cDCF Pause ge l o e s ch t . Ansch l i e s s end e r f o l g t e i n e Aus− ∗/145 /∗ wertung des s t a t i s c h en Za eh l r e g i s t e r s cDCF Puls . Be inha l te t d i e s e s Z a eh l r e g i s t e r ∗/146 /∗ einen Wert zwischen den Konstanten KONSTDCFHMIN und KONSTDCFHMAX, so wurde e in ∗/147 /∗ High des DCF−Telegramms e rm i t t e l t . Im DCF−S t a t u s r e g i s t e r ( cDCF Status ) werden ∗/148 /∗ daher d i e Flags bDCF High und bDCF Neue Sekunde g e s e t z t . Das Flag ∗/149 /∗ bDCF Neue Sekunde d i ent a l s Zeichen e i n e r neu empfangenen und gue l t i g en Sekunde . ∗/150 /∗ Beinha l te t das Z a eh l r e g i s t e r cDCF Puls e inen Wert zwischen den Konstanten ∗/151 /∗ KONSTDCFLMIN und KONSTDCFLMAX, so wurde e in Low des DCF−Telegramms e rm i t t e l t . Im ∗/152 /∗ DCF−S t a t u s r e g i s t e r ( cDCF Status ) werden daher d i e Flags bDCF Low und ∗/153 /∗ bDCF Neue Sekunde g e s e t z t . Das Flag bDCF Neue Sekunde d i ent auch h i e r a l s Zeichen ∗/154 /∗ e i n e r neu empfangenen und gue l t i g en Sekunde . Be inha l te t das s t a t i s c h e Zaehl− ∗/155 /∗ r e g i s t e r cDCF Puls e inen Wert der weder zwischen den Konstanten KONSTDCFHMIN und ∗/156 /∗ KONSTDCFHMAX noch zwischen den Konstanten KONSTDCFLMIN und KONSTDCFLMAX l i e g t , so ∗/157 /∗ handel t es s i ch um einen Ueber t ragungs f eh l e r . In diesem Fa l l werden d i e Fehler− ∗/158 /∗ f l a g s bDCF Fehler und bDCF Bitfehler im DCF−S t a t u s r e g i s t e r ( cDCF Status ) g e s e t z t . ∗/159 /∗ Das Flag bDCF Neue Sekunde wird h i e r aber n i cht gesetzt , da es s i ch in diesem ∗/160 /∗ Fa l l um ke ine gu e l t i g e Sekunde handel t . Das F eh l e r f l a g bDCF Fehler wird e r s t be i ∗/161 /∗ der Erkennung e i n e r neuen Minute wieder g e l o e s ch t . ∗/162 /∗ ∗/163 /∗ Bei e i n e r f a l l enden Flanke ( der a k tu e l l e Pegel des DCF−Eingangs i s t l o g i s c h 0) ∗/164 /∗ wird nur das s t a t i s c h e Za eh l r e g i s t e r cDCF Puls g e l o e s ch t . ∗/165 /∗ ∗/166 /∗ In der 59 . Sekunde e r f o l g t ke ine Absenkung des Traegers . Da es a l s o in der 59 . ∗/167 /∗ Sekunde ke ine f a l l e nd e Flanke gibt , g i b t es auch ke ine s t e i g ende Flanke . Das ∗/168 /∗ Za eh l r e g i s t e r cDCF Pause l a e u f t ueber , da es nur einen Zaeh lber e i ch von 0 b i s 255 ∗/169 /∗ b e s i t z t . D i es er Ueber lauf wird h i e r ausgenuetzt . Zur Bestimmung e i n e r neuen ∗/170 /∗ Minute bzw . zur Bestimmung des Telegrammbeginns . I s t das F e h l e r f l a g gesetzt , so ∗/171 /∗ wird es nun ge l o e s ch t . War es n i cht gesetzt , so wird das Flag bDCF Neue Minute im ∗/172 /∗ DCF−H i l f s r e g i s t e r ( cDCF Hi l f s r eg i s t e r ) g e s e t z t . ∗/173 /∗ ∗/174 /∗ Uebergabeparameter : ∗/175 /∗ ke i n e r ∗/176 /∗ ∗/177 /∗ Rueckgabeparameter : ∗/178 /∗ ke i n e r ∗/179 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/180 void DCF Routine (void )181 {182 stat ic char cDCF Puls = 0 ; // Impul s ze i t des DCF−Impulses183 stat ic char cDCF Pause = 0 ; // Ze i t zwischen zwei DCF−Impulsen184185186 bDCF Port Alt = bDCF Port Neu ;187 bDCF Port Neu = bDCF Port In ;188

5 DEMONSTRATIONSBEISPIEL 37

189 i f ( bDCF Port Neu == bDCF Port Alt )190 {191 // Der Pegel am Portpin ( bDCF Port In ) hat s i ch n i cht veraender t192 i f ( bDCF Port Neu )193 {194 cDCF Pause++;195 i f ( cDCF Pause > KONSTDCFNEUEMIN)196 {197 // Ueber lauf −> Neue Minute198 i f ( bDCF Fehler )199 {200 // Wenn Feh l e r f l a g ( bDCF Fehler ) g e s e t z t d i e s e s nun loeschen201 bDCF Fehler = 0 ;202 }203 else

204 {205 // Anforderungs f l ag f u e r ”Neue Minute”206 bDCF Neue Minute = 1 ;207 }208 }209 }210 else

211 {212 cDCF Puls++;213 }214 }215 else

216 {217 // Der Pegel am Portpin ( bDCF Port In ) hat s i ch veraender t218 i f ( bDCF Port Neu )219 {220 // s t e i g ende Flanke221 cDCF Pause = 0 ;222223 // Pruefen , ob e in High empfangen wurde224 i f ( ( cDCF Puls > KONSTDCFHMIN) && ( cDCF Puls < KONSTDCFHMAX) )225 {226 bDCF High = 1 ;227 bDCF Low = 0 ;228 bDCF Bitfehler = 0 ;229 bDCF Neue Sekunde = 1 ;230 }231232 // Pruefen , ob e in Low empfangen wurde233 else i f ( ( cDCF Puls > KONSTDCFLMIN) && ( cDCF Puls < KONSTDCFLMAX) )234 {235 bDCF High = 0 ;236 bDCF Low = 1 ;237 bDCF Bitfehler = 0 ;238 bDCF Neue Sekunde = 1 ;239 }240 else

241 {242 // Fehler243 bDCF Bitfehler = 1 ;244 bDCF Fehler = 1 ;245 bDCF High = 0 ;246 bDCF Low = 0 ;247 }248 }249 else

250 {251 // f a l l e n d e Flanke252 cDCF Puls = 0 ;253 }254 }255 }256257258 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/259 /∗ DCF UP Sekunde : ∗/

5 DEMONSTRATIONSBEISPIEL 38

260 /∗ ∗/261 /∗ Aufgaben : ∗/262 /∗ + j e nachdem ob das Bit bDCF Low oder das Bit bDCF High g e s e t z t i s t d i e s e s Bit ∗/263 /∗ dem Telegramm ( Reg i s t e r cDCF Telegramm1 b i s cDCF Telegramm8) hinzufuegen ∗/264 /∗ + Anforderungs f l ag ( Flag bDCF Neue Sekunde ) zuruecksetzen ∗/265 /∗ ∗/266 /∗ Vorgehensweise : ∗/267 /∗ I s t das Flag bDCF Low ( im Reg i s t e r cDCF Status ) g e s e t z t das Car ry f l ag ( im SFR ∗/268 /∗ STATUS) loes chen . I s t aber das Flag bDCF High ( e b e n f a l l s im Reg i s t e r cDCF Status ) ∗/269 /∗ gesetzt , das Car ry f l ag s e t z t en . D i es es Car ry f l ag nun dem Telegramm hinzufuegen . ∗/270 /∗ Dieser Vorgang e r f o l g t mit einem so genannten Sch i ebebe f eh l . Dabei werden a l l e ∗/271 /∗ Bi ts des Reg i s t e r s cDCF Telegramm1 auf d i e naechst hoehere Pos i t i on verschoben . ∗/272 /∗ ( Bit 6 wandert i n s Bit 7 , Bit 5 wandert i n s Bit 6 usw . Bit 0 wandert i n s Bit 1) . ∗/273 /∗ Der Inha l t vom Car ry f l ag wandert i n s Bit 0 . Der Inha l t von Bit 7 wird i n s Carry− ∗/274 /∗ f l a g geschoben . Bei den Reg i s t e r cDCF Telegramm2 b i s cDCF Telegramm6 e r f o l g t ∗/275 /∗ de r s e l b e Vorgang . (Der Inha l t von Bit 7 des Reg i s t e r s cDCF Telegramm1 wird i n s ∗/276 /∗ Carry geschoben , und das Carry aber we i te r in das Bit 0 des Reg i s t e r s ∗/277 /∗ cDCF Telegramm2) . Achtung : Diese Sch i ebebe f eh l e s ind nur a l s Assembler−Anweis− ∗/278 /∗ ungen ver fuegbar . Daher s ind d i e s e Be f eh l e in einem asm−Block ! ∗/279 /∗ ∗/280 /∗ Uebergabeparameter : ∗/281 /∗ ke i n e r ∗/282 /∗ ∗/283 /∗ Rueckgabeparameter : ∗/284 /∗ ke i n e r ∗/285 /∗ ∗/286 /∗ Anmerkung : ∗/287 /∗ Die Flags bDCF Low und bDCF High koennen n i e g l e i c h z e i t i g g e s e t z t s e i n . Es i s t ∗/288 /∗ nur moegl ich , dass entweder nur bDCF Low oder nur bDCF High g e s e t z t i s t , aber n i e ∗/289 /∗ beide g l e i c h z e i t i g . ∗/290 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/291 void DCF UP Sekunde (void )292 {293 i f ( (bDCF Low) | | (bDCF High) )294 {295 i f (bDCF Low)296 {297 // Carry = 0298 STATUS. F0 = 0 ;299 }300 else

301 {302 // Carry = 1 ;303 STATUS. F0 = 1 ;304 }305306 asm {307 RLF cDCF Telegramm1 , 1308 RLF cDCF Telegramm2 , 1309 RLF cDCF Telegramm3 , 1310 RLF cDCF Telegramm4 , 1311 RLF cDCF Telegramm5 , 1312 RLF cDCF Telegramm6 , 1313 // RLF cDCF Telegramm7 , 1314 // RLF cDCF Telegramm8 , 1315 }316 }317318 // Anforderungs f l ag l oes chen319 bDCF Neue Sekunde = 0 ;320 }321322323 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/324 /∗ DCF UP Minute : ∗/325 /∗ ∗/326 /∗ Aufgaben : ∗/327 /∗ + Datum, Uhrzei t und d i e Zusatz in f ormat i onen aus den Reg i s t e rn cDCF Telegramm1 ∗/328 /∗ b i s cDCF Telegramm6 zusammensetzen . ∗/329 /∗ + Das so eben e rm i t t e l t e Telegramm mit dem Telegramm der vorhergehenden Minute ∗/330 /∗ ve r g l e i ch en . Die so eben e rm i t t e l t e Minute muss dabei um 1 g r o e s s e r a l s d i e vor−∗/

5 DEMONSTRATIONSBEISPIEL 39

331 /∗ hergehende Minute se in , und d i e so eben e rm i t t e l t en Werte f u e r d i e Stunde , Tag , ∗/332 /∗ Monat , Jahr und Wochentag muss mit den Werten des vorhergehenden Telegramms ∗/333 /∗ uebereinstimmen . ACHTUNG: Bei d i e s e r e in f achen Ueberpruefung wird der Uebergang ∗/334 /∗ von z . B. 13:59 auf 14:00 a l s f a l s c h gewertet , da s i ch h i e r d i e Stunde aendert , ∗/335 /∗ und auch d i e Minute um mehr a l s 1 . Wuerden h i e r a l l e moegl ichen Uebergaenge ∗/336 /∗ be rueck s i ch t i g t , dann wuerde d i e s e s Unterprogramm noch umfangreicher a l s es ∗/337 /∗ ohnehin schon i s t werden . Durch d i e s e Vereinfachung dauert d i e Synchron i s i e rung ∗/338 /∗ im schl immsten Fa l l nur e i n e Minute l a enge r . ∗/339 /∗ + Das a l t e Datum bzw . d i e a l t e Uhrzei t ( von der vorhergehenden Minute ) durch das ∗/340 /∗ neue Datum bzw . Uhrzei t e r s e t z en . Dies i s t f u e r d i e Ueberpruefung des naechsten ∗/341 /∗ Telegramms notwendig . ∗/342 /∗ + Wenn das neu empfangene Datum bzw . d i e neu empfangene Uhrze i t g u e l t i g i s t , d i e ∗/343 /∗ BCD−kod i e r ten Datums− bzw . Uhrzeitkomponenten in e i n e b inaer e Form umwandeln ∗/344 /∗ und damit d i e mi t l au f ende Uhr synch r on i s i e r en . Das Flag bDCF Sync im Reg i s t e r ∗/345 /∗ cDCF Status s etzen . D i es es g e s e t z t e Flag kennzeichnet , dass d i e mi t l au f ende Uhr ∗/346 /∗ mit der DCF−Uhr s yn ch r on i s i e r t i s t . ∗/347 /∗ + Anforderungs f l ag ( Flag bDCF Neue Minute im Reg i s t e r cDCF Status ) zuruecksetzen . ∗/348 /∗ ∗/349 /∗ Uebergabeparameter : ∗/350 /∗ ke i n e r ∗/351 /∗ ∗/352 /∗ Rueckgabeparameter : ∗/353 /∗ ke i n e r ∗/354 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/355 void DCF UP Minute (void )356 {357 // Jahr zusammensetzen (BCD−Format )358 cDCF Jahr BCD = 0 ;359 i f ( cDCF Telegramm1 . F1) cDCF Jahr BCD . F7 = 1 ;360 i f ( cDCF Telegramm1 . F2) cDCF Jahr BCD . F6 = 1 ;361 i f ( cDCF Telegramm1 . F3) cDCF Jahr BCD . F5 = 1 ;362 i f ( cDCF Telegramm1 . F4) cDCF Jahr BCD . F4 = 1 ;363 i f ( cDCF Telegramm1 . F5) cDCF Jahr BCD . F3 = 1 ;364 i f ( cDCF Telegramm1 . F6) cDCF Jahr BCD . F2 = 1 ;365 i f ( cDCF Telegramm1 . F7) cDCF Jahr BCD . F1 = 1 ;366 i f ( cDCF Telegramm2 . F0) cDCF Jahr BCD . F0 = 1 ;367368 // Monat zusammensetzen (BCD−Format )369 cDCF Monat BCD = 0 ;370 i f ( cDCF Telegramm2 . F1) cDCF Monat BCD . F4 = 1 ;371 i f ( cDCF Telegramm2 . F2) cDCF Monat BCD . F3 = 1 ;372 i f ( cDCF Telegramm2 . F3) cDCF Monat BCD . F2 = 1 ;373 i f ( cDCF Telegramm2 . F4) cDCF Monat BCD . F1 = 1 ;374 i f ( cDCF Telegramm2 . F5) cDCF Monat BCD . F0 = 1 ;375376 // Wochentag zusammensetzen (BCD−Format )377 cDCF Wochentag = 0 ;378 i f ( cDCF Telegramm2 . F6) cDCF Wochentag . F2 = 1 ;379 i f ( cDCF Telegramm2 . F7) cDCF Wochentag . F1 = 1 ;380 i f ( cDCF Telegramm3 . F0) cDCF Wochentag . F0 = 1 ;381382 // Tag zusammensetzen (BCD−Format )383 cDCF Tag BCD = 0 ;384 i f ( cDCF Telegramm3 . F1) cDCF Tag BCD . F5 = 1 ;385 i f ( cDCF Telegramm3 . F2) cDCF Tag BCD . F4 = 1 ;386 i f ( cDCF Telegramm3 . F3) cDCF Tag BCD . F3 = 1 ;387 i f ( cDCF Telegramm3 . F4) cDCF Tag BCD . F2 = 1 ;388 i f ( cDCF Telegramm3 . F5) cDCF Tag BCD . F1 = 1 ;389 i f ( cDCF Telegramm3 . F6) cDCF Tag BCD . f0 = 1 ;390391 // Stunde zusammensetzen (BCD−Format )392 cDCF Stunde BCD = 0 ;393 i f ( cDCF Telegramm4 . F0) cDCF Stunde BCD . F5 = 1 ;394 i f ( cDCF Telegramm4 . F1) cDCF Stunde BCD . F4 = 1 ;395 i f ( cDCF Telegramm4 . F2) cDCF Stunde BCD . F3 = 1 ;396 i f ( cDCF Telegramm4 . F3) cDCF Stunde BCD . F2 = 1 ;397 i f ( cDCF Telegramm4 . F4) cDCF Stunde BCD . F1 = 1 ;398 i f ( cDCF Telegramm4 . F5) cDCF Stunde BCD . F0 = 1 ;399400 // Minute zusammensetzen (BCD−Format )401 cDCF Minute BCD = 0 ;

5 DEMONSTRATIONSBEISPIEL 40

402 i f ( cDCF Telegramm4 . F7) cDCF Minute BCD . F6 = 1 ;403 i f ( cDCF Telegramm5 . F0) cDCF Minute BCD . F5 = 1 ;404 i f ( cDCF Telegramm5 . F1) cDCF Minute BCD . F4 = 1 ;405 i f ( cDCF Telegramm5 . F2) cDCF Minute BCD . F3 = 1 ;406 i f ( cDCF Telegramm5 . F3) cDCF Minute BCD . F2 = 1 ;407 i f ( cDCF Telegramm5 . F4) cDCF Minute BCD . F1 = 1 ;408 i f ( cDCF Telegramm5 . F5) cDCF Minute BCD . F0 = 1 ;409410 // Zusa t z i n f o s zusammensetzen411 cDCF Zusatzinfos = 0 ;412 i f ( cDCF Telegramm5 . F7) cDCF Zusatzinfos . F4 = 1 ;413 i f ( cDCF Telegramm6 . F0) cDCF Zusatzinfos . F3 = 1 ;414 i f ( cDCF Telegramm6 . F1) cDCF Zusatzinfos . F2 = 1 ;415 i f ( cDCF Telegramm6 . F2) cDCF Zusatzinfos . F1 = 1 ;416 i f ( cDCF Telegramm6 . F3) cDCF Zusatzinfos . F0 = 1 ;417418 // Neues Telegramm mit dem a l t en Telegramm ver g l e i ch en419 bDCF Fehler = 0 ; // zue r s t F eh l e r f l a g l oes chen420 i f (cDCF Minute BCD − cDCF Minute Alt − 1) bDCF Fehler = 1 ; // Minuten pruefen421 i f ( cDCF Stunde BCD − cDCF Stunde Alt ) bDCF Fehler = 1 ; // Stunden pruefen422 i f (cDCF Tag BCD − cDCF Tag Alt ) bDCF Fehler = 1 ; // Tag pruefen423 i f (cDCF Monat BCD − cDCF Monat Alt ) bDCF Fehler = 1 ; // Monat pruefen424 i f (cDCF Jahr BCD − cDCF Jahr Alt ) bDCF Fehler = 1 ; // Jahr pruefen425 i f ( cDCF Wochentag − cDCF Wochentag Alt ) bDCF Fehler = 1 ; // Wochentag pruefen426427 // Al tes Telegramm durch das neue Telegramm er s e t z en428 cDCF Minute Alt = cDCF Minute BCD ;429 cDCF Stunde Alt = cDCF Stunde BCD ;430 cDCF Tag Alt = cDCF Tag BCD ;431 cDCF Monat Alt = cDCF Monat BCD ;432 cDCF Jahr Alt = cDCF Jahr BCD ;433 cDCF Wochentag Alt = cDCF Wochentag ;434435 // Wenn DCF−Telegramm kor r ekt f r e i l a u f e n d e Uhr und Datum mit der DCF−dekod i e r ten436 // Uhrzei t (und dem Datum) laden437 i f ( bDCF Fehler == 0)438 {439 cUhr Stunde = Bcd2Dec ( cDCF Stunde BCD) ;440 cUhr Minute = Bcd2Dec ( cDCF Minute BCD) ;441 cUhr Sekunde = 0 ;442 cDatum Tag = Bcd2Dec (cDCF Tag BCD) ;443 cDatum Monat = Bcd2Dec (cDCF Monat BCD) ;444 cDatum Jahr = Bcd2Dec ( cDCF Jahr BCD) ;445 cDatum Wochentag = cDCF Wochentag ;446447 bDCF Sync = 1 ;448 }449 else

450 {451 bDCF Fehler = 0 ;452 }453454 // Anforderungs f l ag l oes chen455 bDCF Neue Minute = 0 ;456 }457458459 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/460 /∗ DCF Innere Uhr : ∗/461 /∗ ∗/462 /∗ Aufgabe : ∗/463 /∗ Fuer den Fa l l dass kein g u e l t i g e s DCF−Telegramm empfangen werden kann so r g t ∗/464 /∗ d i e s e s Unterprogramm dafuer , dass d i e Uhrzei t trotzdem jede Sekunde a k t u a l i s i e r t ∗/465 /∗ wird . I s t f u e r e i n e l a enge r e Ze i t kein ko r r ek t e r DCF−Empfang moegl ich , so wuerden ∗/466 /∗ di e Minuten , Stunden , Tage usw . stehen b l e iben , da ja im Unterprogramm ∗/467 /∗ DCF UP Minute nur gu e l t i g e DCF−Telegramme uebernommen werden . D i es es Unter− ∗/468 /∗ programm wird a l s o p a r a l l e l zu den Unterprogrammen f u r d i e DCF−Dekodierung aufge− ∗/469 /∗ ru f en . ∗/470 /∗ ∗/471 /∗ Vorgehensweise : ∗/472 /∗ Die Sekunden ( Reg i s t e r cUhr Sekunde ) um 1 erhoehen . Be inha l te t d i e s e s Reg i s t e r ∗/

5 DEMONSTRATIONSBEISPIEL 41

473 /∗ nun den Wert 60 , so beginnt e i n e neue Minute . Daher d i e Sekunden loes chen und d i e ∗/474 /∗ Minuten ( Reg i s t e r cUhr Minute ) um 1 erhoehen . Be inha l te t d i e s e s Reg i s t e r nun den ∗/475 /∗ Wert 60 , so beginnt e i n e neue Stunde . Daher d i e Minuten loes chen und d i e Stunden ∗/476 /∗ ( Reg i s t e r cUhr Stunde ) um 1 erhoehen . Be inha l te t d i e s e s Reg i s t e r nun den Wert 24 , ∗/477 /∗ so beginnt e in neuer Tag . Daher d i e Stunden loes chen . I s t das Mitzaehlen des ∗/478 /∗ Datums notwendig , so muss nun e in Reg i s t e r f u e r den Tag ( z .B. cDatum Tag) um 1 ∗/479 /∗ erhoeht werden und d i e s e s Ueberpruef t werden , wobei d i e s e Pruefung nun n i cht mehr ∗/480 /∗ so e i n f a ch i s t , da j a j ede r Monat un t e r s c h i e d l i c h v i e l e Tage b e s i t z t . Erschwerend ∗/481 /∗ kommt auch noch hinzu , dass auch d i e Scha l t j ah r e mite inbezogen werden muessen ! ∗/482 /∗ ∗/483 /∗ Uebergabeparameter : ∗/484 /∗ ke i n e r ∗/485 /∗ ∗/486 /∗ Rueckgabeparameter : ∗/487 /∗ ke i n e r ∗/488 /∗ ∗/489 /∗ Achtung : ∗/490 /∗ Dieses Unterprogramm muss j ede Sekunde aufgeru f en werden ∗/491 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/492 void DCF Innere Uhr (void )493 {494 cUhr Sekunde++; // Sekundenz ahler um 1 erhoehen495496 i f ( cUhr Sekunde == 60)497 {498 cUhr Sekunde = 0 ;499 cUhr Minute++;500501 i f ( cUhr Minute == 60)502 {503 cUhr Minute = 0 ;504 cUhr Stunde++;505506 i f ( cUhr Stunde == 24)507 {508 cUhr Stunde = 0 ;509 cDatum Tag++;510 cDatum Wochentag++;511512 i f ( cDatum Wochentag == 7)513 {514 cDatum Wochentag = 0 ;515 }516 }517 }518 }519 }520521522 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/523 /∗ DCF Get Sekunde : ∗/524 /∗ ∗/525 /∗ Aufgabe : ∗/526 /∗ Dieses Unterprogramm g ib t den dez imalkod i e r ten Wert der Sekunde ( im globa l en ∗/527 /∗ Reg i s t e r cUhr Sekunde ) an das au f ru f ende Programm . ∗/528 /∗ ∗/529 /∗ Uebergabeparameter : ∗/530 /∗ ke i n e r ∗/531 /∗ ∗/532 /∗ Rueckgabeparameter : ∗/533 /∗ Sekunde ( dez imalkod i e r t ) ∗/534 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/535 char DCF Get Sekunde (void )536 {537 return ( cUhr Sekunde ) ;538 }539540541 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/542 /∗ DCF Get Minute : ∗/543 /∗ ∗/

5 DEMONSTRATIONSBEISPIEL 42

544 /∗ Aufgabe : ∗/545 /∗ Dieses Unterprogramm g ib t den dez imalkod i e r ten Wert der Minute ( im g loba l en ∗/546 /∗ Reg i s t e r cUhr Minute ) an das au f ru f ende Programm . ∗/547 /∗ ∗/548 /∗ Uebergabeparameter : ∗/549 /∗ ke i n e r ∗/550 /∗ ∗/551 /∗ Rueckgabeparameter : ∗/552 /∗ Minute ( dez imalkod i e r t ) ∗/553 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/554 char DCF Get Minute (void )555 {556 return ( cUhr Minute ) ;557 }558559560 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/561 /∗ DCF Get Stunde : ∗/562 /∗ ∗/563 /∗ Aufgabe : ∗/564 /∗ Dieses Unterprogramm g ib t den dez imalkod i e r ten Wert der Stunde ( im globa l en ∗/565 /∗ Reg i s t e r cUhr Stunde ) an das au f ru f ende Programm . ∗/566 /∗ ∗/567 /∗ Uebergabeparameter : ∗/568 /∗ ke i n e r ∗/569 /∗ ∗/570 /∗ Rueckgabeparameter : ∗/571 /∗ Stunde ( dez imalkod i e r t ) ∗/572 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/573 char DCF Get Stunde (void )574 {575 return ( cUhr Stunde ) ;576 }577578579 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/580 /∗ DCF Get Tag : ∗/581 /∗ ∗/582 /∗ Aufgabe : ∗/583 /∗ Dieses Unterprogramm g ib t den dez imalkod i e r ten Wert des Kalendertag ’ s ( im ∗/584 /∗ g loba l en Reg i s t e r cDatum Tag) an das au f ru f ende Programm . ∗/585 /∗ ∗/586 /∗ Uebergabeparameter : ∗/587 /∗ ke i n e r ∗/588 /∗ ∗/589 /∗ Rueckgabeparameter : ∗/590 /∗ Tag ( dez imalkod i e r t ) ∗/591 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/592 char DCF Get Tag (void )593 {594 return ( cDatum Tag) ;595 }596597598 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/599 /∗ DCF Get Monat : ∗/600 /∗ ∗/601 /∗ Aufgabe : ∗/602 /∗ Dieses Unterprogramm g ib t den dez imalkod i e r ten Wert des Kalendertmonat ’ s ( im ∗/603 /∗ g loba l en Reg i s t e r cDatum Monat) an das au f ru f ende Programm . ∗/604 /∗ ∗/605 /∗ Uebergabeparameter : ∗/606 /∗ ke i n e r ∗/607 /∗ ∗/608 /∗ Rueckgabeparameter : ∗/609 /∗ Monat ( dez imalkod i e r t ) ∗/610 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/611 char DCF Get Monat (void )612 {613 return ( cDatum Monat ) ;614 }

5 DEMONSTRATIONSBEISPIEL 43

615616617 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/618 /∗ DCF Get Jahr : ∗/619 /∗ ∗/620 /∗ Aufgabe : ∗/621 /∗ Dieses Unterprogramm g ib t den dez imalkod i e r ten Wert des Ka l ender j ahr es ( im ∗/622 /∗ g loba l en Reg i s t e r cDatum Jahr ) an das au f ru f ende Programm . ∗/623 /∗ ∗/624 /∗ Uebergabeparameter : ∗/625 /∗ ke i n e r ∗/626 /∗ ∗/627 /∗ Rueckgabeparameter : ∗/628 /∗ Jahr ( dez imalkod i e r t ) ∗/629 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/630 char DCF Get Jahr (void )631 {632 return ( cDatum Jahr ) ;633 }634635636 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/637 /∗ DCF Get Wochentag : ∗/638 /∗ ∗/639 /∗ Aufgabe : ∗/640 /∗ Dieses Unterprogramm g ib t den Wert des Wochentag ’ s ( im g loba l en Reg i s t e r ∗/641 /∗ cDatum Wochentag ) an das au f ru f ende Programm . ∗/642 /∗ ∗/643 /∗ Uebergabeparameter : ∗/644 /∗ ke i n e r ∗/645 /∗ ∗/646 /∗ Rueckgabeparameter : ∗/647 /∗ Wochentag (1 = Montag , 2 = Dienstag , . . . , 7 = Sonntag ) ∗/648 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/649 char DCF Get Wochentag (void )650 {651 return ( cDatum Wochentag ) ;652 }653654655 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/656 /∗ DCF Get Status : ∗/657 /∗ ∗/658 /∗ Aufgabe : ∗/659 /∗ Dieses Unterprogramm g ib t den Inha l t des S t a t u s r e g i s t e r s f u e r d i e DCF−Dekodierung ∗/660 /∗ ( im g loba l en Reg i s t e r cDCF Status ) an das au f ru f ende Programm . ∗/661 /∗ ∗/662 /∗ Uebergabeparameter : ∗/663 /∗ ke i n e r ∗/664 /∗ ∗/665 /∗ Rueckgabeparameter : ∗/666 /∗ S t a t u s r e g i s t e r der DCF−Dekodierung ∗/667 /∗ ∗/668 /∗ Anmerkung : ∗/669 /∗ Bedeutung der e i n z e l n en Bit s i eh e we i te r oben unter ”Bi t s in den g loba l en ∗/670 /∗ Reg i s te rn ” ∗/671 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/672 char DCF Get Status (void )673 {674 return ( cDCF Status ) ;675 }676677678 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/679 /∗ DCF Is Low : ∗/680 /∗ ∗/681 /∗ Aufgabe : ∗/682 /∗ Dieses Unterprogramm g ib t den Inha l t des Flags f u e r d i e Erkennung e i n e s Low−Pegel ∗/683 /∗ ( Flag bDCF Low im Reg i s t e r cDCF Status ) an das au f ru f ende Programm . ∗/684 /∗ ∗/685 /∗ Uebergabeparameter : ∗/

5 DEMONSTRATIONSBEISPIEL 44

686 /∗ ke i n e r ∗/687 /∗ ∗/688 /∗ Rueckgabeparameter : ∗/689 /∗ 1 , wenn e in Low−Pegel des DCF−Telegramms d e t e k t i e r t wurde , ansonst i s t der Rueck− ∗/690 /∗ gabewert 0 ∗/691 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/692 char DCF Is Low (void )693 {694 return (bDCF Low) ;695 }696697698 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/699 /∗ DCF Is High : ∗/700 /∗ ∗/701 /∗ Aufgabe : ∗/702 /∗ Dieses Unterprogramm g ib t den Inha l t des Flags f u e r d i e Erkennung e i n e s High− ∗/703 /∗ Pegel ( Flag bDCF High im Reg i s t e r cDCF Status ) an das au f ru f ende Programm . ∗/704 /∗ ∗/705 /∗ Uebergabeparameter : ∗/706 /∗ ke i n e r ∗/707 /∗ ∗/708 /∗ Rueckgabeparameter : ∗/709 /∗ 1 , wenn e in High−Pegel des DCF−Telegramms d e t e k t i e r t wurde , ansonst i s t der ∗/710 /∗ Rueckgabewert 0 ∗/711 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/712 char DCF Is High (void )713 {714 return (bDCF High) ;715 }716717718 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/719 /∗ DCF Is Bi t f eh l e r : ∗/720 /∗ ∗/721 /∗ Aufgabe : ∗/722 /∗ Dieses Unterprogramm g ib t den Inha l t des Flags f u e r d i e Erkennung e i n e s f a l s chen ∗/723 /∗ Pegel ( Flag bDCF Bitfehler im Reg i s t e r cDCF Status ) an das au f ru f ende Programm . ∗/724 /∗ ∗/725 /∗ Uebergabeparameter : ∗/726 /∗ ke i n e r ∗/727 /∗ ∗/728 /∗ Rueckgabeparameter : ∗/729 /∗ 1 , wenn e in f a l s c h e r Pegel des DCF−Telegramms d e t e k t i e r t wurde , ansonst i s t der ∗/730 /∗ Rueckgabewert 0 ∗/731 /∗ ∗/732 /∗ Anmerkung : ∗/733 /∗ Sobald wieder e in g u e l t i g e r LOw− oder High−Pegel empfangen wurde , wird d i e s e s ∗/734 /∗ Flag wieder zurueckgesetzt , im Gegensatz zu Flag bDCF Fehler , welches e r s t be i ∗/735 /∗ einem Minutenbeginn wieder zu rueckge s e t z t wird ∗/736 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/737 char DCF Is Bi t f eh l e r (void )738 {739 return ( bDCF Bitfehler ) ;740 }741742743 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/744 /∗ DCF Is Fehler : ∗/745 /∗ ∗/746 /∗ Aufgabe : ∗/747 /∗ Dieses Unterprogramm g ib t den Inha l t des Flags f u e r d i e Erkennung e i n e s Feh l e r s ∗/748 /∗ ( Flag bDCF Fehler im Reg i s t e r cDCF Status ) an das au f ru f ende Programm . ∗/749 /∗ ∗/750 /∗ Uebergabeparameter : ∗/751 /∗ ke i n e r ∗/752 /∗ ∗/753 /∗ Rueckgabeparameter : ∗/754 /∗ 1 , wenn e in Fehler waehrend der DCF−Dekodierung a u f t r i t t , und am Beginn der ∗/755 /∗ Dekodierung , so l ange auf den e r s t en Minutenwechsel gewartet wird , ansonst i s t der ∗/756 /∗ Rueckgabewert 0 ∗/

5 DEMONSTRATIONSBEISPIEL 45

757 /∗ ∗/758 /∗ Anmerkung : ∗/759 /∗ Dieses Flag wird e r s t be i einem neuen Minutenbeginn zu rueckge s e t z t . Im Gegensatz ∗/760 /∗ zum Flag bDCF Bitfehler , welches be i jedem guel t igem Low oder High ge l o e s ch t wird . ∗/761 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/762 char DCF Is Fehler (void )763 {764 return ( bDCF Fehler ) ;765 }766767768 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/769 /∗ DCF Is Sync : ∗/770 /∗ ∗/771 /∗ Aufgabe : ∗/772 /∗ Dieses Unterprogramm g ib t den Inha l t des Flags f u e r den Zustand , ob d i e ” inner e ∗/773 /∗ Uhr” mit der DCF−Uhr s yn ch r on i s i e r t i s t , ( Flag bDCF Sync im Reg i s t e r cDCF Status ) ∗/774 /∗ an das au f ru f ende Programm . ∗/775 /∗ ∗/776 /∗ Uebergabeparameter : ∗/777 /∗ ke i n e r ∗/778 /∗ ∗/779 /∗ Rueckgabeparameter : ∗/780 /∗ 1 , wenn d i e ” inner e Uhr” mit der DCF−Uhr s yn c ch r on i s i e r t i s t , ansonst 0 ∗/781 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/782 char DCF Is Sync (void )783 {784 return (bDCF Sync ) ;785 }786787788 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/789 /∗ DCF Get Zusatzinfos : ∗/790 /∗ ∗/791 /∗ Aufgabe : ∗/792 /∗ Dieses Unterprogramm g ib t den Inha l t des Reg i s t e r s cDCF Zusatzinfos an das auf− ∗/793 /∗ rufende Programm . ∗/794 /∗ ∗/795 /∗ Uebergabeparameter : ∗/796 /∗ ke i n e r ∗/797 /∗ ∗/798 /∗ Rueckgabeparameter : ∗/799 /∗ Reg i s t e r mit d iver s en zu s ae t z l i c h en In f o s d i e im DCF−Telegramm entha l ten s ind ∗/800 /∗ ( In f o s ueber Reserveantenne , Zei tumstel lung , Winter− und Sommerzeit , Schal tsekunde ) ∗/801 /∗ ∗/802 /∗ Anmerkung : ∗/803 /∗ Bedeutung der e i n z e l n en Bit s i eh e we i te r oben unter ”Bi t s in den g loba l en ∗/804 /∗ Reg i s te rn ” ∗/805 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/806 char DCF Get Zusatzinfos (void )807 {808 return ( cDCF Zusatzinfos ) ;809 }810811812 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/813 /∗ DCF Is ResAntenne : ∗/814 /∗ ∗/815 /∗ Aufgabe : ∗/816 /∗ Dieses Unterprogramm g ib t den Inha l t des Flags f u e r den Zustand der Reserve− ∗/817 /∗ antenne ( Flag bDCF Rerserveantenne im Reg i s t e r cDCF Zusatzinfos ) an das auf− ∗/818 /∗ rufende Programm . ∗/819 /∗ ∗/820 /∗ Uebergabeparameter : ∗/821 /∗ ke i n e r ∗/822 /∗ ∗/823 /∗ Rueckgabeparameter : ∗/824 /∗ 1 , wenn d i e Reserveantenne (zum Senden des DCF−Telegramms ) akt iv i s t , ansonst i s t ∗/825 /∗ der Rueckgabewert 0 ∗/826 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/827 char DCF Is ResAntenne (void )

5 DEMONSTRATIONSBEISPIEL 46

828 {829 return ( bDCF Rerserveantenne ) ;830 }831832833 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/834 /∗ DCF Is Zei tumstel lung : ∗/835 /∗ ∗/836 /∗ Aufgabe : ∗/837 /∗ Dieses Unterprogramm g ib t den Inha l t des Flags f u e r d i e Ankuendigung der Zeitum− ∗/838 /∗ s t e l l u n g ( Flag bDCF Zeitumstellung im Reg i s t e r cDCF Zusatzinfos ) an das auf− ∗/839 /∗ rufende Programm . ∗/840 /∗ ∗/841 /∗ Uebergabeparameter : ∗/842 /∗ ke i n e r ∗/843 /∗ ∗/844 /∗ Rueckgabeparameter : ∗/845 /∗ 1 , waehrend d i e Ze i tumste l l ung angekuenigt wird (1 Stunde vor der Ze i tumste l l ung ) ∗/846 /∗ ab der Ze i tumste l l ung i s t der Rueckgabewert 0 ∗/847 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/848 char DCF Is Zei tumstel lung (void )849 {850 return ( bDCF Zeitumstellung ) ;851 }852853854 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/855 /∗ DCF Is Sommerzeit : ∗/856 /∗ ∗/857 /∗ Aufgabe : ∗/858 /∗ Dieses Unterprogramm g ib t den Inha l t des Flags f u e r d i e Sommerzeit ( Flag ∗/859 /∗ bDCF Sommerzeit im Reg i s t e r cDCF Zusatzinfos ) an das au f ru f ende Programm . ∗/860 /∗ ∗/861 /∗ Uebergabeparameter : ∗/862 /∗ ke i n e r ∗/863 /∗ ∗/864 /∗ Rueckgabeparameter : ∗/865 /∗ 1 , waehrend der Sommerzeit (0 , waehrend der Winter ze i t ) ∗/866 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/867 char DCF Is Sommerzeit (void )868 {869 return ( bDCF Sommerzeit ) ;870 }871872873 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/874 /∗ DCF Is Winterze i t : ∗/875 /∗ ∗/876 /∗ Aufgabe : ∗/877 /∗ Dieses Unterprogramm g ib t den Inha l t des Flags f u e r d i e Winter ze i t ( Flag ∗/878 /∗ bDCF Winterzeit im Reg i s t e r cDCF Zusatzinfos ) an das au f ru f ende Programm . ∗/879 /∗ ∗/880 /∗ Uebergabeparameter : ∗/881 /∗ ke i n e r ∗/882 /∗ ∗/883 /∗ Rueckgabeparameter : ∗/884 /∗ 1 , waehrend der Winter ze i t (0 , waehrend der Sommerzeit ) ∗/885 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/886 char DCF Is Winterze i t (void )887 {888 return ( bDCF Winterzeit ) ;889 }890891892 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/893 /∗ DCF Is Schaltsekunde : ∗/894 /∗ ∗/895 /∗ Aufgabe : ∗/896 /∗ Dieses Unterprogramm g ib t den Inha l t des Flags f u e r d i e Ankuendigung e i n e r Schal t−∗/897 /∗ sekunde an ( Flag bDCF Schaltsekunde im Reg i s t e r cDCF Zusatzinfos ) an das auf− ∗/898 /∗ rufende Programm . ∗/

5 DEMONSTRATIONSBEISPIEL 47

899 /∗ ∗/900 /∗ Uebergabeparameter : ∗/901 /∗ ke i n e r ∗/902 /∗ ∗/903 /∗ Rueckgabeparameter : ∗/904 /∗ 1 , Ankuendigung e i n e r Schal tsekunde ∗/905 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/906 char DCF Is Schaltsekunde (void )907 {908 return ( bDCF Schaltsekunde ) ;909 }910911912 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/913 /∗ DCF Is Neue Sekunde : ∗/914 /∗ ∗/915 /∗ Aufgabe : ∗/916 /∗ Dieses Unterprogramm g ib t den Inha l t des Flags f u e r d i e Anforderung zur Abarbeit− ∗/917 /∗ ung des Unterpogramms DCF UP Sekunde an das Hauptprogramm an . ∗/918 /∗ ∗/919 /∗ Uebergabeparameter : ∗/920 /∗ ke i n e r ∗/921 /∗ ∗/922 /∗ Rueckgabeparameter : ∗/923 /∗ 1 , wenn das Unterprogramm DCF UP Sekunde abgea rbe i t e t werden muss ∗/924 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/925 char DCF Is Neue Sekunde (void )926 {927 return ( bDCF Neue Sekunde ) ;928 }929930931 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/932 /∗ DCF Is Neue Minute : ∗/933 /∗ ∗/934 /∗ Aufgabe : ∗/935 /∗ Dieses Unterprogramm g ib t den Inha l t des Flags f u e r d i e Anforderung zur Abarbeit− ∗/936 /∗ ung des Unterpogramms DCF UP Minute an das Hauptprogramm an . ∗/937 /∗ ∗/938 /∗ Uebergabeparameter : ∗/939 /∗ ke i n e r ∗/940 /∗ ∗/941 /∗ Rueckgabeparameter : ∗/942 /∗ 1 , wenn das Unterprogramm DCF UP Minute abgea rbe i t e t werden muss ∗/943 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/944 char DCF Is Neue Minute (void )945 {946 return ( bDCF Neue Minute) ;947 }

Datei DCF.H:

1 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/2 /∗ Header f u e r d i e Unterprogramme zur DCF−Dekodierung ∗/3 /∗ ∗/4 /∗ Compiler : mikroC ∗/5 /∗ ∗/6 /∗ Entwickler : Ste f an Buchgeher ∗/7 /∗ Entwicklungsbeginn der Sof tware : 26 . September 2009 ∗/8 /∗ Funkt i ons f aeh i g s e i t : 26 . September 2009 ∗/9 /∗ Letzte Bearbei tung : 23 . Maerz 2010 ∗/

10 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/111213 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Globale Reg i s t e r ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/14 /∗ ke ine g l oba l en Reg i s t e r ∗/151617 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Portbelegung ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/18 #define bDCF Port In PORTA. F4

5 DEMONSTRATIONSBEISPIEL 48

192021 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Konstanten ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/22 /∗ ISR wird a l l e 4 ms aufgeru f en ∗/23 #define KONSTDCFLMIN 2024 #define KONSTDCFLMAX 3025 #define KONSTDCFHMIN 4026 #define KONSTDCFHMAX 602728 #define KONSTDCFNEUEMIN 2502930 /∗ ISR wird a l l e 10 ms aufgeru f en ∗/31 //#de f i n e KONSTDCFLMIN 832 //#de f i n e KONSTDCFLMAX 1233 //#de f i n e KONSTDCFHMIN 1634 //#de f i n e KONSTDCFHMAX 243536 //#de f i n e KONSTDCFNEUEMIN 100373839 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Funktionsprototypen ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/40 void DCF Init (void ) ;41 void DCF Routine (void ) ;42 void DCF UP Sekunde (void ) ;43 void DCF UP Minute (void ) ;44 void DCF Innere Uhr (void ) ;4546 char DCF Get Sekunde (void ) ;47 char DCF Get Minute (void ) ;48 char DCF Get Stunde (void ) ;4950 char DCF Get Tag (void ) ;51 char DCF Get Monat (void ) ;52 char DCF Get Jahr (void ) ;53 char DCF Get Wochentag (void ) ;5455 char DCF Get Status (void ) ;56 char DCF Is Low (void ) ;57 char DCF Is High (void ) ;58 char DCF Is Bi t f eh l e r (void ) ;59 char DCF Is Sync (void ) ;60 char DCF Is Fehler (void ) ;6162 char DCF Get Zusatzinfos (void ) ;63 char DCF Is ResAntenne (void ) ;64 char DCF Is Zei tumstel lung (void ) ;65 char DCF Is Sommerzeit (void ) ;66 char DCF Is Winterze i t (void ) ;67 char DCF Is Schaltsekunde (void ) ;6869 char DCF Is Neue Sekunde (void ) ;70 char DCF Is Neue Minute (void ) ;

5.5 Anmerkungen zur Software

Der Quellcode fur dieses Demonstrationsbeispiel wurde in C mit der freien Demoversiondes mikroC-Compilers erstellt.

Die Software besteht im Wesentlichen aus den folgenden Programmteilen:

• kurzes Hauptprogramm am Ende des Quellcodes von DCF Demo.c, Zeilen 390 bis446.

• kurze Interrupt-Service-Routine (kurz: ISR), in der Datei DCF Demo.c, Zeilen 89 bis107.

5 DEMONSTRATIONSBEISPIEL 49

• 1 Unterprogramm zur Initialisierung des PIC16F874 (Unterprogramm Init in derDatei DCF Demo.c, Zeilen 137 bis 316).

• 1 Unterprogramm zur Anzeige der Uhrzeit und des Datums inklusive des Wochen-tages (Unterprogramm Anzeige Demo in der Datei DCF Demo.c, Zeilen 347 bis 370).

• Die im Abschnitt 4 (ab Seite 6) besprochenen Unterprogramme zur DCF-Dekodierung(in der Datei DCF.C).

Interrupt-Service-Routine (kurz: ISR):Die ISR (in der Datei DCF Demo.c, Zeilen 89 bis 107) wird alle 4ms aufgerufen und besitzthier nur die Aufgabe drei Zeitbasen (4ms, 100ms und eine Sekunde) zu erzeugen, indemsie fur jede der drei Zeiten ein Botschaftsflag fur das Hauptprogramm erzeugt. Das Haupt-programm reagiert auf diese Botschaftsflags, indem es die Unterprogramme DCF Routine

(alle 4ms), DCF Get Status und Anzeige Demo (alle 100 ms, zur Statusanzeige und zurAnzeige der Uhrzeit und des Datums) und DCF Innere Uhr (jede Sekunde) aufruft. Durchdiesen Mechanismus werden diese Unterprogramm zyklisch aufgerufen.Eine Zeitbasis von 4ms ist hier besonders einfach zu erzeugen, da ja die ISR ohnehin schongenau zu diesen Zeitabstanden aufgerufen wird. Es ist also nur notwendig ein Flag zu set-zen. Dieses Flag tragt hier den Namen bFlagZeitbasis4ms und befindet sich im RegistercFlagISRHP. Die Erzeugung fur die 100-ms-Zeitbasis ist dagegen schon etwas

”umfangrei-

cher“. Damit eine Zeit von 100ms entsteht muss die ISR 25-mal aufgerufen werden (25 x4ms = 100ms). Bei jedem ISR-Aufruf muss ein Zahlregister (cZaehlerZeitbasis100ms)um eins vermindert werden. Besitzt es danach den Wert 0, so sind 100ms vergangen. Nunwird das Botschaftsflag bFlagZeitbasis100ms im Register cFlagISRHP gesetzt und dasZahlregister muss mit dem Wert 25 neu geladen werden. Der Wert 25 wird hier durchdie Konstante KONSTZEITBASIS100MS ersetzt. Die Ein-Sekunden-Zeitbasis wird genausowie die 100-ms-Zeitbasis erzeugt. Jedes Mal wenn 100ms vergangen sind wird das Zahl-register cZaehlerZeitbasis1sek um eins vermindert. Besitzt es danach den Wert 0, soist eine Sekunde vergangen. Nun wird das Botschaftsflag bFlagZeitbasis1sek im Re-gister cFlagISRHP gesetzt und das Zahlregister muss mit dem Wert 10 (10 x 100ms =1000ms = 1 Sekunde) neu geladen werden. Der Wert 10 wird hier durch die KonstanteKONSTZEITBASIS1SEK ersetzt.Die Zeit von 4ms ergibt sich, weil als Takt ein 4,096-MHz-Quarz verwendet wird und weilder Vorteiler (VT) im Register OPTION REG mit dem Wert 1:16 geladen wird (Zeile 141im Unterprogramm Init).

ISRAUFRUF [µs] =4 · 256 · V T

fTakt [MHz]=

4 · 256 · 16

4.096= 4000µs = 4ms

Hauptprogramm:Zuerst mussen der Mikrocontroller und die fur die DCF-Dekodierung globalen Registerinitialisiert werden. Diese Aufgaben werden von den Unterprogrammen Init (Zeile 393)und DCF Init (Zeile 396) ausgefuhrt.

Nun befindet sich das Hauptprogramm in einer Endlosschleife. Diese Schleife besitzt dieAufgabe standig die so genannten Botschaftsflags abzufragen. Ist eines dieser Botschafts-

5 DEMONSTRATIONSBEISPIEL 50

flags gesetzt, so muss vom Hauptprogramm eine bestimmte Aufgabe ausgefuhrt werden.Diese Aufgaben sind in Form von Unterprogrammen vorhanden.

Hier die Tatigkeiten in der Endlosschleife, welche durch die Botschaftsflags ausgelostwerden:

• alle 4ms muss das zentrale Unterprogramm zur DCF-Dekodierung (DCF Routine

ausgefuhrt werden, Zeilen 402 bis 409).

• alle 100ms erfolgt die Ausgabe der Statusinformationen fur die DCF-Dekodierungan den Leuchtdioden. Daher mussen die Unterprogramme DCF Is Low, DCF Is High,DCF Is Bitfehler, DCF Is Fehler und DCF Is Sync (Zeilen 414 bis 418) aufgerufenwerden. Ist eine gultige Uhrzeit (inklusive einem gultigen Datum) emfangen worden,dies lasst sich mit dem Unterprogramm DCF Is Sync (Zeile 421) feststellen, so erfolgtalle 100ms auch die Aktualisierung der Uhrzeit und des Datums auf den 7-Segment-Anzeigen durch das Unterprogramm Anzeige Demo (Zeile 423).

• Jede Sekunde muss die parallel zur DCF-Dekodierung laufende Uhr aktualisiertwerden. Dies erfolgt (gemaß Abschnitt 4.1, ab Seite 7) mit dem UnterprogrammDCF Innere Uhr (Zeilen 431 bis 438).

Achtung:Die Botschaftsflags mussen nach der Ausfuhrung der Aufgaben wieder geloschtwerden, da diese Aufgaben sonst ununterbrochen wiederholt werden!

Wichtig:Gemaß dem DCF-Dekodierverfahren (siehe Abschnitt 4.1, ab Seite 7) muss je-de Sekunde das Unterprogramm DCF UP Sekunde aufgerufen werden. Weitersmuss jede Minute das Unterprogramm DCF UP Minute aufgerufen werden. Auchhier bestimmen zwei

”Botschaftsflags“ wann diese beiden Unterprogramme auf-

gerufen werden mussen. Diese Botschaftsflags werden aber im UnterprogrammDCF Routine (in der Datei DCF.C) gesetzt, und konnen daher, wegen der sogenannten Datenkapselung, nicht direkt gelesen werden. Fur das Lesen dieserFlags sind daher wieder eigene Unterprogramme notwendig. Die Unterprogram-me DCF Is Neue Sekunde bzw. DCF Is Neue Minute haben daher die Aufgabe alsRuckgabewert den Wert der Botschaftsflags an das aufrufende Hauptprogrammzu ubergeben. Die Zeilen 440 bis 444 zeigen diesen vielleicht etwas komplizierterscheinenden Sachverhalt.

Unterprogramm Init:Das Unterprogramm Init (Datei: DCF Demo.c, Zeilen 137 bis 316) dient zur Initialisierungdes Mikrocontrollers. Hier werden unter anderem die Ports konfiguriert (Port dient alsEingang oder als Ausgang), der oder die Timer eingestellt usw. Dieses Unterprogrammist vom Controllertyp abhangig und je nach Anwendung mehr oder weniger umfangreich.

5 DEMONSTRATIONSBEISPIEL 51

In diesem Unterprogramm werden auch die globalen Register initialisiert. Hier, bei diesemDemonstrationsbeispiel die Zahlregister fur die 100-ms-Zeitbasis (Zeile 284) und fur die1-Sekunden-Zeitbasis (Zeile 286).

Unterprogramm Anzeige Demo:Das Unterprogramm Anzeige Demo (Datei: DCF Demo.c, Zeilen 347 bis 370) ist das we-sentliche Unterprogramm fur die Ausgabe der Uhrzeit, des Datums und des Wochentages.Dieses Unterprogramm ist eigentlich sehr einfach, so dass hier keine weitere Erklarungnotwendig ist. Wichtig ist nur, dass es vom Hauptprogramm regelmaßig (zyklisch) aufge-rufen 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 Abschnitt4 (ab Seite 6) sehr ausfuhrlich behandelt, so dass sie hier nicht mehr naher erlautert werdenmussen.

Wichtig:In der Datei DCF.H muss der Portpin (bDCF Port In) gemaß der Demonstrati-onsschaltung nach Abbildung 8 (Seite 24) definiert werden. Hier also der PortpinRA4, Zeile 18.

Sonstiges:Am Beginn des Quellcodes (in der Datei DCF Demo.c) befinden sich die folgenden Defini-tionen und Einstellungen:

• Einbinden externer Codeteile (hier die Unterprogramme fur die DCF-Dekodierung,Zeile 15)

• Definition der globalen Register fur die ISR (Zeilen 31 bis 33)

• Definition der globalen Botschaftsflags (Zeilen 38 bis 40)

• Portdefinition (hier fur die Ausgabe der Uhrzeit, des Datums inklusive Wochentagund fur die Statusanzeige, Zeilen 47 bis 59)

• Konstanten fur die Erzeugung der Zeitbasen (Zeilen 64 und 65)

• Die Funktionsprototypen fur die hier verwendeten Unterprogramme (Zeilen 73 und74)

• Ab Zeile 89 beginnt der Quellcode der ausreichend mit Kommentaren versehen ist

Ein kleiner Nachteil beim mikroC-Compiler ist, dass die Konfigurationsbits fur den PIC-Mikrocontroller in der IDE gesetzt werden mussen. Ich personlich wurde diese lieber imQuellcode mit einer geeigneten Anweisung setzen.

LITERATUR 52

Hier sind die notwendigen Einstellungen fur den PIC16F874 fur dieses Demonstrations-beispiel:! CP OFF! DEBUG OFF! WRT ENABLE OFF! CPD OFF! LVP OFF! BODEN OFF! PWRTE ON! WDT OFF! HS OSC

Literatur

[1] wikipedia. Beitrag uber den Zeitsignalsender DCF77. http://de.wikipedia.org/

wiki/DCF77.

[2] mikroElekronika. mikroElektronika - Tools, Compilers, Books, Magazine. http://

www.mikroe.com/, 2009.

[3] Physikalisch-Technische-Bundesanstalt (PTB). Offizielle Homepage des DCF-Sendersauf der PTB-Webseite. http://www.ptb.de/de/org/4/44/442/dcf77_1.htm, Juni 2007.

[4] Conrad Electronic. Aufbau des DCF-77-Signales (Best.-Nr. 19 06 83), 1994.