Gizmo wrote:
> erst einmal Danke für Deine Hilfe.
>
> könntest Du mir das mit dem Timer genauer erläutern ?
Ein Timer ist erst mal einfach nur eine im µC eingebaute
'Variable'. Diese Variable wird ständig erhöht. Wie schnell
sie erhöht wird, wird mit dem Vorteiler des Timers eingestellt.
Ein Zähler ist entstanden, der ständig vor sich hinzählt.
Soweit so gut und nicht besonders aufregend.
Aber: Dieser Zähler hat wie jede andere 'Variable' einen
Datentyp. Es gibt 8-Bit Zähler und 16-Bit Zähler. Daraus
resultiert, dass es eine Obergrenze gibt, bis zu der dieser
Zähler zählen kann. Ist die Obergrenze erreicht, dann passiert
ein Overflow und der Zähler beginnt wieder bei 0.
Und genau da beginnt die Sache interesant zu werden. Denn dieser
Overflow kann einen Interrupt auslösen. Als Folge dieses Interrupts
wird ein Interrupt Handler angesprungen, der dann irgendetwas
machen kann (während der Zähler immer noch nach wie vor still
und heimlich vor sich hinzählt).
Alles was man dazu tun muss, ist:
* Dem Timer einen Vorteiler einstellen.
Dadurch, dass ein Vorteiler aktiviert wird, beginnt der
Timer bereits mit seiner Zählerei.
Der Vorteiler wird eingestellt, indem man in bestimmten,
dem Timer zugeordneten, Steuerregistern bestimmte Bits
setzt. Welche das sind -> Datenblatt des Prozessors
* In weiteren Steuerregistern des Timers, gibt es Bits für
verschiedene Eregnisse, die dem Timer zustossen können, wie
zb. das ein Overflow passiert. Wenn man dort das richtige
Bit setzt, dann löst der Timer einen Interrupt aus
Welche das sind -> Datenblatt des Prozessors
* Interrupts muessen generell freiggeben sein.
-> sei() aufrufen
* Dann muss man noch einen Interrupt Handler schreiben,
damit es auch eine Aktion gibt, die bei Auftreten dieses
speziellen Interrupts ausgeführt werden soll
Und das wars dann auch schon.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Die_Timer.2FCounter_des_AVR
Am Beispiel eines Mega8:1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 |
|
4 | volatile uint8_t Cnt;
|
5 |
|
6 | ISR( TIMER0_OVF_vect ) // wird aufgerufen wenn der Timer 0
|
7 | { // einen Overflow Interrupt auslöst
|
8 | Cnt = Cnt + 1;
|
9 |
|
10 | if( Cnt == 5 ) { // nach dem 5-ten Interrupt
|
11 | PORTB = PORTB ^ 0xFF; // alle Pins am Port B umdrehen
|
12 | Cnt = 0;
|
13 | }
|
14 | }
|
15 |
|
16 | int main()
|
17 | {
|
18 | DDRB = 0xFF;
|
19 | PORTB = 0xAA;
|
20 |
|
21 | TCCR0 = ( 1 << CS02 ) | ( 1 << CS01 ); // Vorteiler auf 1024
|
22 | TIMSK = ( 1 << TOIE0 ); // Interrupt bei Overflow vom Timer 0
|
23 |
|
24 | sei();
|
25 |
|
26 | while( 1 )
|
27 | ;
|
28 | }
|
Das lässt ein paar Leds am Port B blinken. Wie schnell sie blinken
hängt von der Taktfrequenz des µC ab.
Angenommen dein µC läuft mit 1Mhz.
Dann gehen diese 1Mhz auch an den Vorteiler. Der teilt durch 1024
1000000 / 1024 = 976
d.h. der Timer wird 976 mal in der Sekunde um 1 erhöht.
Da er, als 8 Bit Timer, bis 255 zählen muss ehe dann ein Overflow
passiert, bedeutet das, dass
976 / 256 = 3.8
Overflow in einer Sekunde vorkommen. Dementsprechend wird auch
die ISR 3.8 mal in der Sekunde aufgerufen.
Da aber in der ISR bis 5 gezählt wird, ehe der Port umgeschaltet
wird, bedeutet das, dass
3.8 / 5 = 0.76
die angenommenen Led am Port B mit einer Freuqenz von 0.76 Hz
umgeschaltet werden. Sie blinken also mit einer Frequenz von 0.38Hz
oder ( 1 / 0.38 = 2.6 ) alle 2.6 Sekunden.