DCF77 Funkuhr mit dem BASCOM



WARNUNG !

Die hier beschriebene Schaltung ist mit dem 230V-Stromnetz verbunden und bei unsachgemäßer Handhabung lebensgefährlich! Diese Schaltung darf daher nur von Personen aufgebaut und in Betrieb genommen werden, die eine entsprechende Ausbildung haben und genau wissen, was sie tun. 
Für Schäden, gleich welcher Art, die aus der Verwendung dieser Schaltung hervorgehen, übernehme ich keine Haftung!


IMG_0761a
Das DCF77-Signal
Der Langwellensender DCF 77 sendet  Zeitsignale, die von einer Funkuhr entschlüsselt und sekundengenau angezeigt werden können. Solche Funkuhren gibt es, für kleines Geld,  käuflich zu erwerben. Auch herrscht im Internet kein Mangel an Programmieranleitungen solcher Funkuhren für die Atmel AVR's. Sogar eine fertige Library für den BASCOM gibt es. Doch ich wollte es einmal, von ganz unten beginnend, selbst programmieren. So entstand dieses Projekt.

Beginnen wir mit den Grundlagen. Der Sender sendet auf 77,5 kHz Zeitsignale im Sekundentakt.  Der Grundzustand ist ein Signal mit 100%  Sendeleistung. Dieses wird jede Sekunde auf 15% Sendeleistung abgesenkt.  Die Dauer der Absenkung beträgt entweder 100 mS oder 200 mS.  Dabei gilt: 100 mS  entsprechen einer logischen Null und 200 mS entsprechen einer logischen Eins. Innerhalb einer Minute wird so ein komplettes Zeittelegramm übermittelt.  Insgesamt ist die Information 59 Bit lang. In der 59. Sekunde erfolgt keine Absenkung. Dies dient der Synchronisation auf die volle Minute. Die 60. Sekunde enthält immer die logische Null.  Nicht alle so übertragenen Bits werden benötigt, bzw. können genutzt werden. So sind die Bits 1 bis 14 nicht für das Datum und die Uhrzeit relevant. Sie enthalten Wetterinformationen, die verschlüsselt und nicht frei zugänglich sind.  Bit 15 ist ebenfalls nicht wichtig. Es gibt Auskunft über welche Antenne der Sender gerade sendet.  Die Bits 16 bis 18 geben Auskunft ob wir gerade Sommer- oder Winterzeit haben. Mit Bit 19 wird eine Zeitkorrektur um eine Sekunde angekündigt. Bit 20 ist ein Startbit und immer logisch Eins. Ab Bit 21 wird es für unsere Uhr wirklich spannend. Die Bits 21 bis 27 übertragen die Minuten im BCD-Code.  Dabei hat Bit 21 die Wertigkeit 1, Bit 22 die Wertigkeit 2, Bit 23 die Wertigkeit 4, Bit 24 die  Wertigkeit 8,  Bit 25  die Wertigkeit 10.

IMG_0542
Die fertige Funkuhr.
usw. Bit 28 ist ein Prüfbit (Paritätsbit) für die Minuten. Eine logische Null entspricht dabei einer geraden Parität, eine logische Eins einer ungeraden Parität. Die Bits 29 bis 34 übertragen in gleicher Weise die Stunden, Bit 35 ist wieder ein Paritätsbit. Es folgen: Bit 36 bis 41 für den Kalendertag, Bit 42 bis 44 für den Wochentag, Bit 45 bis 49 für den Kalendermonat und Bit 50 bis 57 für das Kalenderjahr. Bit 58 ist wieder ein Paritätsbit. Diesmal jedoch zusammen für die Bits 36 bis 57.
Wer mehr über den Sender DCF 77 und das Zeittelegramm  erfahren möchte, dem empfehle ich folgende Seiten:
Wikipedia
Ein Artikel von Wolfgang Back
Die Seite der PTB


Die Hardware:

110822aa-002-t
zum Vergrößern, den Plan anklicken.
Die Schaltung besteht aus folgenden Funktionsgruppen:
Dem DCF77-Empfänger,
dem Mikrocontroller mit Oszillator,
dem LCD-Display,
und dem Netzteil

Der DCF77-Empfänger:

Als Empfänger kam eine fertige Platine  von Conrad zum Einsatz: C-Control DCF-Empfängerplatine, Best.-Nr.: 641138, 10,21 Euro. Es gibt eine solche Platine z.B. auch von Reichelt: DCF77 Empfängermodul, Artikel-Nr.: DCF77 MODUL, 13,80 Euro. (Beide Preise Stand: 08.2011) Jedoch habe ich mit der Platine von Reichelt keine Erfahrung und kann daher nicht sagen welche besser oder schlechter ist.
Die Platine von Conrad hat vier Anschlüsse, Pin 1 für GND, Pin 2 für eine Versorgungsspannung zwischen +1,2 V bis +15 V. Bei mir kam eine Versorgungsspannung von +5V zum Einsatz. Pin 3 als nichtinvertierter und Pin 4 als invertierter Ausgang. Bei den Ausgängen handelt es sich um Open Kollektor - Ausgänge, die eine maximale Belastung von  1 mA vertragen. Damit errechnen sich die Pullup- Widerstände zu 5V/0,001 A = 5 k Ohm. Ich wählte hier den Normwert von 5,6 k Ohm. Da man mit 1 mA schlecht eine LED betreiben kann (und der Eingang des AVRs zieht ja auch noch ein bisschen),  schaltete ich zwei Gatter des CMOS Bausteins 4069 dahinter. Den Eingang des 4069 legte ich mit 100 KOhm an Masse. Damit liegt auch bei fehlenden Jumpern ein DCF77platine
definierter Nullpegel an dem Eingang des 4069. Durch die zweifache Invertierung liegt das Signal damit wieder nichtinvertiert an. Es geht einmal über einen 1,5 K Ohm Widerstand an eine Low-Current LED, die im Betrieb dann, bei Empfang, im Sekundentakt aufblinkt und des weitern an den Port PD5 des eingesetzten ATMega88.

Der Mikrocontroller mit Oszillator:
Damit sind wir auch schon bei dem Mikrocontroller. Warum ein ATMega88? Weil ich den gerade da hatte! Es geht aber auch ein ATMega8, der immer noch sehr beliebt ist. Die beiden Controller sind pinkompatibel und unterscheiden sich im Wesentlichen in den Adressen verschiedener Register. Ein Unterschied, der bei der Verwendung des BASCOMs egalisiert wird. Da der DCF77 nicht immer zu empfangen ist, muss der Controller über eine zweite Zeitbasis  verfügen. Damit diese hinreichend genau läuft setzte ich einen externen quarzgesteuerten Oszillator ein. Er wird an Pin 9, XTAL1 angeschlossen. Das Eingangssignal vom DCF77 Empfänger kommt, wie schon gesagt,  auf Pin11,  PD5.  Die Anzeige erfolg auf einem LCD-Display, das an die Pins 15 bis 18, entsprechend PB1 bis PB4 und an Pin 23 entsprechend PC0 und Pin 25, entsprechend PC2 angeschlossen ist. Ferner sind, wie üblich, die Stromversorgung mit den entsprechenden Kapazitäten und der Power-On-Reset angeschlossen. Auch ARef habe ich mit 100nF an Masse angebunden, obwohl hier die Analogeingänge nicht genutzt werden.

Das LCD-Display:
Als LCD-Display wählte ich eins mit zwei Zeilen a 16 Zeichen und einem HD44780 kompatiblen Controller. Da die fertige Funkuhr später als Wandschmuck dienen sollte, wählte ich ein Edelteil, positiv-weiß mit Hintergrundbeleuchtung.  Es kann natürlich auch ein Display ohne Hintergrundbeleuchtung gewählt werden, wichtig ist nur, dass es pinkompatibel bleibt, sonst muss das Layout und die Programmierung geändert werden.

Das Netzteil:
Da der Stromverbrauch der konzipierten Schaltung bei etwa 100mA  liegt, kommt ein sinnvoller Batteriebetrieb nicht in Frage. Ein 9V-Block mit 500mAh wäre schon nach 5 Stunden leer und selbst eine Batterie mit 2500 mAh nach etwas mehr als einem Tag erschöpft. Ich entschloss mich daher ein Netzteil einzusetzen. Da die Uhr stationär betrieben wird, ist das auch kein Nachteil. Ein Printtransformator mit 10VA lag noch in der Bastelkiste. Der Trafo ist zwar deutlich überdimensioniert, war aber halt kostenfrei verfügbar. Das gleiche gilt für den eingesetzten Brückengleichrichter B80C1500. Auch hier hätte eine kleinere Ausführung gereicht. Zur Spannungsstabilisierung kommt ein gewöhnlicher 7805 zum Einsatz. Bei den Elkos ist auf eine ausreichende Spannungsfestigkeit zu achten. Mit 35V lag ich auf der sicheren Seite.
Wer sich mit den Sicherheitsregeln für das Arbeiten mit dem 230V Netz nicht so gut auskennt, dem empfehle ich stattdessen die Verwendung eines fertigen Steckernetzteils. Z.B. Steckernetzteil 5V/DC/1200mA, C- Best.-Nr.: 512683. In dem Platinenlayout spart man damit sowohl den Printtrafo als auch die folgende Gleichrichtung und Spannungsstabilisierung ein. Das Platinenlayout ist dann natürlich entsprechend zu ändern.
110824aa-006-t
zum Vergrößern, den Plan anklicken.
Das Platinenlayout:
Der Hardwareaufbau erfolgte auf  einer Lötstreifenrasterplatine im Europa-
kartenformat 160 x 100 mm. Der nebenstehende Plan zeigt das Layout. Dabei sind die Leiterbahnen rot, Drahtbrücken und Verbindungen auf der Bestückungsseite grün dargestellt.
Einige Komponenten wurden übereinander angeordnet. So die DCF77 Empfängerplatine über den Pull-up Widerständen und das LCD-Display über dem Mikrocontroller und dem  Quarzoszillator.  Dabei klebte ich zur Isolation einen Streifen Papier zwischen die Komponenten. Weil der Controller mit IC- Fassung zu hoch stände, wurde er direkt eingelötet. Die Ansteuerung des LCD- Displays wählte ich so, dass eine direkte Verbindung der Datenleitungen, ohne Drahtbrücken, zu dem Mikrokontroller bestand. Um das LCD-Display entnehmbar zu machen verwendete ich eine Steckverbindung zwischen LCD-
Display und Hauptplatine. Dabei ordnete ich auf der Platine eine Steckerleiste und auf dem LCD-Display eine Buchsenleiste an. Der Printtransformator wurde mit der 230V Seite auf der Innenseite der Platine angeordnet, so dass die Netzspannung möglichst weit von den Rändern entfernt ist. Um die beiden 230V führenden Leiterbahnen wurden im Abstand von zwei Lochrasterpunkten die Leiterbahnen entfernt. Die 230V führenden Leiterbahnen wurden großzügig mit gewebeverstärktem Isolierband abgeklebt. Weiterhin kam unter die Platine eine weitere Lochrasterplatine (diesmal ohne Kupfer), um einen weitgehenden Berührungsschutz zu gewährleisten.  
Neben dem Printtransformator ordnete ich eine Zugentlastung für die 230V Zuleitung an. Der Printtrafo wurde sekundärseitig mit 500mA abgesichert.
Stückliste
Anz.
Bezeichnung
Symb.
C - Best.-Nr.
1 Lötstreifenrasterplatine 160 * 100 mm - 529506
1 Lochrasterplatine 160 * 100 mm - 528455 
4 Zylinderkofschraube M3x10, mit je 2 Unterlegscheiben und 2 Muttern
- -
1 LCD-Display 2 Zeilen, a 16 Zeichen U2 181664
1 C-Control DCF-Empfängerplatine U1 641138
1 Mikrocontroller AVM ATMega88 oder ATMega8 IC2 -
1 Quarzoszillator 8 MHz IC1 158119 
1 CMOS - IC 4069 IC4 172952
1 IC-Fassunung 14pol. - 189618
1 Trimpotentiometer 10 kOhm, liegend P1 422444
1 Mini Impulstaster T602 S1 700460
1 Brückengleichrichter B80C1500 Br1 501441
1 Spannungskonstanthalter 7805 IC3 179205 
1 Printtransformator 10 VA , 2 x  9 Volt Tr1 710554
1 Netzkabel schwarz, 2 x 0,75 - 611984
1 Zugentlastung - 531375
1 Zylinderkopfschraube M3 x 16, mit Unterlegscheibe und Mutter -
-
1 low Current LED, rot D1 146005
1 Elektrolytkondensator 2200 uF, 35V C1 472557 
4 Kondensator, 100 nF C2,C3,C5,C6 453358
1 Elektrolytkondensator 220 uF, 35V C4 472522 
1 Kondensator, 47 nF C7 453080 
2 Kohleschichtwiderstand, 1/4 W, 5,6 kOhm R1,R2 403342
1 Kohleschichtwiderstand, 1/4 W, 100 kOhm R3 403290
2 Kohleschichtwiderstand, 1/4 W, 1,5 kOhm R4,R6
403270
1 Kohleschichtwiderstand, 1/4 W, 10 kOhm R5 403377
1 Stiftleiste RM 2,54, 36 pol. - 741119 
1 Buchsenleiste RM 2,54, 36 pol. -
741120
1 Feinsicherung 0,5A F1 533467
1 Sicherungshalter 5x20 - 533866


Die Software:
Das Programm ist, wie schon gesagt, für den BASCOM geschrieben. Da es über 4 KByte groß ist, kann es leider nicht mit der kostenfreien Demoversion des BASCOM kompiliert werden. Dazu wird die Vollversion benötigt.
Die eigentliche Uhr wird von dem Timer1 des Mikrocontrollers betrieben. Er ist so konfiguriert, dass er jede Sekunde einen Interrupt auslöst, der in der Interruptroutine "Sekundentakt:" abgearbeitet wird.  Das DFC77 Signal stellt diese Quarzuhr. So läuft die Uhr auch bei zeitweise schlechtem Empfang weiter. Die Genauigkeit der reinen Quarzuhr ist eigentlich bescheiden.  Bei meinem Exemplar geht sie alle dreieinhalb Stunden eine Sekunde vor. In dieser Zeit kann sie sich aber immer wieder mit dem DFC77- Signal synchronisieren.

Das Programm besteht aus folgenden Routinen:
Hauptprogramm
Init:
Stellen:
Synchro:
HoleBit:
PTest:
Form:
Sekundentakt:
Kurzzeit:

Kurzzeit:
Neben dem Timer1 verwende ich noch den 8-Bit Timer0. Er wird zur
 source
zur Gesamtansicht, das Bild anklicken.
Messung der Signallängen verwendet. Da die Signale entweder 100 mS oder 200 mS lang sind, ist der Timer0 so konfiguriert, dass  er jede Hundertstelsekunde einen Interrupt auslöst. Dieser Interrupt wird von der Interruptroutine "Kurzzeit:" bedient. Hier wird die Variable "Zaehler" hochgezählt und der Timer0 mit dem Wert von "Preload0" neu gesetzt. Der Wert von "Zaehler" dient dem Vergleich der verstrichenen Signalzeit in Hundertstelsekunden.
An dieser Stelle einmal eine Anmerkung, die dem Verständnis der weiteren Erläuterungen dient. Ich nutze von der DCF77 Empfangsplatine das invertierte Signal. D. h. eine Absenkung des Sendesignals entspricht einem aktiven Signal und steht an dem Port des ATMegas als eine log. Eins an.

Sekundentakt:
Wird, wie schon gesagt, durch einen Interrupt von Timer1, jede Sekunde aufgerufen.  Der Timer1 wird hier durch den  Wert von "Preload1" neu gesetzt.  Ferner wird die Variable "Sekunden" hochgezählt. Hat diese einen höheren Wert als 59 wird sie auf Null gesetzt und die Variable "Minuten" um eins hochgezählt. Ist diese größer als 59 wird sie auf Null gesetzt und die Variable "Stunden" um eins erhöht. Analog verfahre ich mit den Variablen "Tag", "Monat" und "Jahr".  Diese Variablen kommen auch auf dem LCD-Display mittelbar zur Anzeige. Zur richtigen Formatierung wird das Unterprogramm "Form:" aufgerufen. Dies gibt die formatierten Werte in der Variablen "H" zurückt, die dann an der jeweiligen Position im LCD-Display angezeigt werden.  Eine Ausnahme bildet der Wochentag. Seine Darstellungsform ist in dem Stringfeld  "Wota( )" gespeichert. Dabei ist das erste Element der Montag  (Mo) und das siebte Element der Sonntag (So). Die Variable "Wtag" steht für die Wochentage  1 bis 7.

Form:
Sowohl die Zeit als auch das Datum haben in der Darstellung auf dem Display ein ähnliches Format. So wird die Zeit als hh:mm:ss und das Datum als tt.mm.jj dargestellt. Deshalb wird an das Unterprogramm "Form:" immer die Variablen "A" für Stunde, "B" für Minute und "C" für  die Sekunde bei der Zeitdarstellung und "A" für den Kalendertag, "B" für den Kalendermonat und "C" für das Kalenderjahr übergeben. Die Übergabevariable "Sep" legt fest ob der Separator für die Zeit,  also ":" oder für das Datum "." gemeint ist. Die Stringvariable "H" übergibt, wie schon gesagt, die fertig formatierte Anzeige.

Das  Hauptprogramm
ist schnell besprochen. Es ruft zunächst eine Initialisierungsroutine "Init:" auf und läuft dann in einer Endlosschleife, die immer wieder das Unterprogramm  "Stellen:" aufruft, das wie der Name vermuten lässt, die Quarzuhr mit der Zeit der Funkuhr synchronisiert.


Init:
ist eine Initialisierungsroutine. Sie legt die Werte für das Stringfeld "Wota( )" fest, setzt den Wochentag zunächst willkürlich auf 1 (Montag) und legt die Preloadwerte für den Timer0 und den Timer1 fest. Weiterhin  ermittelt sie den Wert für die Variable "V". "V" ist ein Vergleichswert zur Bestimmung der Signalzeiten. Eigentlich könnte man ihn konstant auf 11 setzen (> 100mS = 11 "Zaehler"- Einheiten). Jedoch laufen die Mikrocontroller nicht alle gleich schnell. Es gibt da von Baustein zu Baustein fertigungsbedingt Unterschiede. Außerdem geht es, unter BASIC,  mit dem Messen von Hundertstelsekunden schon nahe an die Grenze des Machbaren. Es kann gut sein, dass da schon mal eine Hundertstelsekunde verschluckt wird. Um solchen Schwierigkeiten aus dem Weg zu gehen testet "Init:" wie viele "Zaehler" - Werte für ein 100 mS Signal gebraucht werden und verwendet den so ermittelten Wert der Variablen "V" später für die Erkennung der Null- und Einszustände des Zeittelegramms. "V"  ist immer 1,5-mal so lang wie das kürzeste Signal.

Synchro:
Diese Routine dient dem Erkennen der 59. Sekunde, sprich des folgenden Minutenwechsels.  Das Programm startet zwei ineinander geschachtelte Schleifen. Die äußere Schleife  setzt die Variable "Zaehler" auf Null und startet den Timer0. Das Programm durchläuft die äußere Schleife solange, bis die Variable "Zaehler" einen größeren Wert als 130 hat. Mit anderen Worten: bis eine längere Zeit als 1,3 Sekunden verstrichen ist. Da in der 0. bis  58. Sekunde immer ein Signal kommt, nur in der 59. Sekunde nicht, ist damit die 59. Sekunde eindeutig ermittelt.
Die innere Schleife läuft solange, wie das Signal auf Null liegt. Sobald das Signal auf Eins wechselt wird die innere Schleife nicht mehr durchlaufen. Das Programm verlässt die innere Schleife ebenfalls, wenn die Variable "Zaehler" einen größeren Stand als 1000 erreicht hat. Dann sind Zehn Sekunden verstrichen ohne dass ein Signalwechsel eintrat. Ein Zeichen dafür, dass der Sender z. Zt. nicht empfangen werden kann. In diesem Fall wird das Fehlerflag "Fehler" gesetzt.
Dadurch erreichen wir, dass das Programm solange in diesen beiden Schleifen bleibt, bis entweder das Synchronsignal empfangen wurde oder ein Timeout stattfindet. Erst danach wird "Synchro:" wieder verlassen.

Stellen:
Stellen koordiniert die kompletten Einzelschritte die zum Stellen der Quarzuhr erforderlich sind. Zunächst wird  der Minutenanfang (mit "Synchro:") abgewartet, dann mit "Holebit:" ein komplettes Zeittelegramm eingelesen, entschlüsselt und auf Fehler geprüft und letztendlich, sekundengenau mit dem Minutenwechsel (wieder mit "Synchro:" ermittelt) die Uhr gestellt.

Holebit:
ist das Herzstück des Programms. Hier wird ein komplettes Zeittelegramm erfasst und entschlüsselt. Das Programm wartet zunächst bis das Signal log. Eins wird, setzt dann die Variable "Zaehler" auf  Null und startet den Timer0. Dann wartet das Programm bis das Signal wieder Null ist und speichert anschließend den Wert von "Zaehler" in die Variable "AZaehler" zwischen (denn "Zaehler" läuft ja interruptgesteuert weiter). Wir haben damit die Dauer des Eins- Signals. Diese wird nun, mit Hilfe der Variablen "V",  ausgewertet. (Wir erinnern uns, "V" stellt die 1,5-fache Zeitdauer der kürzesten Signalzeit dar.)  Ist "Azaehler" kürzer als "V", so haben wir eine log. Null entschlüsselt, ist "AZaehler" größer oder gleich "V" so haben wir eine log. Eins entschlüsselt.  Das Ergebnis dieser Entschlüsselung speichern wir in der Variablen "Einbit". Der Vorgang wird mit Hilfe einer FOR/NEXT- Schleife  59-mal wiederholt und mit der Laufvariablen "Bitnummer" gezählt. "Bitnummer" gibt uns also die Stelle in dem Zeittelegramm an. Weiterhin legen wir mit "Bitnummer" innerhalb der FOR/NEXT- Schleife fest, was nun mit "Einbit" passiert. Dies geschieht mit einer SELECT CASE - Anweisung.  Betrachten wir einmal beispielhaft die Bits 21 bis 27. Zunächst wird der Wert von "Einbit" in der Variablen "Paritaet" aufaddiert. Bei Bit 21 mit einer Zuweisung, ab Bit 22 durch Addition. Weiterhin wird mit Hilfe von "Einbit" der Wert für die Minuten  mit der Variablen "PMinuten" gebildet. Dies geschieht durch beaufschlagen von "Einbit" mit einer Wertigkeit. Bei Bit 21 ist diese 1, bei Bit 22 ist sie 2, bei Bit 23 4, usw. Mit dieser Wertigkeit multiplizieren wir den Wert von "Einbit". Da "Einbit" nur Null oder Eins sein kann, ist das Ergebnis der Multiplikation Null oder eben die Wertigkeit. Jeweils wird das Ergebnis der Multiplikation mit dem Ergebnis des vorherigen Bits hinzu addiert. (Außer bei Bit 21 .)  Damit haben wir dann mit Bit 27 den kompletten Wert für die Minute.  Weiterhin haben wir in der Variablen "Paritaet" die Summe der Werte aller Bits von Bit 21 bis einschließlich Bit 27. Dieser Wert kann nun geradzahlig (z.B. 4) oder Ungeradzahlig (z.B. 7) sein. Bit 28 gibt nun Auskunft darüber, wie das Ergebnis sein SOLLTE; nämlich geradzahlig, dann ist Bit 28 Null oder ungeradzahlig, dann ist Bit 28 Eins. Dies prüfen wir mit dem Unterprogramm "Ptest:". Stimmt die errechnete Parität in der Variablen "Paritaet" mit der erwarteten Parität aus Bit 28 überein, ist alles in Ordnung, wenn nicht, dann war die Übertragung fehlerhaft.
Analog verfahren wir mit den anderen Inhalten des Zeittelegramms. Zu Bemerken ist noch, dass "Minuten" hier "PMinuten",  "Stunden" hier "PStunden" usw. heißen. Diese Doppelung von Variablen ist notwendig, da zu diesem Zeitpunkt noch gar nicht feststeht, ob diese Werte auch gültig und nicht eventuell durch Übertragungsfehler verfälscht sind. Da "Minuten", "Stunden", usw. ja interruptgesteuert, und damit unabhängig von dem Stand der Entschlüsselung des Zeittelegramms und der folgenden Kausalitätskontrolle,  jede Sekunde neu angezeigt werden, ist damit sichergestellt, dass trotzdem keine falschen oder 'halbfertige' Werte zur Anzeige kommen.

Ptest:
Wie testet man ob eine Zahl gerade oder ungerade ist? Nun, wenn man diese Zahl durch Zwei teilt und das Ergebnis keine Nachkommastellen hat, dann ist diese Zahl gerade. Eine ungerade  Zahl hat, teilt man sie durch Zwei, immer Nachkommastellen. Genauso verfahren wir mit der Eingangsvariablen "Paritaet".  Die Funktion Frac() unter BASCOM gibt die Nachkommastellen einer Zahl zurück. Hat die Zahl keine Nachkommastellen gibt Frac() den Wert Null zurück. Wir weisen der Singlevariablen "Paritaet" das Ergebnis  von Frac() zu und prüfen anschließend ob "Paritaet" gleich Null ist. Ist "Paritaet" gleich Null so wird der Variablen "Pbit" der Wert Null zugewiesen, andernfalls weisen wir "Pbit" eine Eins zu. Damit enthält jetzt "Pbit" die Aussage, ob "Paritaet" eine gerade oder ungerade Zahl enthielt. Und zwar in der gleichen Form die auch der Paritätssollwert "Einbit" enthält. Ergibt ein Vergleich der beiden, dass sie identisch sind, so bedeutet das: die Parität ist ok. Falls nicht, ist etwas mit der Übertragung schief gegangen und wir setzen das Fehlerflag "Fehler" gleich Eins.


Das Programm steht hier zum Download bereit



zurueck