PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Timer vom ATMega8



seitenmaster
25.08.2004, 11:05
Hi,
ich habe mittlerweile schon ziemlich viel hier im Forum über die Timer gesehen,aber nichts hat so richtig geholfen.
Ich habe einen ATMega8 und möchte den Timer nutzen. Zu Hause arbeitet mein Controller mit einem Takt von 4MHz (extern).
Wie initialisiere ich den Timer in C/C++ und kann ihn beispielsweise auf eine Sekunde einstellen?

seitenmaster
25.08.2004, 14:56
Das gibts doch nicht!! Ist das so schwer, dass hier keiner eine Antwort kennt??

Frank
25.08.2004, 15:32
Ein Beispiel:


/*Blinkende LEDs im Sekundentakt 4MHz/2^16/64=1Hz --> 4MHz/16bit/Prescaler*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

volatile char count;

SIGNAL (SIG_OVERFLOW1) {
if (count == 1) {
PORTB = 0xFF;
count--;
return;
}
if (count == 0) {
PORTB = 0x00;
count++;
return;
}
}

void timer (void) {

TIMSK = _BV(TOIE1); //Timer Overflow Interrupt enable
TCNT1 = 0; //Rücksetzen des Timers
TCCR1B = _BV(CS11) | _BV(CS10); //Prescaler 64
sei ();
}

int main (void) {
DDRB = 0xff;
timer ();
for (;;) {}
}

Quelle:
http://www.mc-project.de/
Auf der Seite gibts weitere nette C-Beispiele

seitenmaster
26.08.2004, 08:25
Danke für den Tipp mit der Seite. Ich habe den Quelltext zwar noch nicht verstanden, aber der ist da ja scheinbar auch erklärt.

Warum blinkt es im AVR-Studio im Simulator nicht?

seitenmaster
26.08.2004, 08:53
Das ist noch zum verrücktwerden!!
Also ich steig nicht so richtig durch,der Timer macht mir echt Schwierigkeiten. Das Problem ist, im Simulator klappts nicht (kann auch sein das ich nur zu blöd bin), naja zumindest alles mit Timer geht da irgendwie nicht und Ich finde irgendwie viel zu wenig darüber im Netz.
Also wenn jemand ne Seite kennt, die mir helfen könnte(allein fürs Verständnis reciht), dann schreibt mir bitte mal hier den Link.

Frank
26.08.2004, 10:18
Ob man Timer im AVR-Studio simulieren kann weiss ich nicht. Jedenfalls halte ich es für einfacher erste Timer-Experimente mit dem echten Controller zu machen. Hier hilft auch das Datenblatt des Mega8 weiter. Wichtig ist das du die Bedeutung der Register verstehst.

Sehr hilfreich ist hier auch das AVR Buch von Roland Walter.

seitenmaster
26.08.2004, 10:21
Danke für die Tipps. Das ist es ja was ich verstehen will,erstmal die Bedeutungen. Schade,aber naja dann muss ich das heute Abend machen mit den Timerexperimenten,da ich an der Arbeit bin :-)

Gibts das Buch auch online, als pdf oder so?

26.08.2004, 10:56
Nein, aber die Seiten:
http://www.mc-project.de/
http://www.rowalt.de/mc/index.htm

seitenmaster
26.08.2004, 12:43
ja danke ,also die erste kenne ich, die hilft aber nicht viel und die zwiete bringt nicht viel weil ich es in c machen will.

26.08.2004, 13:12
Dann erkläre doch mal bitte, was du an meinem Programm genau nicht verstehst. Wo genau hängt es denn bei dir. Möchtest du etwas spezielles mit einem Timer realisieren?
Da ich mich leider nicht mehr ganz in die Lage eines Einsteigers hineinversetzen kann, wäre mir eine diesbezügliche Auskunft lieb. Dann würde ich auch die Rubrik "Timer" um ein paar Erklärungen ergänzen.

Gruß Alex

seitenmaster
26.08.2004, 13:21
ok gut,danke.
Also ich will einfach zum verständins mal ein kleines Programm in C schreiben, welches beispielsweise eine LED am Pin 0 an Port B alle 2 Sekunden ein bzw. aus schaltet.


Dazu muss ich wissen wie ich den Timer initialisiere, am besten noch für was die einzelnen initialisierungsschritte gut sind und wie ich den Timer aktiviere und wieder deaktiviere.

Das wars im Grunde schon, darauf könnte ich dann aufbauen.

26.08.2004, 14:06
Timer Initialisierung:

Bsp.: Verwendung von Timer1

TIMSK |= _BV(TOIE1);
//aktivieren des Überlaufinterrupts von Timer1

Nun muss man ausrechnen, wie man auf die 2s kommt (ich nehme mal 4MHz Takt an). Als Prescaler (Vorteiler) verwende ich mal exemplarisch 1024, du kannst auch einen anderen nehmen, musst dann nur die folgende Rechnung abändern.

TCCR1B = _BV(CS12) | _BV(CS10); //Prescaler definieren

Mit diesem Prescaler erhält man nun eine Zählfrequenz von 4MHz/1024 = 3,906kHz, also dauert ein Zählschritt dann 1/3,906kHz = 256us.
Um auf 2s zu kommen, muss der MC also 2s/256us = 7812,5 Zählschritte machen.
Das Timer1 ein 16-Bit Timer ist, musst du ihn also immer mit 2^16-7812 = 57723 vorladen.

TCNT1 = 57723; //Zählregister vorladen

Zuletzt musst du Interrupts noch global zulassen.

sei ();

Das LED-Blinken würde ich dann, wie oben bereits demonstriert, in der ISR ausführen lassen.

Gruß, Alex

26.08.2004, 14:09
Achso, deaktivieren geht einfach durch Löschen der CSxx-Bits, oder zurücksetzen von TOIE1 oder falls du keine anderen Interrupts mehr verwendest mittels cli ().

Gruß, Alex

26.08.2004, 14:11
Und irgendwie geht die Uhr hier im Forum falsch, habe meinen Beitrag 15:12 Uhr verfasst ...

seitenmaster
26.08.2004, 15:15
Hier z.B. scheinbar ist der Timer hier in diesem Perogramm auf 1 Sekunde eingestellt, aber wie kann ich ihn umstellen z.B. auf 3 Sekunden?



/*Blinkende LEDs im Sekundentakt 4MHz/2^16/64=1Hz --> 4MHz/16bit/Prescaler*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

volatile char count;

SIGNAL (SIG_OVERFLOW1) {
if (count == 1) {
PORTB = 0xFF;
count--;
return;
}
if (count == 0) {
PORTB = 0x00;
count++;
return;
}
}

void timer (void)
{
TIMSK = _BV(TOIE1); //Timer Overflow Interrupt enable
TCNT1 = 0; //Rücksetzen des Timers
TCCR1B = _BV(CS11) | _BV(CS10); //Prescaler 64
sei ();
}

int main (void) {
DDRB = 0xff;
timer ();
for (;;) {}
}

26.08.2004, 15:37
@seitenmaster

Sag mal hast du meinen Beitrag 3 Postings weiter oben nur überlesen oder mutwillig ignoriert?
Dieser sollte dir die Frage beantworten.

Alex

seitenmaster
26.08.2004, 15:41
oh das hatte er vorhin garnicht angezeigt, sorry den beitrag habe ich nicht gesehen.

JSt
29.08.2004, 21:12
Hallo zusammen,
da ich ebenfalls Anfänger bei den Microcontrollern bin passte dieser Thread super. Ich bin tatsächlich soweit gekommen, dass meine LED blinken.
Das ausrechnen der Blinkfrequenz funktioniert nicht oder ich habe es nicht verstanden (wahrscheinlich beides). Als Controller wird der Mega32 mit 16MHz (RN Control 1.4) Codeschnipsel folgt

TIMSK = _BV(TOIE1); //Timer Overflow Interrupt enable
TCNT1 = 34268; //ca. 5sec
TCCR1B = _BV(CS12) | _BV(CS10); //Prescaler 1024

erwartet habe ich 2 Sekunden geworden sind es 5 Sekunden. Wenn ich
TCNT1 = 49911 setze bleibt es bei ca. 5 Sekunden. Warum?

Grüße
Jürgen

Kjion
29.08.2004, 21:23
Setzt du den Wert von TCNT1 in der Interruptroutine immer wieder neu ?? Ansonsten hast du bis auf das erste Mal immer die maximale Zeit die du mit dem Timer warten kannst und die liegt bei 4,1 Sekunden bei 16 Mhz ;-)

MfG Kjion

JSt
29.08.2004, 22:19
Hatte ich natürlich nicht gemacht. Das wars Danke.
Gruß
Jürgen