Timerprobleme

Gast #1131830
Lesenswert?

Hallo zusammen!

Ich habe erst angefangen Mikrocontroller zu bedienen und habe meine 
ersten Erfahrungen gemacht. Ich programmiere in C mit dem AVR Studio.
Nun mein Problem:
Ich will einen Timer programmieren mit dem mega 8. Mit dem steuere ich 
eine LED an die im Sekundentakt ein- und ausschalten soll. Die Frequenz 
habe ich bei den Configuration Options auf 8000000 Hz gestellt.
Doch statt nach einer Sekunde zu blinken benötigt er etwa 8 Sekunden. 
Was habe ich falsch?
Hier der Code:
#include <avr/interrupt.h>
#include <stdlib.h>
#include <avr/io.h>

volatile static uint32_t count = 0;

ISR(TIMER1_OVF_vect)
{
  count++;
}

int main (void)
{
  TCCR1B |= (1<<CS10);
  TIMSK |= (1<<TOIE1);
  sei();
  DDRC |= (1<<2);
  PORTC |= (1<<2);

  while(1)
  {
    if (count < 122) PORTC &= ~(1<<2);
    if (count >= 122) PORTC |= (1<<2);
    if (count > 244) count = 0;
  }return 1;
}

Diese 122 errechnen sich aus 8000000 Hz Taktfrequenz / 65536(da 16-Bit 
Timer) = ca. 122.


Was habe ich mir falsch überlegt?

Grüsse Alex
Persönliche Seite #1131892
Lesenswert?

Wie gesagt, Fuses kontrollieren.

Für sowas ist eigentlich der CTC-Mode besser geeignet:
1
#define F_CPU           8000000
2
#define IRQS_PER_SECOND 100
3
#define PRESCALE        8
4

5
void timer1_init(void)
6
{
7
  // Mode #4 für Timer1 (Manual S. 97)
8
  // und Prescale=8
9
  TCCR1A = 0;
10
  TCCR1B = (1 << WGM12) | (1 << CS11);
11

12
  // PoutputCompare für gewünschte Timer1 Frequenz
13
  OCR1A = (unsigned short) ((unsigned long) F_CPU / IRQS_PER_SECOND / PRESCALE -1);
14

15
  // OutputCompare-Interrupt A für Timer 1
16
  TIMSK |= (1 << OCIE1A);
17
}

Dann reicht auch eine 8-Bit Variable zum Zählen die immer von 1 bis 100 
(oder 0 bis 99) läuft.

Mit einer 32-Bit Variablen musst du sicherstellen, daß der Zugriffe 
darauf atomar sind, d.h. nicht von einem Interrupt unterbrochen werden 
können.

Mit einem PRESCALE von 256 bekommt man auch 1 IRQ/Sekunde hin, aber für 
viele Anwendungen sind 100 IRQs/s genehm (Taster entprellen, etc)
#1131953
Lesenswert?

> Die Frequenz habe ich bei den Configuration Options auf
> 8000000 Hz gestellt.

Andere haben ja schon auf dein Problem hingewiesen.
Möchte das nur etwas vertiefen.

Es gibt nur eine Möglichkeit beim Mega8 die Taktfrequenz zu verändern 
und das ist über die Fuses. Die werden aber vom Programmer nicht 
eigenmächtig angerührt, sondern die Umstellung musst du explizit machen. 
Aber sei vorsichtig, es passiert ganz schnell, dass man sich da aus dem 
Controller aussperrt. Lieber alles 3-mal kontrollieren, ehe man die 
Fuses neu stellt.

http://www.mikrocontroller.net/articles/AVR_Fuses

Die Angabe in den Configuration Options hat informellen Charakter. Du 
informierst die Entwicklungsumgebung, und damit auch dein Program, 
darüber, wie schnell dein µC getaktet ist.
Gast #1131979
Lesenswert?

Das verwirrt mich jetzt aber ein bisschen. Ich verwende schon den 
internen Takt, aber ich habe gemeint, dass er bei 16Mh liegt?! Oder ist 
das der höchstwert mitdem man ihn takten darf oder wie soll ich das 
verstehen?

Danke für die vielen und schnellen Antworten! Denke das wird es sein. 
Werde es jetzt testen.
Grüsse Alex
#1131992
Lesenswert?

Alex wrote:
> Das verwirrt mich jetzt aber ein bisschen. Ich verwende schon den
> internen Takt, aber ich habe gemeint, dass er bei 16Mh liegt?!

Wo hast du denn diesen Wert her?

Auslieferungszustand ist: 1Mhz, interner Takt
so wie es im Datenblatt des Prozessors beschrieben ist.

Und dein Testprogramm bestätigt das ja auch eindrucksvoll.

> Oder ist
> das der höchstwert mitdem man ihn takten darf oder wie soll ich das
> verstehen?

Atmel sichert zu, dass bei 16Mhz der Prozessor noch einwandfrei 
funktioniert. Man kann auch höher gehen, nur kann es dann sein, dass 
einige Teile des Chips nicht mehr mitspielen. Zb. das EEPROM.
Persönliche Seite #1132158
Lesenswert?

> Das habe ich z.B. von hier:
> http://www.roboternetz.de/wissen/index.php/Atmel_Controller_Mega8
>
> Da habe ich einfach angenommen, dass das der interne Takt ist...

Was da steht ist der maximale Taktrate, für den der ATmega8 spezifiziert 
ist. Akkerdingst steht nicht dabei, was die Angabe aussagt. Ist also 
nutzlos, wenn man nicht eh schon weiß, was das steht...

Werksseitig kommt der ATmega8 mit 1MHz inernem RC-Oszillator.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren