Ich will mit einem Mikrocontroller ATMega32 90 Sekunden abwarten. Das soll mit dem 8-Bit Timer gelöst werden. Folgedermaßen hab ich mir das überlegt: Taktfrequenz: 8MHz Prescalor 1024 -> Auflösung 128µs 25ms/128µs = 195 -> 255-195 = 60 (von hier muss der 8-Bit-Timer hinaufzählen) Mit einem Overflowinterrupt wird dann gezählt. Getestet hab ich es, indem ich mit einem Tastendruck eine LED einschalte, die dann nach der entsprechenden Zeit wieder ausgehen sollte. Mein Problem ist allerdings, dass diese Zeit nicht mit der Berechnung überein stimmt. Die LED geht ca. 10 Sekunden zu früh aus. Hier der Code: ------------------------------------------------------------------------ -- #define F_CPU 8000000 #include <avr/io.h> #include <avr/interrupt.h> #include <inttypes.h> #include <util/delay.h> int Zeit = 0; void InitPort() { PORTB = 0x01; DDRB = 0x01; } void InitInterrupt() { TIMSK |= (1<<TOIE0); // Owerflow Interrupt enabled sei(); // Interrupts enablen } void InitTimer() { TCCR0 = (1<<CS02) | (1<<CS00); // Prescalor: 1024 (CS02, CS01, CS00 => 101) TCNT0 = 60; // Von 60 wird aufwaerts gezaehlt } ISR(TIMER0_OVF_vect) { Zeit ++; // globale Variable wird erhöht if (Zeit >=3600) { // 90 * 40ms PORTB = 0x01; // LED aus Zeit = 0; } TCNT0 = 60; } int main () { InitPort(); InitTimer(); InitInterrupt(); while(1) { if (!(PINB & (1<<PB4))) { // Tastendruck Zeit = 0; PORTB = 0x00; // LED an } } return 0; } ------------------------------------------------------------------------ --- Wär toll, wenn mir jemand erklähren könnte, was ich da falsch mache. lg Johannes
Johannes schrieb: > Taktfrequenz: 8MHz interner Takt oder Quartz? > 25ms/128µs = 195 -> 255-195 = 60 (von hier muss der 8-Bit-Timer > hinaufzählen) Warum so kompliziert mit Vorladen? Vorladen ist doch immer Müll. Der Mega32 kann doch CTC auch beim Timer 0!
> int Zeit = 0;
Zeit muss volatile sein.
Und auch das 0-Setzen in main müsste man atomic machen, weil es sich um
einen int handelt.
> interner Takt oder Quartz? Quarz > Der Mega32 kann doch CTC auch beim Timer 0! CTC? Was is das genau? ^^
Johannes schrieb: > CTC C lear T imer count on C ompare match Der Timer hat eine Vergleicher-Einheit in Hardware. Jedesmal, wenn ein Taktimpuls kommt, wird der Zählerstand erhöht und gleichzeitig mit einem Register verglichen. Bei Übereinstimmung wird, sofern gewollt, ein Interrupt ausgelöst und der Zählerstand in Hardware zurückgesetzt. Die Hardware erledigt also alles bis hin zur Interruptauslösung, wenn die entsprechenden Register richtig gesetzt sind. Nur um die Interrupt-Routine/-Behandlung musst du dich dann kümmern. mfg mf
volitile hat funktioniert ^^ ich hab zwar kein Ahnung was das macht, aber es fuktioniert :) Danke lg Johannes
Hallo,
>ich hab zwar kein Ahnung was das macht, aber es fuktioniert
hier die Erklärung:
Wenn man eine Variable in einem Interrupt oder außerhalb der Funktion,
in der sie deklariert wurde verwendet muss man sie als Globale Variable
ausweisen ->volantile.
Gruß Jannis
Jannis C. schrieb: > muss man sie als Globale Variable > > ausweisen ->volantile. Nicht ganz. Global sind alle Variablen, die ausserhalb der Funktionen deklariert werden. Diese Variable bekommt dann eine feste Speicherstele im RAM (Heap). Damit der Compiler jedesmal, nachdem die Variable in einer Funktion verändert wurde, diese auch wieder in die Speicherstelle zurück schreibt, wird diese mit "volatile" spezifiziert. Sonst kann es passieren, daß der Compiler die Variable in der Funktion einfach wegoptimiert. mfg.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.