Timerinterrupts howto

Gast #2617154
Lesenswert?

Hallo,

ich versuche einen Timer zu schreiben, der alle 100µs eine Variable 
hochzählt...
Leider wird der Interrupt nie ausgeführt. Woran könnte das liegen?
1
void enableTime2()
2
{
3
  u8 tmpSREG = SREG;
4
  cli();
5

6
  //normal mode
7
  TCCR0 &= ~(1<<WGM01);
8
  TCCR0 &= ~(1<<WGM00);
9

10
  //normal port operation for OC0
11
  TCCR0 &= ~(1<<COM01);
12
  TCCR0 &= ~(1<<COM00);
13
  TCCR0 &= ~(1<<CS02);
14

15
  //set prescaler to 64
16
  TCCR0 |= 1<<CS01;
17
  TCCR0 |= 1<<CS00;
18

19
  //preload
20
  TCNT0 = 230;
21

22
  //enable overflow interrupts
23
  TIMSK |= 1<<TOIE0;
24

25
  SREG = tmpSREG;
26

27
  //enable interrupts
28
  SREG |= 1<<7;
29
}
30

31
volatile u64 _time;
32

33
void setTime(u64 time)
34
{
35
  u8 tmpSREG = SREG;
36
  cli();
37
  _time = time;
38
  SREG = tmpSREG;
39
}
40

41
u64 getTime()
42
{
43
  u8 tmpSREG = SREG;
44
  cli();
45
  u64 ret = _time;
46
  SREG = tmpSREG;
47
  return ret;
48
}
49

50
ISR(TIMER0_OVF_vect)
51
{
52
  _time += 100;
53
  TCNT1 = 230;
54
  toggleOutputPin(led3);
55
}
56

57
int main()
58
{
59
  Pin* led1 = allocPin(2, 0);
60
  Pin* led2 = allocPin(2, 1);
61
  led3 = allocPin(2, 3);
62
  setAsOutputPin(led1);
63
  setAsOutputPin(led2);
64
  setOutputPin(led1);
65
  setOutputPin(led2);
66
  setTime(0);
67
  enableTime2();
68
  while (1)
69
  {
70
    u64 time = getTime();
71
    if (time != 0 && time%1000000 == 0)
72
    {
73
      toggleOutputPin(led1);
74
    }
75
    _delay_ms(50);
76
    toggleOutputPin(led2);
77
  }
78
  freePin(&led1);
79
  freePin(&led2);
80
  freePin(&led3);
81
}
Gast #2617203
Lesenswert?

Hier mit dem Atmega32 bei 1 MHz habe ich kein Problem.

Um das Programm simulierbar zu machen musste ich ein paar typedefs 
machen, eine Variable definieren und ein paar Funktionen als Dummymakros 
erstellen.

Die ISR wird zum ersten Mal nach 1730 µs ausgeführt. Bis zum 2. und den 
folgenden Aufrufen vergehen dann jeweils 16384 µs. Die unterschiedlichen 
Zeiten kommen davon, dass du in der ISR den falschen Timer Counter 
vorlädst.
Bei F_CPU 16.64 MHz komme ich auch auf ~100µs.
Gast #2617261
Lesenswert?

Bei euch blinkt led1 jede Sekunde, led2 schnell und led3 "blinkt" mit 
einer nicht mehr wahrnembaren Frequenz?

Ich verwende Linux + Eclipse + CDT-Plugin + AVR-Plugin(->avr-gcc + 
avrdude) + AVRISPmkII + RNControl + ATmega32
Gast #2617266
Lesenswert?

Mhh, jetzt geht es mehr oder weniger. So ganz rund läuft das aber immer 
noch nicht...
Jedenfalls danke für die Hilfe!
Ich werde am Monrag noch mal in der Uni mit nem Logikanalysator da dran 
gehen.
Gast #2617509
Lesenswert?

> Bei euch blinkt led1 jede Sekunde, led2 schnell und led3 "blinkt" mit
> einer nicht mehr wahrnembaren Frequenz?

Natürlich nicht.

Du hattest geschrieben "IRQ wird nicht aufgerufen", daher habe ich mir 
dieses Problem i Simulator angesehen. Für einen Hardwaretest fehlt doch 
schon der AVR Typ und das Anschlussbild der LEDs!

Aber selbst für die IRQ-Untersuchung fehlten im Sourcecode mehrere 
Funktionen, Variaben und typedefs.

Die Funktionen habe ich kurz und schmerzlos als Dummys implementiert und 
dabei implizit vorausgesetzt, dass die keinen Seiteneffekt auf den IRQ 
haben.
Gast #2617666
Lesenswert?

Das ist klar.
Irgendwie geht es jetzt. Aber wo der Fehler war, kann ich nicht sagen.
Bloß blinkte die LED nicht so, wie ich es erwartet habe:
led an, 1s warten, led aus, 1s warten, ...
sondern etwa recht zufällig:
an, aus, an, aus, 5s warten, an, 10 sek warten,...
teilweise geht die led auch nicht "ganz" an, sondern man sieht es nur im 
unteren bereich kurz aufblitzen
mein toggle habe ich aber ganz normal als xor realisiert
PORT ^= 1<<PIN;
Gast #2617890
Lesenswert?

Timergesteuertes Tooglen und Delay-gesteuertes Toggeln in einem Programm 
vertragen sich nicht besonders gut. Bei dem 50ms Warten hast du 500 
Timer0 IRQs... es ist sehr wahrscheinlich, dass du dadurch den genauen 
Zeitpunkt verpasst, bei dem time%1000000 == 0 ist.
Gast #2617897
Lesenswert?

Bei genau 50ms = 500 IRQs würde es sogar noch klappen. Sobald es aber 
schon 499 oder 501 sind, klappt es schon nicht mehr. Und diese 
Abweichung hast du drin, wenn die Timerberechnung und die 
Delay-Implementierung nicht 100% exakt aufeinander passen.

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