Pfad: Home => AVR-Übersicht => Anwendungen => Eieruhr-Timer m8   This page in english: Flag EN
Eieruhr-Timer mit m8 Anwendungen von
AVR-Einchip-Prozessoren AT90S, ATtiny, ATmega und ATxmega
Eieruhr-Timer mit ATmega8
Logo
Eieruhr ATmega8

Eieruhr-Timer mit einem ATmega8

Diese Eieruhr ist mit acht rot-grünen LED ausgestattet, von denen zum Stromsparen immer nur maximal zwei aktiv sind. Die erste zeigt die letzte ganze Minute in rot an, die zweite die gerade aktive Minute in grün mit zunehmend rotem Anteil. Zur vollen Minute spielt der Lautsprecher programmierbare Tonfolgen.

Auch zu diesem Projekt gibt es weitere Materialien:

Hardware

Schaltbild des m8-Timers Das Schaltbild gibt es hier im LibreOffice-Format als Draw-Datei. Die zugehörigen Berechnungen zu Schaltzeiten finden sich hier.

An den ATmega8 sind acht rot-grüne Duo-Leds an die Ports B und D angeschlossen. Jeweils zwei Bit-Port-Ausgänge treiben eine LED. Die Widerstände RL begrenzen den LED-Strom auf ca. 10 mA. Ihre Größe hängt von der Betriebsspannung ab, in der Tabelle sind Werte für diverse Betriebsspannungen angegeben.

Zu jeder vollen Minute wird eine programmierbare Melodie abgespielt. Das erfolgt über den Port PC0, an den der Lautsprecher über einen Elko angeschlossen ist.

Um die beiden Ports B und D vollständig für die LED-Ausgänge benutzen zu können, sind sowohl die LED-Steuerung als auch der Lautsprecher-Ausgang nicht an Timer-Pins angeschlossen. Die Organisation beider zeitkritischen Vorgänge erfolgt mit zwei Interrupts, die die betreffenden Ausgänge steuern. Wie das erfolgt, ist in dem Kapitel Software näher erläutert.

Aufbau, Gedruckte Schaltung

Eieruhr m8 Gedruckte Schaltung als gif Eieruhr m8 Bestueckung der gedruckten Schaltung Für die Eieruhr wurde von mir eine gedruckte Schaltung als hochauflösendes GIF mit den Maßen 40 * 50 mm entwickelt (links, auf das Bild klicken für hochaufgelöst). Die Bestückung ist rechts zu sehen.

Alle LEDs sind in gleicher Richtung eingebaut, so dass nur der längere LED-Anschluss immer unten liegen muss.

Die Schaltung kommt mit einer einzigen Brücke aus. Die einzelne Leitung innerhalb des ISP6-Steckers ist ein bisschen knifflig, bei mir hat es beim Ausdruck mit dem Laserdrucker, mit der UV-Belichtung mit UV-Leds, dem Entwickeln mit verdünnter Natronlauge und beim Ätzen mit Eisen-III-Chlorid aber prima geklappt.

Wer den ATmega8 nicht in der fertigen Schaltung programmieren will, kann den ISP6-Stecker auch weglassen.

Die Schaltung hat bei 3 V Betriebsspannung den folgenden Stromverbrauch.

PhaseZustandAnzahl LEDsLautsprecherStrom (mA)
StartErste LED in grün mit zunehmendem Rot-Anteil1-7,4
Eine LED grün, Musikstück1X18
FortlaufendEine LED rot, nächste LED grün mit zunehmendem Rotanteil2-13,3
neunte MinuteNur Musikstück-X8
SchlafenEnde, fertig, aus--0,4

Software

Software-Download

Den Quellcode im Assembler-Format gibt es hier, den Quellcode im Browser hier.

Das Assemblieren geht mit jedem AVR-Assembler. Der Assembler 2 im Studio ab 4.19 kann das, meiner (gavrasm) auch.

Beim Programmieren müssen die werksseitigen Fuse-Einstellungen nicht geändert werden.

Software-Ablauf

Die LED-Steuerung

LED-Anschlussreihe an den beiden Ports Die Steuerung der LEDs ist etwas komplizierter aufgebaut, weil die jeweilige vorherige rote LED noch anbleiben muss, wenn die Pulsweitenmodulation auf die nächste LED umgeschaltet werden muss.

Das Bild zeigt die Anschlussfolge der acht LEDs an den beiden Ports. Bei den betreffenden Binärkombinationen geht die jeweilige LED entweder in grün oder in rot an. Die Zeile Hex zeigt die auszugebende Bitkombination auf den Ports B bzw. D.

Um die vorherige LED ebenfalls anzuschalten, jeweils in rot, muss ab LED Nummer 2 die Bitkombination der davor davor stehenden roten LED addiert werden. Das ergibt die in PB und PD angegebenen Hexadezimalkombinationen. Ab der LED 5 wird PD verwendet. Da bei LED 5 die LED 4 rot werden muss, sind in diesem Fall sowohl PD als auch PB nicht Null.

Organisation des SRAM Die LED-Kombinationen 1 bis 8 Hier sind die Kombinationen der LEDs 1 bis 3 und 8 gezeigt, wie sie im SRAM stehen.

Die Tabelle im SRAM Um die Interrupt-Service-Routine nicht mit unnötigen und zeitintensiven Entscheidungen zu belasten, sind diese Bitkombinationen im SRAM einmalig erzeugt und gespeichert.

Beim Betrieb zeigt das Registerpaar Y auf die jeweils aktuelle LED, bei dem Umschalten auf die nächste LED werden dann jeweils vier zu Y addiert. Das Schema verwendet die zeitweilige Addition von Offsets zu Y (ldd r,Y+n), um jeweils zu Beginn jedes Zyklusses auf die rote Kombination zuzugreifen (Y und Y+1) und beim erfolgten Compare-Match dann auf die grüne (Y+2, Y+3).

Die Zeitsteuerung

PWM-Steuerung der LEDs Die Steuerung der Rot-Grün-Umschaltung erfolgt in PWM-Zyklen. Zum Beginn jedes Zyklusses wird die LED auf rot geschaltet, indem das erste Portbit auf Eins und das nachfolgende auf Null gestellt wird. Ist der aktuelle Vergleichswert erreicht (Compare Match), wird auf grün umgeschaltet. Bei 1 MHz, einem Vorteiler von 1 und einem CTC-Teilerwert von 61 (Vergleichswert: 60) wird eine PWM-Frequenz von 1.000.000 / 1 / 61 / 256 = 64,037 Hz erreicht. Das entspricht 15,616 Millisekunden pro PWM-Zyklus.

Dieser PWM-Zyklus wird 14 mal wiederholt. Der Compare-Zähler wird dabei jeweils von 0 auf 255 hochgezählt. Das ergibt exakt 15,616 / 1000 * 15 * 256 = 60 Sekunden. Bei meiner Betriebsspannung von 3 V und bei einem alten ATmega8 war es nötig, die 15 auf 14 zu korrieren, damit die Minuten stimmen.

Zu Beginn des Quellcodes wird TC2 initiiert: der Compare-Wert wird auf 60 eingestellt, der Wiederholzähler in X auf 14 und der Timer wird im CTC-Modus mit einem Vorteiler von 1 gestartet. Alles folgende läuft in der Interrupt-Service-Routine des TC2-OC ab.

Der Vergleichswert von 60 bedeutet auch, dass alle Interrupt-Service-Routinen innerhalb dieser Zeitspanne abgearbeitet sein müssen, weil es sonst zu verpassten Interrupts der LED-Zeitsteuerung kommen würde. Im Quellcode und im Flussdiagramm sind daher die Zeitbedarfe ermittelt. Bei 1 MHz Takt sind alle Anforderungen eingehalten, es besteht daher kein Anlass für einen beschleunigten Takt, der ATmega8 kann mit 1 MHz korrekt arbeiten.

Flussdiagramm der Zeitsteuerung mit der OC2-ISR

Flussdiagramm der TC2-OC-ISR Dies ist die gesamte OC-Routine. Sie beginnt mit dem Vergleich des Registers rPwmCnt mit dem Vergleichswert in Register rPwmCmp. Sind beide gleich, dann wird die LED auf Grün geschaltet.

Dann wird der PWM-Zähler in Register rPwmCnt erhöht. Ist dieser nicht Null, wird die ISR beendet.

Erreicht er 256 (= 0), dann wird der PWM-Wiederholzähler in X um Eins erniedrigt. Ist dieser nicht Null, wird der nächste Zyklus mit gesetzter roter LED gestartet (Restart mit Y und Y+1).

Wenn der PWM-Wiederhol-Zähler Null geworden ist, wird er erneut mit 14 gestartet und der Vergleichswert der PWM in Register rPwmCmp um Eins erhöht. Ist dieses Register danach nicht Null, wird der nächste Zyklus ebenfalls mit roter LED neu gestartet.

Wenn das Compare-Register Null erreicht, dann wird der Zeiger Y in das SRAM um vier erhöht. Falls nicht das Ende des SRAM-Puffers erreicht wird, wird die nächste Melodie abgespielt (siehe OC1A-ISR) und mit der nächsten roten LED begonnen, auf die jetzt der Zeiger Y zeigt.

Falls das Ende erreicht ist, wird der Timer TC2 abgeschaltet und dessen Interrupt-Enable-Bit ebenfalls (das OCIE1A-Bit bleibt aktiv um auch noch die letzte Melodie fertig abzuspielen).

Melodien abspielen

Flussdiagramm der Tonausgabe mit OCR1A Das Abspielen von Melodien verwendet den 16-Bit-Zähler TC1 im CTC-Modus. Mit jedem dieser Interrupts wird der Lautsprecher-Ausgang auf Eins bzw. auf Null gestellt.

Um die Teilerrate von TC1 dafür auf einen bestimmten Ton einzustellen, enthält die Software eine Tonleitertabelle in Konstanten ab dem Label Gamut:. Hier sind alle Töne der Tonleiter von 27 Hz bis 18,794 kHz in 9 1/2 Oktaven als Konstanten definiert. Für Kammerton A4 ist dort ein Teilerwert von 1.136 (CTC-Compare-A = 1.135) angegeben. Das bedeutet, dass der TC1-Teiler eine Frequenz von 1.000.000 / 1.136 / 2 = 440,14 Hz erzeugt. Die 2 resultiert aus der Tatsache, dass ein Ton aus jeweils zwei Zyklen (High und Low) besteht, der Compare-Wert also nur für eine Teilschwingung ausgelegt ist.

Zwei Tonhöhen sind noch besonders:
  1. cPs: Dieser Ton stellt eine Pause dar, d.h. der entsprechende Ton von 64 Hz wird zwar vom Timer erzeugt, aber am Lautsprecher nicht ausgegeben: er schaltet dazu das Bit bQuiet im Flaggenregister rFlag auf Eins und unterdrückt damit die Ausgabe des Tons. Das Vorliegen des cPs-Tons wird an dessen LSB-Fingerprint erkannt, es ist nicht notwendig, auch das MSB zu überprüfen, wie die Tabelle zeigt.
  2. cEnd: Dieser Ton schaltet die weitere Tonausgabe ab. Damit kann man die Melodien voneinander trennen. Das Abspielen wird zu jeder vollen Minute einfach aus der Zeitmessroutine heraus neu gestartet, der Melodiezeiger Z behält die Adresse der nächsten Melodie hinter dem cEnd-Zeichen. Zur Erkennung muss nur das LSB ausgewertet werden, da es keine weiteren Töne mit Null-LSB gibt.
Da jeder Ton eine unterschiedliche Anzahl an Durchläufen machen muss, um die gleiche Zeitdauer zu erreichen, sind diese Dauern in den Konstanten ab dem Label Durations: angegeben. Alle diese Dauern beginnen mit n, zum Kammerton A4 gehören die Tonhöhe cA4 und die Dauer nA4. Alle Dauern dieser Tabelle sind auf auf eine Dauer von vier Sekunden normiert (vier Schläge, wie der Musiker so sagt). Bei ganzen Noten wird die Notendauer nicht geteilt, bei Viertel durch 4, bei drei Achteln mal 3 durch 8, bei Sechzehntel durch 16. Durch Multiplikation mit drei und Teilen durch 8 kann man auch 3/8-Noten erzeugen. Achtung! Bei den ganz niedrigen Noten wie der Pause sind Sechzehntel Dauer noch in Ordnung, aber noch tiefer kann es beim Dividieren Null geben, dann dauert der Ton fälschlich ganz, ganz lange an.

Eine weitere Grenze betrifft die maximal mit dieser Methode erzeugbare Frequenz. Wie Du aus dem Fließdiagramm der OC1A-ISR siehst, braucht die Routine maximal 40 Taktzyklen. Damit wären Damit wären die Töne G8 und höher nicht mehr erzeugbar. Glücklicherweise braucht die Hälfte der Interrupts nur 18 Taktzyklen, weil sie nur die Polarität des Lautsprecherausgangs umkehren müssen. Jeder Interrupt, der mit der hohen Anzahl Widerholungen zu tun hat, braucht nur 21 Taktzyklen, und nur ein einziger am Ende des Tons braucht 40. Also sind 12,5 (G8), 14 (E9), 16 (C9) und 17 kHz (D9) locker erzeugbar. Nur bei E9 kann ich für nichts garantieren. Da mein Lautsprecher schon ab 12 kHz nichts mehr Hörbares von sich gibt, kann ich die ordnungsgemäße Funktion bei diesem Ton auch gar nicht mehr verifizieren.

Mit den Konstanten können Melodien als Tabellen im Flash-Memory erzeugt werden. Dies hier ist z. B. die Internationale als Tabelle:

Internationale:
  ;   Völ-                      ker
  .dw cH3,nH3*3/16, cPs,nPs/16, cA3,nA3/16, cPs,nPs/16
  ;   hört                   die                      Sig                    na-                    le
  .dw cG2,nG2/2, cPs,nPs/16, cD2,nG2*3/8, cPs,nPs/16, cH1,nH1/8, cPs,nPs/16, cE2,nE2/2, cPs,nPs/16, cC2,nC2/4,cPs,nPs/8
  ; Auf                         zum                     letz-                  ten                      Ge-                    fecht!
  .dw cA3,nA3*3/16, cPs,nPs/16, cG2,nG2/16, cPs,nPs/16, cF2,nF2/2, cPs,nPs/16, cE2,nE2*3/8, cPs,nPs/16, cD2,nD2/8, cPs,nPs/16, cD2,nD2/2,cPs,nPs/8
  ;   Die                    In-                      ter-                   na-                    tio-       na-                    le
  .dw cD2,nD2/4, cPs,nPs/16, cH3,nH3*3/8, cPs,nPs/16, cH3,nH3/8, cPs,nPs/16, cA3,nH3/4, cPs,nPs/16, cD2,nD2/4, cPs,nPs/16, cG2,nG2/2, cF2,nF2*3/8,cPs,nPs/8
  ;   er-                       kämpft                 das                    Men-                   schen-                 recht.
  .dw cF2,nF2*3/16, cPs,nPs/16, cE2,nE2/8, cPs,nPs/16, cD2,nD2/8, cPs,nPs/16, cE2,nE2/4, cPs,nPs/16, cA3,nA3/4, cPs,nPs/16, cA3,nA3/2
  .dw cEnd

Jede zu spielende Note besteht also aus zwei Worten: das erste gibt die Tonhöhe an (cXn, cPs=Stumm), das zweite die Tondauer (nXn). Das ist ein bisschen umständlich, kann aber alles an Noten und Pausen kodieren, was so vorkommen kann.

Fehlt zwischen zwei Noten die Pause (cPs und nPs nicht angegeben), dann hängen beide Töne unmittelbar zusammen. Damit kann man herrliche auslaufende Kreissägen oder startende kreischende Motorsägen programmieren. Im Flash ist dafür noch genug Platz. Man achte nur darauf, dass jede Melodie nicht länger als eine Minute dauert, sonst gibt es Kuddelmuddel.

cEnd schließt die Melodie ab und schaltet den Lautsprecher stumm. Die wird dann erst wieder zur vollen Minute gestartet.

Rechts ist der gesamte Ablauf der Tonausgabe im Flussdiagramm zu sehen.

Eieruhr-Video



Link zur ogg-Video-Datei und zur MP4-Datei.

Zum Seitenfang


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