Forum: Mikrocontroller und Digitale Elektronik Timer initialisieren/Anfängerin


von Julia (Gast)


Lesenswert?

Hallo,
Bin dabei das Tutorial durchzuarbeiten und bin bei dem Timer stehen 
geblieben. Ich kapiere das einfach nicht! Wie wird ein timer 
initialisiert (Overflow nach 50ms)? und dann Timer overflow variieren?
Der Controller ist Atmega 8515. Wie ich gelesen habe muss man man den 
Datenblatt lesen was ich schon versucht habe zu machen aber ich verliere 
den Übersicht und weiß nicht was wichtig und was nicht wichtig ist.
Als Anfängerin habe ich so geschrieben:
/* Atmega 8515*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include<avr/delay.h>

int main(void)
{
   DDRB = 0xFF;
   PORTB = 0x01;
  // Timer 0 konfigurieren
  TCCR0 = (1<<CS02); // clkI/O/256 (From prescaler)

  // Overflow Interrupt erlauben
  TIMSK |= (1<<TOIE0);

  // Global Interrupts aktivieren
  sei();

  while(1)
  {

  }
}




ISR (TIMER0_OVF_vect)
{
  PORTB = (1<<PB0);
  _delay_ms(50);
  PORTB = ~(1<<PB0);
  _delay_ms(50);
}

Bitte um einfache Erklärung
Danke

von Wolfgang (Gast)


Lesenswert?

Die Interupt-Routine soll den Prozessor so kurz wie möglich 
beschäftigen, damit andere Interupts auch zum Zuge kommen können. Ein 
Aufruf von delay hat dort überhaupt nichts zu suchen.

Gruß
Wolfgang

von Thomas E. (thomase)


Lesenswert?

Julia schrieb:
> TCCR0 = (1<<CS02); // clkI/O/256 (From prescaler)
Daraus errechnet sich der Takt mit dem der Timer betrieben wird.
F_CPU / 256
Angenommen F_CPU = 1MHZ: 1MHz / 256 = 3906 Hz
Damit wird der Timer 3906 mal pro Sekunde um 1 erhöht. Das Register ist 
8 Bit breit, somit gibt es bei 256 einen Überlauf: 255 + 1 = 0 = 
Überlauf.
Das löst einen Interrupt aus.
Also: 1Mhz / 256(Prescaler) / 256 (Überlauf) = 15,26 Hz
1 / 15,25Hz = 65,5ms

Julia schrieb:
> ISR (TIMER0_OVF_vect)
> {
>   PORTB = (1<<PB0);
>   _delay_ms(50);
>   PORTB = ~(1<<PB0);
>   _delay_ms(50);
> }
Das ist Mist.

ISR (TIMER0_OVF_vect)
{
   PORTB ^= (1 << PB0);
}
Jetzt geht alle 65,5ms die LED an bzw. aus. Was man gerade so erkennen 
kann. 1s / 65,5 ms = 15.

volatile char ct = 0;
ISR (TIMER0_OVF_vect)
{
   ct++;
   if (ct == 15)
   {
     PORTB ^= (1 << PB0);
     ct = 0;
   }
}
Damit blinkt die LED im Sekundentakt. Fast, da Rundungsfehler.

Das geht genauer und eleganter mit dem Compare-Interrupt. Aber bring' 
erstmal das zum Laufen.

>#include<avr/delay.h>
Das vergisst du jetzt, daß es das gibt.

mfg.

von Karl H. (kbuchegg)


Lesenswert?

Julia schrieb:

> Datenblatt lesen was ich schon versucht habe zu machen aber ich verliere
> den Übersicht und weiß nicht was wichtig und was nicht wichtig ist.

> Bitte um einfache Erklärung

http://www.mikrocontroller.net/articles/FAQ#Timer

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
Noch kein Account? Hier anmelden.