Difference between revisions of "AVR Embedded Tutorial - Timer, Counter/de"
m (Fixed template loop; modded categories to German; added language category) |
|||
(One intermediate revision by one other user not shown) | |||
Line 1: | Line 1: | ||
− | {{ | + | {{LanguageBar}} |
+ | |||
=Timer / Counter= | =Timer / Counter= | ||
==Titel== | ==Titel== | ||
+ | |||
Hier geht es nicht darum, alle Register zu verstehen. Dies sollte nur ein praktisches Beispiel sein, wie man es in FPC/Lazarus umsetzt. | Hier geht es nicht darum, alle Register zu verstehen. Dies sollte nur ein praktisches Beispiel sein, wie man es in FPC/Lazarus umsetzt. | ||
+ | |||
Genauere Details gibt es hier: | Genauere Details gibt es hier: | ||
+ | |||
* https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR | * https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR | ||
==Beispiel, LEDs über Timer steuern== | ==Beispiel, LEDs über Timer steuern== | ||
+ | |||
Dieses Beispiel zeigt, wie man die beiden Timer eines ATtiny2313 verwenden kann. | Dieses Beispiel zeigt, wie man die beiden Timer eines ATtiny2313 verwenden kann. | ||
Jeder Timer steuert eine LED an, welche an Bit 0 und 1 des PortD sind. Dabei sollte die LED an PD0 etwas schneller blinken. | Jeder Timer steuert eine LED an, welche an Bit 0 und 1 des PortD sind. Dabei sollte die LED an PD0 etwas schneller blinken. | ||
===Beispiel Code=== | ===Beispiel Code=== | ||
+ | |||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
program Project1; | program Project1; | ||
Line 17: | Line 23: | ||
====Timer 0 Interrupt==== | ====Timer 0 Interrupt==== | ||
+ | |||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
− | + | procedure Timer0_Interrupt; public Name 'TIMER0_COMPA_ISR'; interrupt; | |
const | const | ||
t = 10; // LED sollte nur bei jedem 10. Durchlauf umschalten. | t = 10; // LED sollte nur bei jedem 10. Durchlauf umschalten. | ||
Line 36: | Line 43: | ||
====Timer 1 Interrupt==== | ====Timer 1 Interrupt==== | ||
+ | |||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
− | + | procedure Timer1_Interrupt; public Name 'TIMER1_COMPA_ISR'; interrupt; | |
const | const | ||
t = 500; // LED sollte nur bei jedem 500. Durchlauf umschalten. | t = 500; // LED sollte nur bei jedem 500. Durchlauf umschalten. | ||
Line 55: | Line 63: | ||
====Timer initialisieren==== | ====Timer initialisieren==== | ||
+ | |||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
− | |||
begin | begin | ||
// -- Interrupt unterbinden. | // -- Interrupt unterbinden. | ||
Line 85: | Line 93: | ||
==Timer extern getaktet== | ==Timer extern getaktet== | ||
+ | |||
Einen Timer kann man auch extern getaktet werden. Folgendes Beispiel demonstriert dies mit einem Atmega328. | Einen Timer kann man auch extern getaktet werden. Folgendes Beispiel demonstriert dies mit einem Atmega328. | ||
Zum extern takten gibt es folgende Pins am AVR: | Zum extern takten gibt es folgende Pins am AVR: | ||
+ | |||
* '''T0''' taktet Timer 0 | * '''T0''' taktet Timer 0 | ||
* '''T1''' taktet Timer 1 | * '''T1''' taktet Timer 1 | ||
+ | |||
Der Timer 2 kann '''nicht''' extern getaktet werden. | Der Timer 2 kann '''nicht''' extern getaktet werden. | ||
+ | ===Beispiel einer Uhr=== | ||
− | |||
Für eine exakte Uhr ist ein Quarz/Oszilator mit 4.194304MHz geeignet. Dieser lässt sich gut in einer 2er Potenz teilen, so das man auf einen Sekunden-Takt kommt. | Für eine exakte Uhr ist ein Quarz/Oszilator mit 4.194304MHz geeignet. Dieser lässt sich gut in einer 2er Potenz teilen, so das man auf einen Sekunden-Takt kommt. | ||
Hier wird der Timer 0 extern getaktet, dazu muss man den Oszilator an '''T0''' (PD4) anschliessen. | Hier wird der Timer 0 extern getaktet, dazu muss man den Oszilator an '''T0''' (PD4) anschliessen. | ||
====Timer Interrupt==== | ====Timer Interrupt==== | ||
+ | |||
Jeder 16384 Aufruf des Interupts ist eine Sekunde. | Jeder 16384 Aufruf des Interupts ist eine Sekunde. | ||
+ | |||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
− | + | procedure Timer0_Interrupt; public Name 'TIMER0_OVF_ISR'; interrupt; | |
const | const | ||
cl = 16384 shr 1; // 4194304 / 256 / 2; | cl = 16384 shr 1; // 4194304 / 256 / 2; | ||
Line 121: | Line 134: | ||
====Timer inizialisieren==== | ====Timer inizialisieren==== | ||
+ | |||
Der springende Punkt ist der Wert bei '''TCCR0B''', dieser sagt, das der Timer extern getaktet wird. | Der springende Punkt ist der Wert bei '''TCCR0B''', dieser sagt, das der Timer extern getaktet wird. | ||
+ | |||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
begin | begin | ||
Line 139: | Line 154: | ||
==Stolperfalle== | ==Stolperfalle== | ||
+ | |||
Die Namen der Proceduren können abweichen, ein Beispiel: | Die Namen der Proceduren können abweichen, ein Beispiel: | ||
+ | |||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
// ATtiny2313 | // ATtiny2313 | ||
Line 147: | Line 164: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | = Siehe auch = | |
− | * Übersichtseite [[AVR Embedded Tutorial/de]] | + | |
+ | * Übersichtseite [[AVR Embedded Tutorial/de|AVR Embedded Tutorial]] | ||
Autor: [[User:Mathias|Mathias]] | Autor: [[User:Mathias|Mathias]] | ||
− | [[Category: | + | [[Category:AVR/de]] |
− | [[Category: | + | [[Category:Arduino/de]] |
− | [[Category: | + | [[Category:Embedded/de]] |
+ | [[Category:Tutorials/de]] | ||
+ | {{AutoCategory}} |
Latest revision as of 01:35, 24 January 2020
│ Deutsch (de) │ English (en) │
Timer / Counter
Titel
Hier geht es nicht darum, alle Register zu verstehen. Dies sollte nur ein praktisches Beispiel sein, wie man es in FPC/Lazarus umsetzt.
Genauere Details gibt es hier:
Beispiel, LEDs über Timer steuern
Dieses Beispiel zeigt, wie man die beiden Timer eines ATtiny2313 verwenden kann. Jeder Timer steuert eine LED an, welche an Bit 0 und 1 des PortD sind. Dabei sollte die LED an PD0 etwas schneller blinken.
Beispiel Code
program Project1;
Timer 0 Interrupt
procedure Timer0_Interrupt; public Name 'TIMER0_COMPA_ISR'; interrupt;
const
t = 10; // LED sollte nur bei jedem 10. Durchlauf umschalten.
z: integer = 0; // Zähler für Leerdurchläufe.
begin
TCNT0 := 128; // Speed halbieren 0 = langsam (default)
Inc(z);
if (z = t) then begin
PORTD := PORTD or (1 shl 0); // LED Pin0 ein
end;
if (z = t shl 1) then begin
PORTD := PORTD and not (1 shl 0); // LED Pin0 aus
z := 0;
end;
end;
Timer 1 Interrupt
procedure Timer1_Interrupt; public Name 'TIMER1_COMPA_ISR'; interrupt;
const
t = 500; // LED sollte nur bei jedem 500. Durchlauf umschalten.
z: integer = 0; // Zähler für Leerdurchläufe.
begin
Inc(z);
if (z = t) then begin
PORTD := PORTD or (1 shl 1); // LED Pin1 ein
end;
if (z = t shl 1) then begin
PORTD := PORTD and not (1 shl 1); // LED Pin1 aus
z := 0;
end;
end;
Timer initialisieren
begin
// -- Interrupt unterbinden.
asm cli end;
// -- PD0 und PD1 auf Ausgabe stellen.
DDRD := %00000011;
// -- Timer0 initialisieren.
TCCR0A := 0;
TCCR0B := %101; // CPU-Takt / 1024
TIMSK := TIMSK or (1 shl OCIE0A); // Timer0 soll Interrupt auslösen.
// -- Timer1 initialisieren.
TCCR1A := 1; // CTC-Modus
TCCR1B := %010; // CPU-Takt / 8
TIMSK := TIMSK or (1 shl OCIE1A); // Timer1 soll Interrupt auslösen.
// -- Interrupt aktivieren.
asm sei end;
// -- Hauptschleife
repeat
// Mache Irgendwas.
until 1 = 2;
end.
Timer extern getaktet
Einen Timer kann man auch extern getaktet werden. Folgendes Beispiel demonstriert dies mit einem Atmega328. Zum extern takten gibt es folgende Pins am AVR:
- T0 taktet Timer 0
- T1 taktet Timer 1
Der Timer 2 kann nicht extern getaktet werden.
Beispiel einer Uhr
Für eine exakte Uhr ist ein Quarz/Oszilator mit 4.194304MHz geeignet. Dieser lässt sich gut in einer 2er Potenz teilen, so das man auf einen Sekunden-Takt kommt. Hier wird der Timer 0 extern getaktet, dazu muss man den Oszilator an T0 (PD4) anschliessen.
Timer Interrupt
Jeder 16384 Aufruf des Interupts ist eine Sekunde.
procedure Timer0_Interrupt; public Name 'TIMER0_OVF_ISR'; interrupt;
const
cl = 16384 shr 1; // 4194304 / 256 / 2;
zaehler: UInt16 = 0; // Zählt bis cl erreicht ist.
begin
Inc(zaehler);
// Nach einer halben Sekunde LED ausschalten.
if zaehler = cl then begin
PORTB := PORTB and not (1 shl 5);
end;
// Sekunde ist erreicht.
if zaehler >= cl shl 1 then begin
PORTB := PORTB or (1 shl 5);
zaehler := 0; // Zähler zurücksetzen.
end;
end;
Timer inizialisieren
Der springende Punkt ist der Wert bei TCCR0B, dieser sagt, das der Timer extern getaktet wird.
begin
DDRB := 1 shl 5; // Pin PD5 auf Ausgabe
TCCR0A := %00; // Normaler Timer
TCCR0B := %111; // Clock / Externer Pin TO, steigende Flanke.
TIMSK0 := (1 shl TOIE0); // Timer 0 Interrupt aktivieren.
asm sei end; // Interrupts einschalten.
repeat
// Hier kann die Zeit auf ein Display ausgegeben werden.
until 1 = 2;
end.
Stolperfalle
Die Namen der Proceduren können abweichen, ein Beispiel:
// ATtiny2313
procedure Timer0_Interrupt; public Name 'TIMER0_COMPA_ISR'; interrupt;
// ATtiny44
procedure Timer0_Interrupt; public Name 'TIM0_COMPA_ISR'; interrupt;
Siehe auch
- Übersichtseite AVR Embedded Tutorial
Autor: Mathias