-
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.
-
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
-
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
-
Und irgendwie geht die Uhr hier im Forum falsch, habe meinen Beitrag 15:12 Uhr verfasst ...
-
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?
Code:
/*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 (;;) {}
}
-
@seitenmaster
Sag mal hast du meinen Beitrag 3 Postings weiter oben nur überlesen oder mutwillig ignoriert?
Dieser sollte dir die Frage beantworten.
Alex
-
oh das hatte er vorhin garnicht angezeigt, sorry den beitrag habe ich nicht gesehen.
-
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
-
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
-
Hatte ich natürlich nicht gemacht. Das wars Danke.
Gruß
Jürgen