Pfad: Home => AVR-DE => Anwendungen => Vielfachtimer tn24
Vielfachtimer klein AVR-Anwendungen

Vielfachtimer mit ATtiny24
Logo

Vielfachtimer mit ATtiny24 und 12 LEDs

Hier wird ein Timer beschrieben, mit dem Zeiten zwischen 5 Sekunden und sieben Minuten in zwölf Stufen ausgewählt werden können (grüne LEDs) und auf Knopfdruck gestartet werden (rote LEDs). Auswahl und Start/Stop des Timers werden mit drei Tasten kontrolliert.

Diese gesamte Seite als PDF (18 Seiten, 742 kB).

Abspielen eines Videos.

Seitenanfang Hardware Aufbau Software

1 Hardware

Vielfachtimer Schaltbild Das ist es: Die LED-Ströme in dieser Schaltung wurden gemessen und liegen zwischen 10 mA für eine grüne LED und 12 mA für eine rote LED. Das reicht unter normalen Umständen völlig aus. Durch den Blinkmodus wird der durchschnittliche Strombedarf zusätzlich halbiert. Der Betriebsstrom für den Controller liegt bei 0,1 mA, weil er interrupt-gesteuert angesteuert wird und die überwiegende Betriebszeit im Schlafmodus auf Timer- und Tasten-Ereignisse wartet.


Seitenanfang Hardware Aufbau Software

2 Aufbau

2.1 Gedruckte Platine

Multitimer gedruckte Platine Das ist das Layout der 45-mal-53 mm großen gedruckten Platine. Die Maße wurden so gewählt, damit sechs davon auf eine Euro-Platine mit 160-mal-100 mm passen.

Multitimer Platinenbestueckung So sind die Bauteile auf der Platine zu bestücken.

Multitimer Bohrplan Platine Das ist der Bohrplan für die Platine. Alle unbeschrifteten Löcher sind vom Durchmesser 0,8 mm.

2.2 Montage

Multitimer von oben gesehen Das ist der Blick auf das Teil, wie es aus der Platzierung der Bauelemente auf der Platine resultiert. Die Taster und der Schalter sind für die Bedienung mit der rechten Hand ausgelegt (sorry, Linkshänder).

Multitimer Seitenansicht Das ist die Seitenansicht mit Bemaßung. Es zeigt die Plexiglas®-Platten auf der Ober- und Unterseite und wie der Controller, die LEDs, die Taster und die beiden AAA-Batterien reinpassen. Das Batteriegehäuse ist mit einem kurzen Stück Zwillingslitze von unten her an die Platine gelötet. Durch Abschrauben der unteren Plexiglas®-Platte kann die Batterie leicht gewechselt werden.
Multitimer Platine bestueckt So sieht die Leiterplatte mit den montierten Komponenten aus.

Multitimer Bohrplan Abdeckung Das ist der Bohrplan für die Abdeckung.


Seitenanfang Hardware Aufbau Software

3 Software

Die Software ist komplett in Assembler geschrieben, um vollen Zugriff auf die zeitlichen Abläufe zu erreichen und minimalen Batteriestromverbrauch. Der Controller wird zu mehr als 99,9% im Schlafmodus betrieben, wird nur beim 0,1-Sekunden-Interrupt und bei Tastendrücken aus dem Schlafmodus geholt. Das Gerät schaltet nach 10 Sekunden die Leuchtdioden ganz aus. Danach liegt der Strombedarf ungefähr bei der Batterie-Selbstentladungsrate.

Die folgenden Kapitel zeigen die Struktur der Software und wie sie funktioniert:
  1. Kapitel 3.1 liefert Links zum Quellcode im Assembler- und im HTML-Format.
  2. Kapitel 3.2 stellt die Hardware-Testoptionen vor, die im Quellcode eingeschaltet werden können,
  3. In Kapitel 3.3 wird der Tasteninterrupt PCINT1 dargestellt.
  4. Kapitel 3.4 zeigt die Erzeugung des 0,1-Sekunden-Interrupts.
  5. Kapitel 3.5 demonstriert wie der 0,1-Sekunden-Interrupt behandelt wird. und
  6. Kapitel 3.6 zeigt, wie der besondere Blinkrhythmus erzeugt wird.


Die Entscheidung, alle Abläufe innerhalb der beiden Interrupt-Service-Routinen zu bearbeiten, ist etwas ungewöhnlich, ist aber wegen der raschen Bearbeitung der Interrupts und der gemächlichen Abläufe ohne Probleme machbar.

3.1 Quellcode

Den Assembler-Quellcode gibt es hier zum Download und kann hier im Internetbrowser in HTML-Format angezeigt werden.

3.2 Hardware-Testoptionen

Für die Inbetriebnahme der fertig aufgebauten Schaltung enthält der Quellcode Testoptionen. Mit dem Schalter Debug_Leds = 1 werden die LEDs reihum nacheinander in grün und rot beleuchtet. Mit dem Schalter Debug_Switches = 1 werden die Schalter abgefragt und, falls gedrückt, auf drei der LEDs dargestellt.

3.3 Tasten-Interrupt PCINT1

Fliessdiagramm Tasten Dieser Interrupt tritt ein, sobald eine Taste gedückt oder losgelassen wird. Die Interrupt-Service-Routine muss Zuerst wird der Eingabeport, an den die Tasten angeschlossen sind, gelesen. Alle nicht mit Tasten verbundenen Eingangsbits werden mit Einsen ausgeodert und festgestellt, ob mindestens einer der drei Tasteneingänge auf Null ist. Ist das der Fall wird überprüft, ob das Torkelregister rTgl auf Null ist. Ist dies nicht der Fall, wird der Tastendruck nicht weiter ausgewertet (Prellunterdrückung, erst wenn die Karenzzeit in der 0,1-Sekunden-Routine abgelaufen ist).

Dann wird die Taste Run abgefragt. Ist diese gedrückt, wird die bRun-Flagge invertiert. Ist bRun danach gesetzt, wird der Zählerwert in rSecH:rSecL auf den gewählten Zeitwert gesetzt. In beiden Fällen wird die gewählte LED mit der Nummer in rSelect in die aktuell angezeigt LED rState kopiert und angezeigt.

Ist bRun aktiv (Zähler zählt abwärts) erfolgt keine Auswertung der beiden ausstehenden Tasten Down und Up. Lählt der Timer nicht, wird bei den Tasten Down und Up überprüft ob der ausgewählte Wert der LED-Nummer bei Eins (Down-Taste) oder beim Maximalwert (Up-Taste) steht. Ist das nicht der Fall, wird der rSelect-Wert erhöht bzw. erniedrigt.

In allen beiden Fällen wird die gewählte LED in rSelect angezeigt. In allen Fällen mit aktivem Tastendruck wird das Prellunterdrückungsregister rTgl auf seinen Neustartwert gesetzt und damit bis zum Ende der Karenzzeit Tastenreaktionen unterbunden.

Der Assembler-Quellcode der Routine kann auf der oben gelinkten Webseite oder im Quellcode selbst eingesehen werden.

3.4 0,1-Sekunden-Takterzeugung

Multitimer 0,1-Sekundenerzeugung Werksseitig läuft der ATtiny24 mit dem internen 8-MHz-RC-Oszillator, teilt dessen Frequenz mit dem Taktvorteiler CLKPR durch 8 und taktet den Controller und alle Timer mit 1 MHz Takt.

Der 16-Bit-Timer TC1 wird von dieser Software mit einem Vorteilerwert von 8 gestartet und in den CTC-Modus gebracht: beim Erreichen des Wertes im Vergleichsport A wird der Timer mit dem nächsten Taktimpuls auf Null gesetzt. Mit dem Vergleichswert von 12.499 ergibt sich ein Takt von 10 Hz.

Beim Erreichen des Compare-Werts in A wird der Compare-A-Interrupt ausgelöst.

3.5 0,1-Sekunden-Interrupt

TC1 0,1 Sekunden Fliessdiagramm Sieht kompliziert aus, besteht aber überwiegend aus einfachen Verzweigungen: das Ablaufdiagramm der 0,1-Sekunden-Interrupt-Service-Routine.

Zum Programmstart ist die Flagge bLedTest gesetzt und die Nummer der LED in rState wird einfach erhöht und die LED eingeschaltet. Das erfolgt bis zur 12-ten LED, dann wird bLedTest ausgeschaltet und die LED-Nummer wird auf den voraugewählten Zustand eingestellt. Ab jetzt beginnt der normale Ablauf.

Er beginnt mit der Abfrage, ob das Entprellregister rTgl Null ist. Wenn nicht, wird es um Eins vermindert.

Dann erfolgt die Abfrage, ob der Zähler gerade abwärts zählt oder steht (Flagge bRun). Ist das Zählen inaktiv, wird das 16-Bit-Sekundenregister in rSecH:rSecL um Eins vermindert. Erreicht es Null, wird die LED ausgeschaltet (Timeout).

Ist Zählen aktiv, wird der Zehntelsekunden-Zähler rCnt abwärts gezählt. Ist der nicht Null, wird der Zählerstand in rCnt mit dem Abschaltwert in rOff verglichen. Sind beide gleich, wird die LED ausgeschaltet.

Mit dem Erreichen von Null bei rCnt ist eine Sekunde um und der 16-Bit-Sekundenzähler in rCntH:rCntL wird um eine Sekunde vermindert. Ist dieser nicht Null, wird der Sekundenstand in umgewandelt und die erreichte LED aktiviert.

Wenn die Sekunden Null erreichen, wird die bRun-Flagge ausgeschaltet, die anzuzeigende LED-Nummer aus der Nummer der ausgewählten LED in rSelect entnommen, der Inaktivitäts-Abschaltwert in das Sekundenregister geladen und die LED in rState angezeigt.

Der gesamte Ablauf, einschließlich der Software-Multiplikation zum Berechnen des rOff-Wertes, bleibt unter einer halben Millisekunde und ist daher mit dem Zeitablauf verträglich, auch wenn während des Ablaufs der 0,1-Sekunden-Routine nicht auf Tastendruck-Interrupts reagiert werden kann.

Der resultierende Assembler-Code für diesen Ablauf kann im Quellcode besichtigt werden.

3.6 Blinkrhythmus

LED-Kontrolle Das hier erläutert die LED-Ansteuerung am Beispiel der LED5. Diese LED ist mit der grünen Anode am Portpin PA0 (über einen Widerstand), mit der roten Anode an Portpin PA4 angeschlossen. Um zu leuchten, müssen beide Richtungsbits (DDA0 und DDA4) als Ausgang (=1) geschaltet sein. Der Ausgangsport PORTA bestimmt dann die Farbe der LED: Mit PORTA0 High und PORTA4 Low leuchtet die LED grün, sind beide Bits umgekehrt ist sie rot.

Soll die LED ausgeschaltet werden, z. B. beim Blinken, wird einfach Null in den Richtungsport geschrieben. Soll die gleiche LED wieder eingeschaltet werden, wird der zuvor in das Register rDdr geschriebene Wert in den Richtungsport ausgegeben.

LED-Kontrolle in Assembler Das ist der nötige Assemblercode, um die LED in Abhängigkeit vom Zählzustand in der Flagge bRun entweder grün (bRun=0) oder grün (bRun=1) leuchten zu lassen: alle Lampen-Bits werden mit einem Exklusiv-Oder mit 0x7F einfach umgedreht (aus Nullen werden Einsen, aus Einsen werden Nullen).

Sind die 12 LED-Kombinationen aus Richtungs- und Output-Werten in einer Tabelle abgelegt, kann sogar für den Fall, dass einzelne LEDs falsch herum eingebaut wurden, einfach der Grün-Wert anders definiert werden und die Farben der LED sind wieder korrekt.

LED-An-Dauer zwischen 30 und 0 Im Zählmodus (hier für 30 Sekunden abwärts) zeigt die An-Dauer der LED an, wie nahe der Zählerstand zur nächsten LED ist:
LED-An-Dauer 120 bis 90 Das ist die LED-An-Dauer zwischen 120 und 90 Sekunden.

LED-An-Dauer-Berechnung Die Berechnung der An-Zeit der LED geht folgendermaßen (hier am Beispiel der Sekunden bei 13).

Der gesamte Abstand zwischen 20 und 10 Sekunden wird in 9 Abschnitte geteilt und mit 256 multipliziert (resultierender Faktor f - hier 230 - wird im Quellcode als Konstante abgelegt). f wird nach folgender Formel berechnet:
f = 9 * 256 / (Noben - Nunten)

und ist für die verschiedenen Zeitperioden und in jedem Fall kleiner als 256 (8-Bit).

Die zwischen der aktuellen Zeit (13 Sekunden) und der nächstniedrigen Zeit (10 Sekunden) Zeitraum (3 Sekunden) wird mit diesem Faktor multipliziert, ergibt in diesem Fall 690 oder hexadezimal 0x02B2. Durch Wegstreichen des niedrigen Bytes (0xB2) wird der Wert durch 256 geteilt. Das MSB wird um Eins erhöht (2 ==> 3) und bildet den Wert rOff. Die Formel für diese Berechnung lautet also:
N = (T - Nunten) * f / 256 + 1

Man beachte, dass bei der Division in jedem Fall abgerundet wird.

Erreicht der Wert der Zehntelsekunden (in Register rCnt) diesen Abschaltwert, wird die LED abgeschaltet.

Im Quellcode ist diese Berechnung in der Unterroutine Sec2Led zu finden. Sie berechnet aus der Zeitinformation in rSecH:rSecL Die dafür nötigen Werte sind als Tabellen im Flash abgelegt, z. B. die Dauern bei den verschiedenen LEDs:

;
; Dauertabelle
LedDur:
.dw 0,5,10,20,30
.dw 60,90,120,180
.dw 240,300,360,420
.dw 65535 ; Ende der Tabelle
;
; Multiplikatorentabelle
MultTab:
.db 0,0,0,230,230,77,77,77,38,38,38,38,38,1
;
; Zehnertabelle (fuer 10..1)
TenTable:
.db 0,2,4,6,8,9
;
; Led-Tabelle der Ports
;   1. Byte: PORTA, 2. Byte: DDRA
LedTable:
.db 0b00000000,0b00000000 ; #0, aus
.db 0b00010000,0b00010001 ; #1, LED 5 gruen
.db 0b00010000,0b00010010 ; #2, LED 10 gruen
.db 0b00010000,0b00010100 ; #3, LED 20 gruen
.db 0b00010000,0b00011000 ; #4, LED 30 gruen
.db 0b00100000,0b00100001 ; #5, LED 60 gruen
.db 0b00100000,0b00100010 ; #6, LED 90 gruen
.db 0b00100000,0b00100100 ; #7, LED 120 gruen
.db 0b00100000,0b00101000 ; #8, LED 180 gruen
.db 0b01000000,0b01000001 ; #9, LED 240 gruen
.db 0b01000000,0b01000010 ; #10, LED 300 gruen
.db 0b01000000,0b01000100 ; #11, LED 360 gruen
.db 0b01000000,0b01001000 ; #12, LED 420 gruen
;

Diagramm LED-An-Dauer 420 bis 1 Das Ergebnis der Berechnungen für den gesamten Zeitraum zeigt das Diagramm.

Angezeigt sind die Nummern der LEDs (linke Skala, in blau) und der Abschaltwert in Zehntelsekunden (rechte Skala, rot).
Seitenanfang Hardware Aufbau Software


Lobpreisungen, Fehlerberichte, Geschimpfe und Spam bitte via Kommentarseite an mich.

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