Anwendungen von
AVR-Einchip-Controllern AT90S, ATtiny, ATmega und ATxmega DCF77 Wecker mit ATmega324PA
10 DCF77 Wecker mit ATmega324PA
Experimentell! Noch nicht getestet!
Mit diesem Projekt versuche ich folgende Teile zu integrieren:
den AM-Gleichrichter für 77.5 kHz HF oder 32.868 kHz
ZF,
den Controller, der die Frequenz der Eingangs-HF-Stufe mit der
AFC-PWM einstellt und den AGC-Regler, der die Verstärkung des
HF-/ZF-Verstärkers über die AGC-PWM einstellt und der die
DCF77-Signale dekodiert, und
die Anzeige von Datum und Zeit auf einer LCD.
Das sind die Verbindungen der Weckuhr zu den Empfangskomponenten.
Zusätzlich kommen noch folgende Komponenten hinzu, um einen
vollwertigen Wecker zu erhalten:
ein Quarz, der die Zeitbasis für die DCF77-unabhängige
Zeit- und Datumsinformationen liefert, auch ganz ohne DCF77,
die Möglichkeit, Datum und Uhrzeit und die Weckzeit mittels
dreier Tasten einzustellen,
das Stellen einer Weckzeit, zu der Melodien auf einem kleinen
Lautsprecher ertönen, und
das Messen des Umgebungslichts, um die Helligkeit der
LCD-Beleuchtung an die dessen Intensität anpassen zu können.
Das Projekt ist bislang eine Idee und noch nicht fertig aufgebaut.
10.1 Auswahl des Controllers
Um alle Hardware-Anforderungen zu erfüllen, die benötigt
werden, muss der Controller folgende Komponenten haben:
zwei PWM-Ausgänge mit hoher Frequenz für die AFC- und
AGC-Steuerung,
einen PWM-Ausgang mit einer Frequenz von 100 bis 200 Hz
für die Hintergrundbeleuchtung der LCD,
einen 16-Bit-Timer im CTC-Modus mit einem OC-Ausgangspin um den
Weckton und die Musik zu erzeugen,
zwei Xtal-Pins um den Controller mit einem Quarz takten zu
können,
einen 8-Bit bidirektionalen Port für den Datentransfer zur
LCD und um die Busy-Flagge der LCD lesen zu können,
drei Pins für die drei Tasten, die Interrupts beim
Tastendrücken auslösen können (entweder INTn- oder
PCINTn-Interrupts),
drei Analogwandler-Eingänge für die Messung der
HF/ZF-Amplitude, des Umgebungslicht-Sensors und eines Potenziometers,
das für die komfortable Eingabe von Datum, Uhrzeit und Weckzeit
dient.
Da einer der drei Timer auch noch den 5-ms-Puls für die
DCF77-Signal-Analyse und für die daraus abgleiteten Sekundenimpulse
liefern muss, habe ich TC2 für diesen Zweck ausersehen. Da eine
genaue Zeitbasis nötig ist und daher dieser Timer im CTC-Betrieb
mit Compare A arbeiten muss, habe ich OCR2B für die PWM vorgesehen.
Das ist die Auswahl des Controllers im AVR-Assembler-Simulator avr_sim.
Nicht sehr viele AVR-Typen erfüllen alle diese Anforderungen. Allen
enden mit "4". Ein Preisvergleich ergab, dass ATmega324PA
mein Favorit ist.
10.2 Die Hardware
Das ist das Schaltbild der kompletten Hardware des Weckers.
Die drei AD-Wandler-Kanäle ADC0, ADC1 und ADC2 sind mit den folgenden
externen Komponenten verbunden:
das HF- oder ZF-Signal des DCF77-Empfängers, das auf seine
Amplitude hin intern untersucht wird, ist an ADC0 angeschlossen,
ADC1 empfängt das Sensorsignal des Umgebungslichtmessgeräts
von außerhalb der Box,
an ADC2 ist der Schleifer des Potenziometers angeschlossen, das die
Spannung für 0 bis 59 (Sekunden, Minuten) bzw. für 0 bis 23
(Stunden) bzw. 0..6 (Wochentag) misst.
Normalerweise misst der ADC die Amplitude des HF-/ZF-Signals in einer sehr
schnellen Folge und ist daher im Freilaufmodus mit eingeschalteten Interrupts.
Von Zeit zu Zeit (2 Sekunden für den Lichtsensor, 200 ms für
das Potenziometer, aber nur, wenn die Eingabe aktiv ist. In beiden Fällen
werden Freilaufmodus und ADC-Interrupts gestoppt und nach der Einzelmessung
im Polling-Verfahren wieder gestartet.
Der Controller wird von dem Quarz mit 4,096 MHz getaktet, so dass der
Betrieb der Weckuhr auch ohne Synchronisation mit DCF77 über Monate
hinweg exakt erfolgt, ohne dass die Uhr nachgestellt werden muss.
Die AFC- und AGC-Signale werden von den Ausgängen OC0A und OC0B produziert
und mit einem jeweils zweistufigen RC-Netzwerk gefilter. Die PWM-Frequenz
beträgt 16 kHz, während die Zeitkonstante des RC-Netzwerks
1000-fach niedriger bei 14,5 Hz liegt. Daher ist die Restwelligkeit
des RC-Netzwerks mit 10 µV niedrig genug, um die AFC und AGC
nicht zu stören. Während die Welligkeit am ersten Kondensator
noch 7,82 mV beträgt, ist sie am zweiten Kondensator
vernachlässigbar niedrig. Die Berechnung wurde mit LibreOffice
Calc durchgeführt, das Rechensheet ist
hier verfügbar.
Die drei Tasten sind an PB0, PB1 und PB2 angeschlossen. Die Eingänge
sind mit Pull-Up-Widerständen per software auf die Betriebsspannung
gezogen. Tastendrücke bewirken PCINT-Interrupts. Jede betätigte
Taste blockiert weitere PCINT-Interrupts für 100 ms lang, so
dass Tastenprellen unterbunden wird.
Alle externen Komponenten sind über einen 10-poligen Steckverbinder
angeschlossen, dessen Pinbelegung rechts unten gezeigt ist.
Um den ATmega324PA innerhalb des Systems zu programmieren ist ein
Standard-6-Pin-Stecker vorhanden. Der ist in der extern fertig programmierten
Version nicht nötig, aber erleichtert Programmänderungen.
10.3 Aufbau des Weckers
Noch zu machen (TBD)
10.4 Software für den Wecker
TBD
10.4.1 Download der kompletten Software
TBD
10.4.2 Software für Hardware-Tests
TBD
10.4.2.1 Testen des Quarztaktes und des ISP-Interfaces
TBD
10.4.2.2 Installation und testen der LCD
TBD
10.4.2.3 Testen der LEDs
TBD
10.4.2.4 Testen der AFC- und AGC-Signal-Erzeugung
TBD
10.4.2.5 Testen der Tasten
TBD
10.4.2.6 Testen des Lautsprechers
TBD
10.4.2.7 Testen des HF-/ZF-Gleichrichters
TBD
10.4.2.8 Testen des Umgebungslichtsensors
TBD
10.4.2.9 Testen des Potenziometers
TBD
10.4.3 Software für den Wecker
10.4.3.1 Datum und Zeit
Die Zeit ist unabhängig von der DCF77-Synchronisation
abgeleitet vom 4,096-MHz-Systemtakt durch TC2. TC2 teilt
im Vorteiler durch 256 und im CTC-Modus durch Voreinstellung
in Compare A durch 80. Das liefert eine PWM-Zykluszeit von
f = 4,096 MHz / 256 / 80 = 200 Hz. Das Register
rSecDiv zählt von 200 auf Null. Ist es Null, dann ist
eine Sekunde vergangen und Zeit und Datum müssen um
eine Sekunde erhöht werden.
Zeit und Datum sind vollständig in den ersten SRAM-Zellen
in binärer Form abgelegt. Jeder Bestandteil (Sekunde,
Minute, etc.) benötigt ein Byte. Insgesamt umfasst dieser
Datensatz sieben Bytes. Diese werden zu Beginn des Programms
auf einen Startwert gesetzt. Dieser kann mit den Tasten und
dem Potenziometer verstellt werden. Tritt DCF77-Synchronisation
ein, werden Zeit und Datum überschrieben und die Sekunden
auf Null gesetzt.
Das ist der Algorithmus zur Erhöhung um eine Sekunden.
Im linken Teil der beiden Fließbilder erfolgt die
Erhöhung, im rechten Teil jeweils der Update der LCD.
Alle Flussdiagramme gibt es in der LibreOffice-Zeichnungsdatei
hier.
Die meisten Erhöhungen sind einfach und simpel. Nur die
Berechnung der Tage des aktuellen Monats ist etwas tricky,
was wir einem Papst von um die 1500 und seinen Beratern zu
verdanken haben.
Bei der Realisierung in Assembler wird das Zeigerreister X
(R27:R26) verwendet, das immer dann erhöht wird, wenn
eine weitere Komponente erreicht wird.
Die Anzeige der Komponenten auf der LCD beginnt jeweils mit
dem Setzen der Ausgabeposition (Zeile, Spalte). Alle
Bestandteile außer des Wochentags erfolgen durch Aufruf
der Routine LcdDec2, die Bestandteil der LCD-Include-Datei
lcd.inc ist und aus einer
Binärzahl in R16 eine zweistellige Dezimalzahl macht
und auf der LCD ausgibt.
Damit der Benutzer den Wochentag nicht von Hand einstellen
muss, gibt es eine Routine, die den Wochentag aus dem
eingestellten Datum ermittelt. Rechts ist das Flussdiagramm
der Routine dargestellt.
Es ist recht einfach gestrickt und basiert auf dem Wochentag
am 1.1.2000, einem Samstag. Für jeden Tag und jedes Jahr
(minus 1) wird eins hinzugezählt. Der Versatz durch die
Monate ist etwas komplizierter und mit einer Tabelle im Flash
gelöst. Bei allen Monaten ab März muss noch Eins
hinzugezählt werden, wenn es ein Schaltjahr ist. Bei
den Jahren muss noch für jedes Schaltjahr seit 2000,
außer für das aktuelle Jahr, noch jeweils Eins
hinzugezählt werden.
Am Ende wird so lange 7 von der Zahl abgezogen, bis sie
kleiner als 7 ist (Modulo-Berechnung).
Wer mit der Berechnung ein wenig herumspielen spielen will:
hier ist der Quellcode
im asm-Format.