Forum: Mikrocontroller und Digitale Elektronik ATtiny202 Timer/Counter Type B (TCB) kein Sprung in ISR


von Christian S. (siblette)


Lesenswert?

Hallo zusammen.

Simple Geschichte: mein TCB am ATtiny202 läuft im Periodic Interrupt 
Mode (default). Die Initialisierung gemäß Datenblatt ist überschaubar:
1
static volatile uint32_t ticks_100us;
2
3
void InitTCB()
4
{
5
    ticks_100us = 0;
6
7
    // set TOP value (period)
8
    TCB0.CCMP = 1000 - 1;
9
10
    // enable timer overflow interrupt
11
    TCB0.INTCTRL = TCB_CAPT_bm;
12
13
    // clock prescaler 2, enable timer
14
    TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc | TCB_ENABLE_bm;
15
16
    // enable global interrupts
17
    sei();
18
}

Lese ich das Status Register des TCB sehe ich, dass der Timer läuft 
(entsprechendes Bit auf 1). Ich kann auch nach kurzer Zeit sehen, dass 
entsprechendes Interrupt Flag (TCB0 Overflow Interrupt) auf 1 gesetzt 
wird.

Jedoch wird die ISR nie aufgerufen??? Kein Inkrement von ticks_100us.
1
// TCB0 overflow interrupt
2
ISR(TCB0_INT_vect)
3
{
4
    ticks_100us++;
5
6
    // clear interrupt flag
7
    TCB0.INTFLAGS = TCB_CAPT_bm;
8
}

Habe schon das weltweite Web durchsucht, im Datenblatt nachgelesen; 
komme einfach nicht weiter. Bitte um Hilfe.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Christian S. schrieb:

>     // enable timer overflow interrupt
>     TCB0.INTCTRL = TCB_CAPT_bm;

in meinem Datenblatt steht nichts davon, dass das Bit TCB_CAAPT in 
INTCTRL gesetzt werden muss:

"21.3.2 Initialization
By default, the TCB is in Periodic Interrupt mode. Follow these steps to 
start using it:

• Write a TOP value to the Compare/Capture register (TCBn.CCMP).

• Enable the counter by writing a '1' to the ENABLE bit in the Control A 
register (TCBn.CTRLA). The counter will start counting clock ticks 
according to the prescaler setting in the Clock Select bit
field (CLKSEL in TCBn.CTRLA).

• The counter value can be read from the Count register (TCBn.CNT). The 
peripheral will generate an interrupt when the CNT value reaches TOP."

Grüßle
Volker

von Georg M. (g_m)


Lesenswert?

Christian S. schrieb:
> Jedoch wird die ISR nie aufgerufen???

Die LED blinkt, also müsste eigentlich alles funktionieren.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
volatile uint16_t count;
5
6
ISR(TCB0_INT_vect)
7
{
8
  count++;
9
  if(count == 0x05DC)
10
  {
11
    PORTA.OUTSET = PIN3_bm;          // LED ON
12
  }
13
  if(count == 0x0682)
14
  {
15
    PORTA.OUTCLR = PIN3_bm;          // LED Off
16
    count = 0;                       // clear count
17
  }
18
  TCB0.INTFLAGS = TCB_CAPT_bm;
19
}
20
21
void InitTCB()
22
{
23
  TCB0.CCMP = 1000 - 1;
24
  TCB0.INTCTRL = TCB_CAPT_bm;
25
  TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc | TCB_ENABLE_bm;
26
}
27
28
int main(void)
29
{
30
  PORTA.DIRSET = PIN3_bm;          // PA3 as output
31
  InitTCB();
32
  sei();
33
  while(1)
34
  {
35
    ;
36
  }
37
}

von Roland K. (Gast)


Lesenswert?

Hallo in die Runde,
ich stand gerade vor dem gleichen Problem wie Christian vor einem Jahr 
bei dem vom Timer TCB0 her identischen AVR64DD32.

Ich initialisiere den Timer,
das Capture-Flag wird gesetzt,
ich kann es in main() abfragen, einen Pin toggeln und das Capture Flag 
löschen.
Es blinkt.
Wenn ich stattdessen eine ISR verwende, passiert nichts.

Das von Georg vorgestellte Programm läuft jedoch problemlos.

Die Lösung war:
Ich hatte noch einen zweiten Timer (TimerA) initialisiert, und den 
overflow-interrupt aktiviert:

      TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm;

Den habe ich aber nicht genutzt und daher keine ISR geschrieben und auch 
das Interrupt-Flag nicht zurückgesetzt.

Damit habe ich den Interrupt von TCB0 blockiert.
Er  lief zwar und das Interrupt-bzw. Capture-Flag wurde gesetzt und 
konnte in main() ausgelesen und zurückgesetzt werden, eine ISR wurde 
aber nicht aufgerufen.

Fazit:
Eine ISR für TCA0 ist notwendig, egal ob sie das Flag zurücksetzt oder 
nicht, d.h. sie kann auch leer sein.
In diesem Fall muss das Flag an anderer Stelle zurückgesetzt werden.

Ich vermute, dass ich jetzt nicht nur mein Problem gelöst habe, sondern 
auch noch etwas über Interrupt-Handling gelernt habe ;-)

von Veit D. (devil-elec)


Lesenswert?

Hallo,

ich kann nur jeden für den Einstieg empfehlen sich die "Getting 
Starting" u.a. App Notes auf der Controller Seite unter Documentation 
durchzuarbeiten. Die der megaAVR Reihe (ATmega4809) kann man auch 
nehmen, weil die verwandt sind. Auch die Hardwareinheiten der neuen 
ATtinys sind verwandt. Damit hat man ein breites Spektrum an Beispielen 
inkl. Erklärung zusätzlich zum Manual.

von S. Landolt (Gast)


Lesenswert?

Roland K. schrieb:

> Fazit: Eine ISR für TCA0 ist notwendig, egal ob ...
So formuliert ist es falsch; und wozu aktiviert man einen Interrupt, 
wenn man ihn nicht nutzt?

> etwas über Interrupt-Handling gelernt
'If several level 0 interrupt requests are pending at the same time, the 
one with the highest priority is scheduled for execution first.': die 
TCA-Interrupts liegen nun mal vor den TCB, und da in diesem Fall das 
TCA-Flag nie zurückgesetzt wird ...

von Roland K. (Gast)


Lesenswert?

Ich kann Veit mit seiner Empfehlung für die "Getting started ..."nur 
zustimmen.
Ich arbeite mich aktuell in den AVR-DD ein.
Da es für diese ziemlich neue Serie Wesentlich weniger Infos und 
Beispiele gibt, als für ältere Modelle, war eine für den Zugang 
wesentliche "Erkenntnis", dass nicht nur die Dx-Modelle, sondern auch 
die mega0 und die neueren Tinys verwandt sind und deren Einführungen 
sinnvoll verwendet werden können.
Was auch hilfreich ist, ist die youtube-Reihe zum bare-metal-programming 
eines neueren AT-Tiny:
https://www.youtube.com/playlist?list=PLtQdQmNK_0DQ8KGcZ1BOPv-3RDPvtqJ1H

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.