Pfad: Home => AVR-DE => Anwendungen => DCF77_tn24_v3
DCF77 TN24 Logo AVR-Anwendungen

DCF77-Uhr mit ATtiny24
Hardware, Aufbau, Anwendung und Software für die DCF77-Uhr
Logo

DCF77-Uhr mit ATtiny24, Version 3

Diese Seiten als PDF (32 Seiten, 649 KB).

DCF77-Uhr mit tn24
Die DCF77-Uhr mit dem ATtiny24 in der ersten Version hier erfreut sich seit Jahren großer Beliebtheit. Bislang (April 2019) habe ich insgesamt über 2.500 Zugriffe auf die Projektwebseite registriert, 48% davon haben den Quellcode von der Seite abgerufen.

Trotz der Popularität weist die Version aber einige Nachteile auf:
  1. Sie ist auf das LCD-Format 2*24 ausgelegt. 24-spaltige LCDs gibt es aber heute gar nicht mehr zu kaufen, nur noch einige antike Exemplare sind im Ramschhandel zu finden. Ein Umbau hätte erhebliche Änderungen im Programm erforderlich gemacht, so dass eine völlig neue Konstruktion von Hard- und Software weniger aufwändig war.
  2. Die Auswertung der DCF77-Signale erfolgte nicht sehr ausgefeilt. Das geht besser. Auch das ein Grund, das Programm vollständig neu zu schreiben.
  3. Die Uhr hatte keinen Quarztakt, so dass sie bei längerem Betrieb ohne DCF77-Signal um 10% verkehrt ging. Das ist für eine Uhr nicht akzeptabel.
  4. Die Ansteuerung der LCD war im "quick-and-dirty-Modus" erstellt und nicht mit standardisierten Methoden realisiert. Auch das geht mittlerweile besser, mit der Software hier.
Dieses Projekt hier hat diese Nachteile nicht mehr. Allerdings hat es ein paar interessante Besonderheiten:
  1. Der Prozessortakt kommt aus einem 32,768 kHz-Uhrenquarz. Das kommt daher, weil der ATtiny24 NUR mit Niedrigfrequenzquarzen betrieben werden kann. Bei höheren Frequenzen muss zwingend ein externer Quarzoszillator angeschlossen werden. Und das finde ich sowas von überkandidelt, dass ich die 32 kHz Takt ausprobieren wollte (und: ja, es geht auch noch mit so niedrigem Takt eine Uhr mit DCF77-Erkennung und LCD-Ansteuerung zu betreiben).
  2. Bedingt durch die niedrige Taktfrequenz gibt es zwei weitere Besonderheiten zu beachten:
  3. Da mit diesem Takt der gesamte Ablauf sehr langsam wird, war sicherzustellen, dass die gesamte Taktauswertung des DCF77-Signals, einschließlich aller Fehlerprüfungen (22 Arten von Fehlern können auftreten) und der Umwandlung der DCF77-Daten in binäre Datums- und Zeit-Formate nicht länger dauert als der kürzeste Takt von DCF77 (100 ms minus Toleranz = 80 ms). Daher waren alle Routinen zu simulieren und ihre Ausführungszeiten zu messen. Die Zeiten liegen allesamt unter 30 ms und halten daher die Anforderungen ein.
  4. Mit einem Jumper lässt sich die Uhrzeit von MEZ/MESZ, wie sie DCF77 liefert, auf die Angabe der UTC-Zeit umrechnen. Dabei wird nicht einfach eine (MEZ) oder zwei (MESZ) Stunden abgezogen, da dies kurz nach Mitternacht ein falsches Datum ergäbe. Die Umrechnung von MEZ/MESZ auf UTC erfolgt bei diesem Projekt absolut korrekt, da auch das Datum und der Wochentag korrekt umgerechnet wird.
  5. Ein weiteres besonderes Feature ist, dass die DCF77-Signalerkennung sowohl bei Aktiv-High- als auch bei Aktiv-Low-Signalen korrekt erfolgt, ohne das Programm umstellen zu müssen.
  6. Die Verfolgung des DCF77-Erkennungsprozesses kann mit folgenden Mitteln erfolgen:
    1. Fehlercodes von E0 bis E9 sowie von EA bis EM erscheinen jeweils auf dem Display. E0 bis E5 betreffen Fehler, die bei der Signalauswertung erkannt wurden, E6 gibt an, dass in einer Minute nicht exakt 59 Bits empfangen wurden. Die anderen Fehler betreffen Probleme bei der Umwandlung der DCF77-Bits in das Binärformat (Paritätsfehler, Einer-Ziffern größer als Neun, Zahlen größer als im zulässigen Bereich) sowie Formatfehler (Nullbit zu Beginn oder Einsbit am Datum-Zeit-Beginn falsch). Die erscheinenden Fehlercodes werden nach einer Sekunde wieder ausgeblendet.
    2. Sind alle Fehlerprüfungen korrekt absolviert und wurden Datum und Uhrzeit mit DCF77 erfolgreich synchronisiert, erscheint DCF im Display. Nachfolgende Fehler überschreiben dies wieder.
    3. Falls gewünscht, können die erkannten letzten drei Bits des Datenstroms auf der Anzeige ausgegeben werden (vor dem Assemblieren cDcfMoniBits im Abschnitt Adjustable constants auf 1 setzen). Fehlermeldungen sind dabei ausgeschaltet und erscheinen nicht.
    4. Die Anzahl empfangener Bits kann durch Setzen der Konstante cDcfMoniBitCount im Abschnitt Adjustable constants auf Eins jeweils dargestellt werden. Fehlermeldungen erscheinen nicht.

1 Hardware

1.1 Prozessor und LCD

Schaltbild DCF77 ATtiny24 V3 Das ist das Schaltbild der Uhr mit der angeschlossenen LCD. Die LCD arbeitet im 4-Bit-Modus, die Anschlüsse D0 bis D3 bleiben daher offen. Der Datenbus ist an das obere Nibble des Port A des ATtiny24 angeschlossen. Die drei Steuerungsanschlüsse RS, R/W und E der LCD liegen an den Portanschlüssen PA1 bis PA3. An PA0 liegt der Jumper, der die Zeit- und Datumsausgabe von MEZ/MESZ auf UTC umstellt, wenn er geschlossen wird. Das kann jederzeit und im laufenden Betrieb der Uhr erfolgen, da Pegelwechsel laufend erkannt werden. Man kann daher statt des Jumpers auch einen Schalter verwenden.

An der LCD ist am VO-Eingang noch ein 10k-Trimmer zur Kontrasteinstellung angeschlossen. Die Intensität der Hintergrundbeleuchtung kann mit einem Trimmer von 200 Ω zwischen ca. 7 und 25 mA verstellt werden, die Helligkeitsunterschiede sind nur im Dunkeln wahrnehmbar.

An den beiden XTAL-Anschlüssen des ATtiny24 ist der Uhrenquarz mit zwei Kondensatoren von 18 pF angeschlossen. Der Reset-Eingang liegt mit 10 kΩ an Plus und ist mit dem ISP6-Anschluss verbunden, über den der Prozessor mittels USCK, MISO und MOSI in der Schaltung programmiert werden kann.

Da die verwendete LCD nur mit 4,5 bis 5,5 V betrieben werden kann, das verwendete DCF77-Modul aber nur 3,3 V verträgt, wird die Betriebsspannung des DCF77-Moduls mit einem Widerstand und einer Zenerdiode erzeugt und mit einem Elko vom Zener-Rauschen befreit. Der Signalausgang wird mit einem Widerstand von 330 kΩ auf Plus 3,3 V gezogen, damit auch Open-Collector-Module funktionieren. Das Signal wird am INT0-Eingang des ATtiny24 (PB2) eingespeist, dessen Pull-Up nicht eingeschaltet wird.

In der Stromzufuhrleitung liegt noch eine kräftige 5,6V-Zenerdiode, damit auch beim Dauerladen des Akkus mit niedrigen Strömen keine Überspannung auftreten kann und um die Schaltung vor Verpolung der Stromzufuhr zu schützen.

Die Ausgabe von Uhrzeit und Datum ist von der Einstellung der Konstanten cDateFormat in der Sektion Adjustable Constants der Software abhängig und kann deutsches (0) und englisches (1) Datumsformat. Natürlich betrifft das dann auch die Abkürzungen der Wochentage.

1.2 Netzteil und Akkuversorgung

Netzteil- und Akkuschaltung Die Versorgung mit Strom erfolgt wahlweise aus einem trafobestückten Netzteil mit einem 6V/0,33VA-Trafo und geregelt mit einem 78L05, oder einem Viererpack Akkus. Alle Sorten von Akkus mit einer Nennspannung von 1,2 V können verwendet werden.

Die Akkus können bei Netzbetrieb mit einem kleinen Strom von 2,5 mA bei Laune gehalten werden. Durch Umlegen des Jumpers erfolgt die Ladung etwas schneller (bei einer Nennkapazität der Akkus von 2000 mAh in knapp drei Tagen). Es wird nicht empfohlen, beim schnelleren Laden auch die Uhr anzuschließen. Schaden tut es nicht, dafür sorgt die Zenerdiode am Spannungseingang der Uhr, die alles über 5,6 V auffrisst.

Die Umschaltung von Netz- auf Akkubetrieb und zurück erfolgt unterbrechungsfrei.

Netzteil unter Last Dies hier zeigt das Netzteil unter Volllast. Die Eingangsspannung für den 78L05 reicht vollkommen aus.


Seitenanfang Hardware Aufbau Software

2 Aufbau

2.1 Prozessor und LCD

Aufbau der Prozessorplatine Der Aufbau der Prozessorplatine erfolgt auf einer doppelseitig kaschierten Lochrasterplatine mit 30x50 mm Größe. Die Verwendung des 10-Gang-Trimmers für die Hintergrundbeleuchtungsstärke ist etwas überkandidelt, es war aber sonst kein einfacherer 200Ω-Trimmer zu kriegen. Trimmer und Widerstand kann man auch durch einen Festwiderstand zwischen 68 und 270Ω ersetzen, der Helligkeitsunterschied ist sowieso nur akademisch und nachts.

Da die Platine huckepack auf der LCD sitzt (Rücken an Rücken) wird die LCD mit einer 16-poligen Stiftleiste nach unten bestückt. Das Gegenstück dazu sitzt auf der Lötseite der Prozessorplatine und wird von der Oberseite her eingelötet.

Bestückte Prozessorplatine Wer ein anderes als das hier verwendete DCF77-Modul verwenden will, braucht vielleicht eine vierpolige Buchse dafür.

2.2 Netzteil und Akkuversorgung

Bestücktes Netzteil Das Netzteil und die Akkuversorgung werden ebenfalls auf einer kleinen Lochrasterplatine aufgebaut.


Seitenanfang Hardware Aufbau Software

3 Software

3.1 Downloads

Den Assembler-Quellcode gibt es in englisch hier zum Download und hier zur Ansicht im Browser. Zum Assemblieren ist noch die Include-Routine hier notwendig.

Alle nötigen Berechnungen zu diesem Projekt finden sich in den Rechenblättern im OpenOffice-Dokument hier.

3.2 Fuses

Fuses des ATtiny24 So werden die Fuses des ATtiny24 gesetzt. Bitte unbedingt die Warnungen zu Beginn dieser Seite beachten und die CLKDIV8-Fuse zuallererst löschen. Ich übernehme jedenfalls keinerlei Garantie dafür, dass der Rückweg zum internen RC-Oszillator danach auch noch funktioniert.

3.3 Einstellungen von Eigenschaften

In der Sektion Adjustable constants im Quellcode lassen sich folgende Eigenschaften der Software verstellen: Änderungen werden erst wirksam, wenn der Quellcode assembliert und in das Flash übertragen ist.

3.4 Verfügbare Fehlerdiagnosen

Im Kopf des Quellcodes lassen sich folgende Debug-Optionen einschalten: Bei den beiden Fehlerdiagnosen DebugDcfPulse und DebugDcfCode können übrigens beliebige Testtabellen im Rechenblatt DCF77_pattern des OpenOffice-Dokuments hier aus Zeit- und Datumseinstellungen erzeugt und in den Quellcode kopiert werden, deren Dekodierung in der nachfolgenden Simulation dann erfolgen soll.

3.5 Erweiterungen des Programms

Falls Du vorhast, über geänderte Einstellungen hinaus das Programm zu ändern, bitte Folgendes beachten:
  1. Das Programm belegt in seiner derzeitigen Version einen sehr großen Teil des verfügbaren Flashspeichers im ATtiny24. Für längere Einfügungen ist daher kaum noch Platz. Es muss dann auf den ATtiny44 oder ATtiny84 umgestiegen werden. Bitte beachten, dass beim ATtiny84 zusätzlich das High-Byte des Stackpointers gesetzt wird (erfolgt automatisch wenn der Port SPH vorhanden ist).
  2. Bei allen Erweiterungen ist sicherzustellen, dass diese die 80/100-ms-Ausführungsgrenze einhalten. Bei länger andauernden Behinderungen von Interrupt-Flaggenbehandlungen kann es zu unerwarteten Nebeneffekten kommen.

3.6 Ablaufsteuerung

Nachfolgend werden einige Details zur Ablaufsteuerung des Programmes beschrieben, die bei Änderungen zu beachten sind.

3.6.1 Sekundenimpulse

Die Sekundenimpulse, die die Uhrzeit und ggfs. das Datum um eine Sekunde erhöhen, werden mittels des Timers TC0 erzeugt. Er arbeitet mit einem Vorteiler von 64 und wird daher aus der Taktfrequenz von 32,768 kHz mit 512 Hz getaktet. Der 8-Bit-Timer läuft bei 256 alle 0,5 Sekunden über und erzeugt einen Overflow-Interrupt. In der Interrupt-Service-Routine wird ein Zählregister abwärts gezählt. Beim Erreichen von Null wird die Flagge bSec gesetzt und der Zähler mit Zwei neu gestartet.

Außerhalb der Interrupt-Service-Routine werden die Sekunden (im SRAM unter Adresse 0x0060) um Eins erhöht und auf der LCD in Zeile 1 in den Spalten 7 und 8 mit führenden Nullen ausgegeben. Erreicht der Sekundenzähler 60, beginnt es wieder bei Null und die Minuten werden erhöht. Nun werden sowohl die Minuten (Zeile 1, Spalten 4 und 5) als auch die Sekunden auf die LCD geschrieben.

Analog dazu Es werden immer nur diejenigen Stellen der Uhr aktualisiert, deren Aktualisierung angezeigt war.

Die Uhr läuft daher quarzgenau vollkommen eigenständig, also auch ohne DCF77-Synchronisation, und muss nur beim ersten Programmieren auf die korrekte Uhrzeit und das korrekte Datum eingestellt werden (Tabelle InitDTTable: im Quellcode). Bei jedem Reset (z. B. beim Unterbrechen der Stromversorgung) stellt sich die Uhr wieder auf diese Voreinstellung zurück, so dass dies nur dann Sinn macht, wenn eine Batterie oder ein Akku unterbrechungsfrei angeschlossen ist. Beim Einstellen der Sekunden ist zu beachten, dass die Flashprogrammierung bei ca. 6,5 kHz ISP-Frequenz etwa 39 Sekunden dauert, und es bei eingeschaltetem Verifizieren doppelt so lange dauert. Hinzu zu addieren ist diejenige Verzögerungszeit, die zwischen der Eröffnung und dem Loslaufen der Uhr eingestellt ist (default: 5 Sekunden), so dass es bis zu 83 Sekunden dauert, bis die Uhr nach dem Start des Flash-Schreibens dann effektiv losläuft.

3.6.2 DCF77-Signalauswertung

Fliessschema DCF77-Signalauswertung Die DCF77-Signalauswertung erfolgt folgendermaßen:
  1. Das DCF77-Empfangsmodul ist an den Eingang INT0 (PB2) angeschlossen. Bei jeder Flanke an diesem Eingang erfolgt ein INT0-Interrupt.
  2. In der Interrupt-Service-Routine wird der Zählerstand von TC1 ausgelesen, die Flagge bDcf gesetzt, der Zähler mit Null neu gestartet und der abgelesene Zählerstand in das Registerpaar rDcfH:rDcfL kopiert. War der Zählerstand allerdings kleiner als die Konstante cSpur (im Quellcode auf 5 ms eingestellt), dann unterbleibt dies und INT0 wartet auf die nächste eintreffende Flanke.
  3. Der Zähler TC1 arbeitet mit einem Vorteiler von 64, so dass er alle 64/32.768 = 1,95 ms um Eins erhöht wird. Eine von DCF77 gesendete Null (100 ms) entspricht dabei einem Zählerstand von etwa 51, eine Eins ca. 102 und ein Minutenwechsel 923 oder 974, je nachdem ob das letzte gesendete Zeichen eine Null oder eine Eins war.
  4. Treffen für 5 Sekunden lang gar keine Pegelwechsel ein, wird TC1 auf Null gesetzt (CTC-Modus) und der Fehlercode E0 auf der LCD ausgegeben (Zeit einstellbar mit der Konstanten TimeOut im Quelltext).
  5. Bedingt durch die Reaktion auf ALLE Pegelwechsel ist es egal, ob Aktiv-High- oder -Low-Signale vorliegen, sie werden alle korrekt gezählt. Da auf den Flankenwechsel eines korrekten Null- oder Eins-Bits immer auch ein zweiter Flankenwechsel erfolgt, wenn das nächste Bit beginnt, werden diese Flankenwechsel aufgrund ihrer Dauer (800 bis 900 ms) erkannt und ignoriert.
  6. Für die Dauer aller Signale lässt sich eine Toleranz einstellen (Konstante cDcfTol in Prozent). Diese sollte nicht zu niedrig (weniger als 5%) und nicht zu hoch (mehr als 30%) eingestellt werden. Überlappen sich Erkennungsbereiche, wird dies beim Assemblieren als Fehler eingestuft und mit einer Fehlermeldung abgefangen.
Allen Signaldauern, die kürzer als für eine Null erforderlich sind oder die zwischen den Bereichen für eine Null, eine Eins, eine Pause oder einem Minutenwechsel liegen oder die länger als ein Minutenwechsel dauern, sind fünf Fehlermeldungen zugeordnet, die als E1 bis E5 auf der LCD angezeigt werden. Liegen beim Minutenwechsel nicht genau 59 korrekt empfangene Bits vor, wird E6 angezeigt.

Alle empfangenen Bits werden in acht Registern (rDcfn mit n=0 bis 7) aufbewahrt. Sie werden jeweils von rDcf7, beginnend mit dessen Bit 7, wie in einem Schieberegister von links nach rechts eingeschoben, so dass das vor dem Minutenwechsel zuletzt gesendete Bit in Bit 7 von rDcf7 liegt. Die Lage aller Bits bei dieser Auswertemethode ist hier im Detail dargestellt.

3.7 DCF77-Zeit- und Datumsextraktion

Flussdiagramm der DCF77-Bits-Auswertung Die in rDcf0 bis rDcf7 gesammelten DCF77-Bits werden, wenn genau 59 fehlerfrei gesammelt sind, ausgewertet und in Datums- und Zeitwerte umgewandelt.

Minutenextraktion Um zu demonstrieren, wie das gemacht wird, hier das Vorgehen bei der Extraktion der Minuten aus dem Datenstrom. Die Bits der DCF77-Sekunden (Beginn der Zählung mit 0) sind in den Registern rDcf3 (Minuten-Einer: Bit 2, bis Minuten-Zwanziger: Bit 7) und rDcf4 (Minuten-Vierziger: Bit 0, Minutenparität: Bit 1) versammelt. Um die Minutenbits vollständig in ein Register zu bekommen, werden
  1. die Register rDcf3 und rDcf4 in ein anderes Registerpaar kopiert (z. B. nach ZH:ZL), was mit MOV geht,
  2. das höhere Byte einmal mit LSR rechts geschoben, wobei Bit 0 von ehemals rDcf4 in das Carry-Bit des Statusregisters gelangt, und von dort
  3. mit ROR in das untere Byte in ZL von links her eingeschoben wird,
  4. nach erneuter Wiederholung von LSR und ROR alle acht Bits der Minuten einschließlich des Paritätsbits in ZL versammelt.
Dann muss die Paritätsprüfung erfolgen. Dazu muss die Anzahl an Einsen in dem Byte geradzahlig sein (even parity). Da die CPU der AVR keine Paritätsflagge kennt, müssen die Anzahl Einsen in einem Zählregister gezählt und mit ANDI Register,1 und anschließendem bedingten Sprung BREQ oder BRNE, oder auch mit SBRC Register,0, entschieden werden, ob die Parität korrekt eine Null ergibt.

Ist das der Fall, können die Einer des Minutenbytes, nach Löschen des Paritätsbits und der Zehnerbits, z. B. mit ANDI ZL,0x0F, daraufhin überprüft werden, ob sie mehr als Neun ergeben. Wenn ja, liegt ein Fehler vor. Hat man vor dem Löschen der Zehner diese nach ZH kopiert, können nun die Zehner, Zwanziger und Vierziger hinzuaddiert werden, z. B. mit SBRC ZH,4 und subi ZL,-10 und analog mit den beiden höherwertigen Bits die Zwanziger und Vierziger.

Danach liegen die Minuten im Binärformat vor und können darauf hin überprüft werden, ob sie größer als 59 sind. Ist das nicht der Fall, sind die Minuten korrekt und können zwischengespeichert werden. Das Zwischenspeichern empfiehlt sich, weil bei der weiteren Umwandlung von Stunden und des Datums weitere Fehler auftreten könnten, so dass die ausgewertete DCF77-Zeit nicht korrekt ist und nicht in die Uhr übernommen werden sollte.

Beim Wochentag ist noch zu beachten, dass DCF77 den Montag mit 1 beginnt, in dieser Uhr aber mit Null gespeichert wird.

In gleicher Weise werden alle weiteren benötigten Datms- und Zeitinformationen zusammengestellt. Am Ende wird noch überprüft, ob das allererste DCF77-Bit eine Null war und ob das erste Zeit- und Datumsbit eine Eins war. Falls bei allen Prüfungen keine Fehler auftraten, können die im Zwischenspeicher gesammelten Auswertungen in die Uhr übertragen werden. Die Sekunden werden auf Null gesetzt. Da mit der Auswertung bis hierhin eine Zeitverzögerung von etwa 30 ms auftrat, wird auch die TC0-Uhr auf einen entsprechenden Wert gesetzt. Wichtig ist noch das Löschen der bSec-Flagge, die in der TC0-OVF-Interrupt-Service-Routine bereits gesetzt sein könnte und bewirken würde, dass die Uhr um eine Sekunde vorgeht.

3.8 LCD-Steuerung

Die LCD-Ansteuerung wurde mit den Include-Routinen in lcd.inc realisiert. Diese enthält alle nötigen Unterroutinen Alle Einstellungen, die dazu nötig sind, wie Ansteuerungsports (Datenport, Kontrollpins), Ansteuerungsarten (mit Busy-Abfrage über den oberen Datenport), Anzahl Zeilen und Spalten der LCD (LcdLines, LcdCols), u.v.a.m., sind im Abschnitt "LCD Configuration" im Quelltext vorgenommen. Darüber können bequem Änderungen des LCD-Typs vorgenommen werden.

Ein großer Vorteil dieser lcd.inc ist, dass mit umfangreichen .IF-Einstellungen kein unnützer Code im Flash landet sondern wirklich nur das, was tatsächlich auch benötigt wird. Nur so war es möglich, mit dem im ATtiny24 verfügbaren Flashspeicher auszukommen.

Seitenanfang Hardware Aufbau Software


Lob, Tadel, Fehlermeldungen, Genöle und Geschimpfe oder Spam bitte über das Kommentarformular an mich.

©2019 by http://www.avr-asm-tutorial.net