Timer macht nicht das, was er soll?

Gast #3091523
Lesenswert?

Hallo,

ich wollte zuerst einen einfachen Timer programmieren, der jede Sekunde 
eine Variable auf 1 setzt. Dazu habe ich den 8-Bit Timer2 genommen, den 
Prescaler auf 1024 gesetzt und den Overflow Interrupt eingeschaltet. 
Jetzt sollte dieser Interrupt alle 1 / (16.000.000 / 1.024 / 256) = ca. 
61 Millisekunden ausgelöst werden. Dies geschieht aber bei mir nur ca. 
alle 3 bis 5 Millisekunden. Mein Code:

1
#define SET_BIT(x,y) x|=(1<<y)
2
#define CLR_BIT(x,y) x&=~(1<<y)
3
#define TGL_BIT(x,y) x^=(1<<y)
4
#define IS_BIT(x,y)  (x&(1<<y))
5

6

7
volatile int changed = 0;
8

9

10
void setup () {
11
  Serial.begin(9600);
12
  
13
  SET_BIT(TCCR2B, CS20);
14
  SET_BIT(TCCR2B, CS22);
15
  SET_BIT(TIMSK2, TOIE2);
16
}
17

18
void loop () {
19
  long t = millis();
20
  while(changed == 0);
21
  t = millis() - t;
22
  Serial.println(t);
23
  changed = 0;
24
}
25

26
ISR (TIMER2_OVF_vect) {
27
  changed = 1;
28
}

Was mache ich falsch?


Danke schon mal
burgerohnealles
Gast #3091566
Lesenswert?

Walter S. schrieb:
> du verwendest timer2, dann musst du auch die Werte für timer2 nehmen

Ahh. Ok. Ich habe jetzt dieses Bit noch gesetzt, aber es funktioniert 
trotzdem noch nicht ganz. Nach meinem Programm wird der Interrupt ca. 
alle 32ms ausgelöst. Es müsste doch ca. alle 16ms sein. Wo ist jetzt der 
Fehler?
#3091574
Lesenswert?

Jonathan K. schrieb:
> Warum steht da:
> http://www.mikrocontroller.net/attachment/173218/table.png was anderes
> als da:
> 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Zähler_des_AVR#8-Bit_Timer.2FCounter
> ?

Weil Atmel zig-verschiedene µC produziert mit jeweils unterschiedlicher 
Ausstattung an Timern.
Ein Tutorial zeigt immer die Dinge beispielsweise anhand eines 
spezifischen µC (und in diesem Fall anhand eines spezfischen Timers, den 
dieser im Tutorial benutzte µC besitzt).

Für dich ist das Tutorial ein Überblick, was die Timer so können und wie 
man sei konfiguriert. Aber deine Bibel, die einzig für dich relevante 
Dokumentation, ist das Datenblatt zu deinem Prozessor.
#3091595
Lesenswert?

Mach da mal
1
void loop () {
2

3
  while(changed == 0)
4
    ;
5
  changed = 0;
6

7
  long t = millis();
8
  while(changed == 0)
9
    ;
10
  t = millis() - t;
11

12
  Serial.println(t);
13
  changed = 0;
14
}

draus.
je nach Baudrate braucht auch der println seine Zeit. Wenn du da einen 
Timer-Interrupt verpasst, dann misst du die Zeit zwischen 2 Interrupts.
Gast #3091607
Lesenswert?

Electronics'nStuff schrieb:
> Electronics'nStuff schrieb:
>> Naja, dann hast du offensichtlich die falsche Taktquelle.
>
> EDIT: Ich tippe mal auf interne Taktquelle, 8MHz.

Hab mal die Fuses gecheckt: FF DE 05 -> Das heißt Ext. Crystal Osc.
Der Arduino läuft mit 16Mhz. Das heißt daran kann es schon mal nicht 
liegen.

Karl Heinz Buchegger schrieb:
> Mach da mal
> void loop () {
>
>   while(changed == 0)
>     ;
>   changed = 0;
>
>   long t = millis();
>   while(changed == 0)
>     ;
>   t = millis() - t;
>
>   Serial.println(t);
>   changed = 0;
> }
>
> draus.
> je nach Baudrate braucht auch der println seine Zeit. Wenn du da einen
> Timer-Interrupt verpasst, dann misst du die Zeit zwischen 2 Interrupts.

Das geht leider auch nicht. Der Arduino gibt immer noch 32 aus.
Gast #3092895
Lesenswert?

Hab jetzt nochmal ein bisschen herumprobiert. Ich dachte schon evtl. ist 
mein Arduino kaputt. Aber mit der Library "TimerOne" funktionierts 
perfekt. Der folgende Code sollte ca. alle 4 Sekunden die LED auf dem 
Arduino ein-/ausschalten (1 / (16.000.000Hz/1024/65536) = ca. 4,2s). 
Warum funktioniert der folgende Code nicht (die LED blink gar nicht)?
1
#define SET_BIT(x,y) x|=(1<<y)
2

3
void setup () {
4
  pinMode(13, OUTPUT);
5

6
  // prescaler: 1024
7
  SET_BIT(TCCR1B, CS12);
8
  SET_BIT(TCCR1B, CS11);
9
  SET_BIT(TCCR1B, CS10);
10
  
11
  // overflow interrupt enable
12
  SET_BIT(TIMSK1, TOIE1);
13
  
14
  // enable global interrupts
15
  sei();
16
}
17

18
ISR (TIMER1_OVF_vect) {
19
  digitalWrite(13, digitalRead(13)^1);
20
}
21

22
void loop () {
23
  // nothing
24
}

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