Pfad: Home => AVR-Übersicht => Anwendungen => DCF77-Weckuhr m16 => Software   This page in english: Flag EN
DCF77 Weckuhr Anwendungen von
AVR-Einchip-Prozessoren AT90S, ATtiny, ATmega und ATxmega
DCF77 Weckuhr mit LCD
Die Assembler-Software

Logo

Die Software für die DCF77-Weckuhr mit LCD

0 Inhalt

  1. Die Software-Struktur
  2. Die Debug-Schalter
  3. Die Software-Einstellungen
  4. Die LCD-Ansteuerung
  5. Uhrzeit und Datum
  6. DCF77-Synchronisation
  7. Tasten
  8. Musik

1 Die Software-Struktur

Die Software in Assembler ist aufgeteilt und in folgende Dateien gegliedert:
  1. dcf77_m16_v4_de.asm: enthält das Hauptprogramm mit der Initiierung der Hardware, mit den Interrupt-Routinen, der DCF77-Synchronisation, der Uhr, der Tastenbedienung und der ADC-Wertmessung,
  2. lcd_8_routinen.inc: alle Routinen zur Einstellung und Bedienung der LCD, Initiierung, Positionierung, Ausgabe von Kontroll- und Textzeichen, Ausgabe von Dezimal- und Hexzahlen, Erzeugen von Spezialzeichen,
  3. musik_code.inc: enthält alle Routinen zur Erzeugung und Kodierung von Musikstücken, die beim Wecken gespielt werden sollen, Notendefinitionen, Kodierung von Noten und Pausendauern, gespeicherte Melodien, Umwandlung von Melodien in Folgen von Tonhöhen und Dauern,
  4. debug_code_de.inc: alle Routinen, die fuer das Auswerten und die Darstellung von Debug-Optionen gebraucht werden, wird nur eingebunden, wenn eine der Debug-Optionen ausgewählt ist. Um eine final funktionierende Version zu assemblieren, müssen alle dbg-Schalter auf Null gesetzt werden.


Struktur Debug Einstellungen LCD Uhrzeit/Datum DCF77 Tasten Musik

2 Die Debug-Schalter

Als Hilfe bei der Inbetriebnahme der Hardware, zum Testen der angeschlossenen Komponenten und zur Fehlersuche bei der Software sind zahlreiche Debug-Optionen in der Software implementiert. Sie werden eingeschaltet, indem die Schalterkonstanten im Kopf der Hauptdatei auf Eins gesetzt werden. Es macht keinen Sinn, mehr als einen einzigen Schalter auf Eins zu setzen.

Folgende Schalterkonstanten sind implementiert und sind nach ihrer Priorität geordnet nachfolgend beschrieben:

  1. dbgLcd: Diese Option schaltet die LCD ein (aktiviert sie), schaltet deren Hintergrundbeleuchtung auf halbe Helligkeit und gibt die Eröffnungsmeldung in Zeile 1 und 2 aus, die Zeilen 3 und 4 sind leer. Ist die Option eingeschaltet, werden keine weiteren Aktionen mehr ausgeführt (der Prozessor friert ein). Alle weiteren Debug-Optionen bauen auf einer funktionierenden LCD auf, dbgLcd ist dazu wieder auf 0 zu setzen.

    DCF77 m16 Debug LCD

  2. dbgAdc: Diese Option schaltet die LCD und deren Hintergrundbeleuchtung ein, misst nacheinander die ADC-Kanäle 0, 1 und 2 im 10-Bit-Modus und gibt das Ergebnis in Zeile 4 aus. Außer diesen fortdauernden Messungen werden keine weiteren Aktionen mehr ausgeführt. dbgAdc muss auf 0 gestellt werden, um weitere Debug-Aktionen oder normale Funktionen auszuführen.

    DCF77 m16 Debug ADC

  3. dbgKey: Diese Option schaltet die LCD und deren Hintergrundbeleuchtung ein und gibt fortlaufend den Zustand der Tasteneingänge an PB0, PB1 und PB2 aus (als 0 oder 1). Außerdem werden keine weiteren Aktionen mehr ausgeführt. Der Schalter dbgKey muss auf 0 gestellt werden, um nachfolgende Debug-Aktionen oder das Normalprogramm auszuführen.

    DCF77 m16 Debug Tasten

  4. dbgSpk: Testet den angeschlossenen Lautsprecher durch Ausgabe eines dauerhaften Tons und führt keine weiteren Aktionen aus.
  5. DCF-Debug-Optionen: Bei allen DCF77-Debug-Optionen läuft der normale Programmablauf weiter, nur in Zeile 4 erfolgen statt der Menüausgabe andere Ausgaben.
  6. dbgMusic: stellt in Zeile 4 den Ausgabeprozess beim Abspielen eines Musikstückes dar. Ausgegeben wird sekündlich: jeweils in 16-Bit Hexadezimalformat.

    DCF77 m16 Debug Musik

  7. dbgPlayStat: zeigt in Zeile 4 den Status des Timers TC1 an. Ausgegeben wird sekündlich:
    DCF77 m16 Debug PlayStat

Um nach dem Debuggen die normale funktionierende Version wieder einzustellen, müssen alle Debug-Schalter auf 0 gesetzt und erneut assembliert werden. Der Debug-Code ist in der finalen Version dann nicht mehr enthalten.

Struktur Debug Einstellungen LCD Uhrzeit/Datum DCF77 Tasten Musik

3 Die Software-Einstellungen

Die Software lässt sich mit Hilfe von Einstellkonstanten einstellen. Diese sind in der Assembler-Hauptdatei unter der folgenden Überschrift zusammengestellt.

;
; ==========================================
;    E I N S T E L L K O N S T A N T E N
; ==========================================
;

3.1 Prozessortakt

Der Prozessortakt lässt sich mit der Konstante clock einstellen. Im Quelltext findet sich diese in den Zeilen

; Prozessortakt externer Quarz
.equ Clock = 3276800 ; Quarzfrequenz

Möglich und sinnvoll und ohne weitere Änderungen an der Software können Quarze mit 2,048 bzw. 2,097152 oder 2,4576 MHz eingesetzt werden und durch Änderung dieser Konstanten angepasst werden.

Soll ein Quarz mit 4,194304 MHz verwendet werden, dann muss Die Konstante cSecDiv findet sich im Quellcode hier:

.equ cSecDiv = clock / cTc0Presc / cTc0Divider
.if cSecDiv>255
  .error "cSecDiv out of range!"
  .endif

Andere Quarze können nicht ohne weitere Software-Änderungen verwendet werden.

3.2 DCF77-Zeitkonstanten

Diese Konstanten finden sich im Quellcode unter
 
;
; DCF77 Signaldauern in Millisekunden
.equ cDcfIgnoreShortTime = 20 ; Ignoriere Kurzimpulse mit weniger als 20 ms
.equ cDcfMinTime = 50 ; Minimum Signaldauer NUll- oder Eins-Bit
.equ cDcfMaxZeroTime = 150 ; Maximum Zeit Null-Bit
.equ cDcfMaxOneTime = 250 ; Maximum Zeit Eins-Bit
.equ cDcfMinInactiveTime = 700 ; Minimum inaktive Zeit bis naechstes Bit
.equ cDcfMaxInactiveTime = 1000 ; Maximum inaktive Zeit bis naechstes Bit
.equ cDcfMin59Time = 1700 ; Minimum Zeit fuer 59ste Sekunde
.equ cDcfMax59Time = 2000 ; Maximum Zeit fuer 59ste Sekunde
.equ cDcfTimeOutTime = 2500 ; Time-Out am DCF77-Signaleingang
;

Die Bedeutung dieser Konstanten ist unter dem DCF77-Erkennungs-Kapitel erläutert. Durch Änderungen bei diesen Konstanten können abweichende Eigenschaften des DCF77-Empfängers ausgeglichen werden. Es ist darauf zu achten, dass es bei den eingestellten Zeiten nicht zu Überlappungen kommt.

3.3 LCD-Hintergrundbeleuchtung

Die Einstellungen zur LCD-Hintergrundbeleuchtung finden sich im Quellcode unter

;
; LCD Hintergrundbeleuchtung
.equ cBackPeriodsTime = 3000 ; Millisekunden Ansteuerung
.equ cBackMin = 10 ; Mindest-Wert der Helligkeit, 10 bis 255
;

Bei der Einstellung von cBackMin muss die LCD bei Dunkelheit gerade noch lesbar sein. cBackPeriodsTime ist Geschmackssache und vermeidet Flimmern der Anzeige.

3.4 S-Meter-Anzeige

Die S-Meter-Anzeige macht nur Sinn, wenn der DCF77-Empfänger diese Spannung auch zur Verfügung stellt. Ansonsten erscheint in der Anzeige S0. Die Einstellung findet sich im Quellcode unter

;
; DCF77-Signalstaerke-Ausgabe in S-Stufen
.equ cSigStrTime = 2000 ; Erneuerung der Ausgabe alle ... Millisekunden
;

Ist keine Spannung verfügbar, kann diese Konstante auf eine sehr lange Zeit eingestellt werden (Maximum bei ca. 24.000, abhängig von der Taktfrequenz).

Welche externe Spannung zu welcher Anzeige auf dem Display führt, ist in der Tabelle SignalTable: im Quellcode festgelegt. Sie passt für den beschriebenen DCF77-Empfänger und bedarf bei anderen Empfängern der Anpassung. Dabei kann der Debug-Modus dbgAdc mit der Einstellung auf Kanal ADC2 behilflich sein, der die Spannung misst und anzeigt.

3.5 Prellunterdrückung der Tasten

Die Einstellung der Prellunterdrückung findet sich im Quellcode unter

;
; Tastenprellunterdrueckung
.equ cKeyCntTime = 30 ; Taste inaktiv fuer ... Millisekunden
;

Sie sollte wenigstens 20 und höchstens 100 Millisekunden betragen.

3.6 Anzahl Weckwiederholungen

Die Anzahl Weckwiederholungen ist Geschmackssache und findet sich im Quellcode unter

;
; Weckwiederholungen
.equ cAlarmRepet = 3 ; Anzahl Minuten Weckwiederholung
;

3.7 Musikstück bei Neustart

Diese Einstellung kann hilfreich sein, wenn man Musikstücke ändern oder ergänzen will (maximal ist die Software auf 16 verschiedene Melodien eingestellt). Die Einstellung findet sich im Quellcode unter

;
; Musikstueck-Auswahl bei Neustart
.equ cDefaultMelody = 2 ; Melodie, die beim Neustart gespielt wird
;

4 Die LCD-Ansteuerung

Die LCD ist folgendermaßen an den ATmega16 angeschlossen: Alle Routinen zur Ansteuerung der LCD sind in der Include-Datei lcd_8_routinen.inc enthalten. Im Kopf dieser Datei sind alle Routinen angegeben, die für die Ansteuerung angesprochen werden können und ihre Funktion ist erläutert.

Helligkeitssteuerung der LCD Die Hintergrundbeleuchtung über den Timer 2 wird im Hauptprogramm eingeschaltet. Dazu wird der Timer 2 mit einem Vorteiler von 64 und als 8-Bit-PWM betrieben (fPWM = 3.276.800 / 64 / 256 = 200 Hz). Höhere Werte im Compare-Register führen zu höherer Helligkeit der Hintergrund-LEDs.

Die Fotodiode mit dem 100k-Widerstand nach Plus misst dazu alle drei Sekunden (einstellbar in cBackPeriodsTime) die Umgebungshelligkeit, der AD-Wandlerkanal ADC1 summiert 64 Einzelwerte auf und das invertierte MSB (je höher die Umgebungshelligkeit desto kleiner die Spannung am ADC1) dieser Summe wird mit dem Wert (255 - Grundhelligkeit) multipliziert (Grundhelligkeitswert einstellbar in cBackMin). Die Grundhelligkeit wird zum MSB des Multiplikationsergebnisses hinzu addiert und der Wert in das Compare-Register von Timer 2 geschrieben.

Daraus ergibt sich etwa der nebenstehende Zusammenhang zwischen der Umgebungshelligkeit und der LCD-Hintergrundbeleuchtung.

5 Uhrzeit und Datum

Eine umfassende Darstellung zu Uhrzeit und Datum in Assembler gibt es hier.

Der Timer 0 erzeugt das Sekundensignal:
  1. Der Prescaler von 64 teilt die Quarzfrequenz und tickt mit 51,200 kHz.
  2. Für 256 Ticks werden 5 ms benötigt (200 Hz), dann erfolgt der Overflow-Interrupt.
  3. In der Overflow-Interrupt-Service-Routine wird das Register rSecDiv von 200 auf Null herabgezählt. Ist Null erreicht wird die Flagge bSec im Flaggenregister rFlag gesetzt und damit, außerhalb des Interrupts, das Erhöhen von Uhrzeit und Datum angetriggert.
Datum und Uhrzeit sind im SRAM ab Adresse sDateTime: in binärem Format abgelegt. Die Reihenfolge der Bytes folgt der Anzeige und ist daher folgendermaßen festgelegt:
  1. Wochentag: 0 (Montag) bis 6 (Sonntag)
  2. Tag: 1 bis 31
  3. Monat: 1 bis 12
  4. Jahr: 0 bis 99
  5. Stunde: 0 bis 23
  6. Minute: 0 bis 59
  7. Sekunde: 0 bis 59
Die Weckzeit-Stunden und -Minuten sind daran anschließend abgelegt.

Erhoehung Sekunde Die Routine IncSec: erhöht die Sekunde um Eins und passt, falls erforderlich, die restlichen Zeit- und Datumsgrößen an, so dass die Uhr auch im Stand-Alone-Betrieb, also ohne DCF77 und mit manuell eingestellter Zeit und Datum, korrekt weiterläuft. Es werden nur diejenigen Parameter der Uhrzeit und des Datums auf der LCD erneuert, die der Anpassung bedürfen, sofern sie sich bei der Erhöhung tatsächlich geändert haben.

Die Ausgabe von Datum und Uhrzeit wird unterdrückt, sobald die manuelle Eingabe von Datum und Uhrzeit angewählt wird (gelbe Taste im Normalbetrieb). Anders als im Diagramm dargestellt erfolgt dennoch die Aktualisierung in jeder Sekunde (und auch die Synchronsiation mit DCF77), damit die Uhrzeit auch nach Abbruch der manuellen Eingabe noch korrekt ist (es erfolgt nur keine Wochentags- und Zahlenausgabe).

Struktur Debug Einstellungen LCD Uhrzeit/Datum DCF77 Tasten Musik

6 DCF77-Synchronisation

Die Erkennung von DCF77-Signalen erfolgt mit dem INT0-Interrupt. Beide Flanken (Low==>High, High==>Low) führen zu einem Interrupt. In der Interrupt-Service-Routine wird
  1. der Stand des Zählers rDcfCntH:rDcfCntL abgelesen, der vom Timer 0 alle 5 ms erhöht wird,
  2. geprüft, ob der Zähler kleiner als cDcfIgnoreShort ist, falls ja wird der Impuls ignoriert,
  3. der Zählerstand in das Registerpaar rDcfH:rDcfL kopiert,
  4. die Flagge bDcf im Flaggenregister rFlag gesetzt, und
  5. das Zählerregisterpaar rDcfCntH:rDcfCntL auf Null gesetzt.
Die weitere Verarbeitung des erkannten DCF77-Signals erfolgt außerhalb des Interrupts in der Routine DcfAct.

DCF77-Signalauswertung Unabhängig von der Polarität des DCF77-Empfängers (Aktiv-High oder Aktiv-Low) dauert bei DCF77
  1. ein Null-Bit 100 ms,
  2. ein Eins-Bit 200 ms,
  3. ein fehlendes Minutensignal zwischen 1.800 und 1.900 ms,
  4. die Zeit zwischen dem Ende eines Bits und dem Beginn des nächsten Bits zwischen 800 für ein Eins-Bit) und 900 ms für ein Null-Bit.
Entsprechend des gewählten Timings beim Erhöhen des Zählers entsprechen 100 ms einem Zählerstand von 20 etc.

Da bei der Erkennung von Null- und Eins-Bits im Empfänger immer eine gewisse Zeit vergeht, je nach der werkelnden Gleichrichter- und Kondensator-Mimik, sind die oben genannten Zeiten mit einer gewissen Toleranz zu versehen. Die Toleranz wurde hier bewusst recht breit gewählt, z. B. für ein Null-Bit 50 bis 149 ms entsprechend einem Zählerstand von 10 bis 29, damit es nicht zu Signalfehlern kommt.

DCF77-Signalfehler-Erkennung Daraus ergibt sich das nebenstehende Diagramm zur Signalfehlererkennung. Signaldauern mit roter Kennzeichnung sind "Signale zur falschen Zeit", sie werden mit den Kürzeln s1 bis s4 in Zeile 3 der LCD angezeigt. Bleibt das DCF77-Signal für länger als 2,5 s lang inaktiv, wird noch s5 angezeigt.

DCF77-Signalauswertung-Fliessbild Das führt zu dem nebenstehenden Flussdiagramm. Ist ein Null- oder Eins-Bit korrekt erkannt, wird eine Null oder eine Eins in den SRAM-Puffer sDcfBits von hinten her eingeschoben und alle anderen 63 Bits um eins nach vorne gerückt. Auf diese Weise sammeln sich die 59 Bits in einer Minute in diesem Puffer an und können nach Ende der Minute, nach Ausbleiben des 60sten Bits ausgewertet werden.

Zunächst ist bei der Auswertung zu prüfen, ob
  1. Signalfehler im Übertragungsstrom vorlagen,
  2. exakt 59 Bits empfangen wurden.
Im zweiten Fall wird die Anzahl der empfangenen Bits nn in Zeile 3 der LCD angezeigt. In beiden Fällen wird die weitere Auswertung verworfen. Hat das Signal über eine Minute lang alle Prüfungen bestanden, kann es an die Dekodierung der Bits gehen.

DCF77-Zuordnung der Bits zu Registern Die gesammelten 59 Bits befinden sich in acht Registern bzw. in acht Speicherstellen des SRAM ab sDcfBits. Da die Bits mit Rotate Right, vom achten Register angefangen, in diese Register eingeschoben wurden, befindet sich das letzte gesendete Bit stets in Bit 7 des achten Registers. Das Rechtsschieben hat den Vorteil, dass die Minuten-Bits in der richtigen Reihenfolge in den Registern oder Speicherzellen liegen und auf einfache Weise in binäre Werte umgerechnet werden können (die BCD-kodierten Zehner natürlich anders als die Einer). Aus dem Rechtsschieben ergibt sich in rückwärtiger Reihung, in welchen Registern oder Speicherzellen die angefangenen Bits für Minuten, Stunden, Tag, Wochentag, etc. liegen. Die genaue Zuordnung für alle 59 DCF77-Bits zu den Bits in den Registern oder Speicherzellen geht aus dem Diagramm hervor.

In der folgenden Beschreibung werden zwei Zählweisen für die DCF77-Bits und die AVR-Register verwendet: die Zählung der Bits kann mit Null oder mit Eins beginnen, ebenso die der Register oder SRAM-Speicherstellen. Damit beide Zählarten möglich sind, sind beide hier angegeben.

Die erste Prüfung ist, ob das erste gesendete Bit (Bit 0 in der 0-basierten Zählung, Bit 1 in der 1-basierten Zählung) eine Null ist. Da DCF77 pro Minute 59 Bits sendet, acht Bytes aber insgesamt 64 Bits umfassen, und weil die Datenbits im Bild von unten nach oben einrotiert werden, befindet sich das erste Bit nicht in Bit 0 des Speichers: das erste gesendete Bit befindet sich in Bit 5 an der SRAM-Adresse sDcfBits (Byte 0 des SRAM-Puffers). Ist das erste Bit keine Null, wird E0 als Fehlermeldung ausgegeben und die weitere Auswertung verworfen.

Ähnlich könnte auch das 21.te Bit geprüft werden: es muss immer Eins sein. Die entsprechende Prüfung und die Fehlermeldung E1 ist aber in dieser Version nicht implementiert.

Die Minuten-Einer befinden sich in den Bits 2 bis 5 an der Adresse sDcfBits+3. Sind diese vier Bits größer als Neun, liegt ein Fehler vor und die Fehlerkennung ME wird ausgegeben.

Die Minuten-Zehner liegen in Bit 6 und 7 von Byte drei (0-basiert) sowie in Bit 0 von Byte 4 im SRAM. Nachdem die beiden unteren Bits mit LSL und ROL mit dem dritten Bit vereint sind, mit ANDI Register,0x07 isoliert wurden und als nicht größer als fünf überprüft sind, werden diese mit zehn mal genommen: dazu wird die Zahl zunächst kopiert, die Kopie durch zweimaliges Linksschieben mit LSL mit vier multipliziert, das Original hinzu addiert und noch einmal links geschoben. Dann werden die Einer dazu addiert und als Minutenbyte in binärem Format zwischengespeichert.

Die Minutenbits haben noch das Paritätsbit P1. Dieses befindet sich in Bit 1 des fünften Bytes (sDcfBits+4). Alle Minutenbits zusammen mit diesem Paritätsbit müssen eine geradzahlige Anzahl an Einsen enthalten. Die Paritätsprüfung erfolgt so, dass
  1. ein Einser-Zähler auf Null gesetzt wird,
  2. solange Bits mit LSL nach links oder mit LSR nach rechts in das Carry-Bit geschoben werden, bis die Zahl Null wird,
  3. immer wenn Carry Eins ist, wird der Einser-Zähler erhöht.
Am Ende muss das Bit 0 des Einserzählers Null sein (z. B. mit ANDI Register,1). Ist das nicht der Fall, liegt ein Paritätsfehler vor.

Analog wird mit den Stunden-Bits verfahren. Auch hier wird noch das Paritätsbit überprüft.

Ist bis dahin alles fehlerfrei, geht es mit den Datumsinformationen in den gesammelten Bits weiter. Hier erstreckt sich das Paritätsbit über das gesamte Datum (23 Bits). Die Paritätsprüfung kann mit derselben Routine erfolgen, indem nacheinander die Einsen in den drei Bytes gezählt werden, aber beim zweiten und dritten Byte das Löschen des Einserzählers unterbleibt.

Ist die gesamte Auswertung mit allen Fehlerprüfungen erfolgreich absolviert, wird als Kurzmeldung in Zeile 3 ok ausgegeben, die dekodierte Zeit in den Puffer sDateTime kopiert (falls nicht gerade eine manuelle Eingabe von Datum und Zeit erfolgt), der Sekundenvorteiler auf 200 und die Sekunden auf Null gesetzt. Die Zeit ist nun DCF77-synchronisiert.


Struktur Debug Einstellungen LCD Uhrzeit/Datum DCF77 Tasten Musik

7 Tasten

Die drei Tasten werden in der Interrupt-Service-Routine des Timers 2 alle 5 ms abgefragt. Ist eine der Taste gedrückt, wird die Flagge bKey gesetzt und das Register zur Prellunterdrückung rKeyCnt auf 30 ms gesetzt (einstellbar mit cKeyCntTime). Nachfolgende Tastendrücke werden nur akzeptiert, wenn das Register auf Null gezählt ist.

Tastenbedienung Ist die Tasteneingabe inaktiv und das Wecken nicht aktiviert (sKeyMode = 0), dann bewirkt der Druck auf die rote Taste das Aktivieren der Weckfunktion (sKeyMode = 1), die gelbe den Beginn der Datums- und Uhrzeiteingabe (sKeyMode = 2) und die weiße die Eingabe der Weckzeit (sKeyMode = 3).

Ist Wecken aktiviert, dann schaltet die rote Taste das Wecken wieder aus, die gelbe erhöht die Weckzeit um fünf und die weiße um zehn Minuten. Dabei wird die eingestellte Weckzeit nur temporär verändert, wird das Wecken ausgeschaltet dann wird wieder die Originalzeit vor der Erhöhung aktiviert.

Bei den Eingabemodi für Datum/Uhrzeit und Weckzeit wird die aktive Eingabeposition blinkend dargestellt. Eingestellt werden immer die Zehner und Einer der betreffenden Zahl gleichzeitig. Hier bewirkt die rote Taste, dass der Eingabecursor in die vorhergehende Position geht. Befindet sich der Cursor bei der Datumseingabe auf dem Wochentag oder bei der Weckzeiteingabe auf der Weckzeitstunde, wird der Eingabemodus wieder verlassen und keine Änderung vorgenommen.

Die gelbe Taste bewirkt im Eingabemodus, dass der alte Zustand an der Cursorposition wieder hergestellt wird und eventuelle Verstellungen wieder rückgängig gemacht werden. Der Cursor wechselt dann in die nächste Position. Die Einstellungen an der Cursorposition können mit dem Potentiometer eingestellt werden. Befindet sich das Potentiometer am linken oder rechten Anschlag wird die niedrigste bzw. höchste Einstellung an dieser Position vorgenommen. Linksdrehen am Potentiometer erniedrigt, Rechtsdrehen erhöht den Wert.

Mit der weißen Taste wird die nächste Position angesteuert. Befand sich der Cursor bei der Datumseingabe auf den Sekunden, wird das eingestellte Datum und die Zeit in den Puffer sDateTime übernommen und angezeigt. Ist die DCF77-Synchronisation erfolgreich, wird das eingegebene Datum und die Zeit wieder überschrieben. Befand sich der Cursor bei der Weckzeiteingabe auf den Minuten, wird die Weckzeit neu gesetzt und das Wecken aktiviert. In beiden Fällen wird mit der weißen Taste der Eingabemodus wieder verlassen.

Struktur Debug Einstellungen LCD Uhrzeit/Datum DCF77 Tasten Musik

8 Musik

Die Musikerzeugung arbeitet hardware-mäßig mit dem Timer TC1. Als Vorteiler ist er auf 1 eingestellt. Die diversen Tonfrequenzen hierfür werden in das Vergleichsregister Compare-A geladen. Erreicht der Zähler den Vergleichswert, Ist die Tonausgabe aktiviert, dann wird in der Compare-A-Interrupt-Routine ein 16-Bit-Zähler in rDurH:rDurL abwärts gezählt, der die Anzahl Durchgänge und damit die Dauer des Tons bestimmt. Erreicht er Null, wird der nächste CTC-Wert aus dem SRAM an der Adresse im Doppelregister Y geladen. Ist dieser Wert 0xFFFF wird der Lautsprecher ausgeschaltet (COM1A1 auf clear), andernfalls wird er eingeschaltet (COM1A0 auf Toggle). Der aus dem SRAM gelesene Wert wird in das Vergleichsregister Compare A geschrieben. Danach wird der 16-Bit-Zählerwert aus dem SRAM in das Registerpaar rDurH:rDurL gelesen. Ist dieser Null, dann ist die Melodie beendet und der Timer-Interrupt wird abgeschaltet.

Ist der Wecker eingeschaltet (sKeyMode = 1), dann wird in jeder Minute die Weckzeit mit der Uhrzeit verglichen. Besteht Gleichheit, dann wird eine der im Flash gespeicherten Melodien zufällig ausgewählt, die Noten und Pausen dieser Melodie analysiert und in CTC-Werte und Dauern in das SRAM konvertiert (Routine MusicCovert:). Die maximale Anzahl an Wiederholungen des Musikstückes in sAlarmRepeat wird auf die Konstante cAlarmRepeat gesetzt. Mit jeder nachfolgenden Minute wird diese Melodie neu gestartet (Routine MusicPlay;), bis entweder der Weckmodus mit der roten Taste ausgeschaltet wird (sKeyMode = 0) oder die Anzahl Wiederholungen erreicht wird.

Die Melodien vor der Konvertierung sind im Flash folgendermaßen abgelegt (NoteNamesTable: in musik_code.inc): Die CTC-Werte für die Noten 0 bis 70 sind in der Tabelle NoteTimerTable: im Flash abgelegt. Das jeweils erste Wort gibt den CTC-Wert für die Erzeugung der Notenfrequenz aus dem Prozessortakt (z.  3,2768 MHz / fTon - 1), das zweite Wort die Anzahl Timerdurchläufe für die Dauer von einer Sekunde (entsricht der Notenfrequenz mal zwei).

Die Melodien sind im Flash in Form dieser Notenfolgen abgelegt. Die Tabelle MelodyTab: zeigt auf den Beginn der jeweiligen Melodie im Flash (mal zwei).

Struktur Debug Einstellungen LCD Uhrzeit/Datum DCF77 Tasten Musik


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