Forum: Projekte & Code AVRxDB und Verwandte - alle TCBs kaskadieren


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Veit D. (devil-elec)


Lesenswert?

Hallo,

übrigens, was ich einmal die Runde werfen möchte ist, man kann bspw. 
beim AVRxDB Controller nicht nur 2 TCB kaskadieren. Das suggeriert zwar 
erstmal das Manual, weil von 32Bit Kaskadierung die Rede ist, aber man 
kann alle verfügbaren TCBs kaskadieren.

Bsp. mit 3 TCBs, 48Bit Counter, den jeweilige Overflow Event bekommt der 
nächste TCB als sein Zähleingang per Event Channel verpasst. Und alle 
TCBs hängen noch auf dem gleichen Event Channel vom eigentlichen 
Takteingang damit alle zum gleichen Zeitpunkt ihre Zählerwerte in die 
Register speichern. Hier wäre Pin PA4 der Takteingang für die gesamte 
Kaskade.
1
void initEventSystem (void)
2
{
3
  EVSYS.CHANNEL0 = EVSYS_CHANNEL0_PORTA_PIN4_gc;    // set Pin PA4 as input event
4
  EVSYS.USERTCB0CAPT = EVSYS_USER_CHANNEL0_gc;      // Connect user to event channel 0
5
  EVSYS.USERTCB1CAPT = EVSYS_USER_CHANNEL0_gc;      //
6
  EVSYS.USERTCB2CAPT = EVSYS_USER_CHANNEL0_gc;      //
7
  
8
  EVSYS.CHANNEL3 = EVSYS_CHANNEL3_TCB0_OVF_gc;      //
9
  EVSYS.USERTCB1COUNT = EVSYS_USER_CHANNEL3_gc;
10
  
11
  EVSYS.CHANNEL4 = EVSYS_CHANNEL4_TCB1_OVF_gc;      //
12
  EVSYS.USERTCB2COUNT = EVSYS_USER_CHANNEL4_gc;
13
}
14
15
void initTCB (void)
16
{
17
  // *** LSB 16-Bit *** //
18
  TCB0.CTRLA = TCB_CLKSEL_DIV1_gc;     // CLK_PER divider
19
  TCB0.CTRLB = TCB_CNTMODE_FRQPW_gc;   // Capture Mode
20
  TCB0.EVCTRL = TCB_CAPTEI_bm;         // Enable Event Input and positive Edge
21
  TCB0.INTCTRL = TCB_CAPT_bm;          // Enable Capture interrupt
22
23
  // *** 1. MSB 16-Bit *** //
24
  TCB1.CTRLA = TCB_CASCADE_bm | TCB_CLKSEL_EVENT_gc; 
25
  TCB1.CTRLB = TCB_CNTMODE_FRQPW_gc;   // Capture Mode
26
  TCB1.EVCTRL = TCB_CAPTEI_bm;         // Enable Event Input and positive Edge
27
28
  // *** 2. MSB 16-Bit *** //
29
  TCB2.CTRLA = TCB_CASCADE_bm | TCB_CLKSEL_EVENT_gc; 
30
  TCB2.CTRLB = TCB_CNTMODE_FRQPW_gc;   // Capture Mode
31
  TCB2.EVCTRL = TCB_CAPTEI_bm;         // Enable Event Input and positive Edge
32
  
33
  // einschalten
34
  TCB0.CTRLA = TCB0.CTRLA | TCB_ENABLE_bm;  // Enable TCB0
35
  TCB1.CTRLA = TCB1.CTRLA | TCB_ENABLE_bm;  // Enable TCB1
36
  TCB2.CTRLA = TCB2.CTRLA | TCB_ENABLE_bm;  // Enable TCB2
37
}
38
39
ISR(TCB0_INT_vect) // alles auslesen
40
{    
41
  //  hier entsprechend auslesen
42
  TCB0.CNT;       // read out CNT first, then CCMP
43
  TCB1.CNT;          
44
  TCB2.CNT;   
45
  TCB0.CCMP;
46
  TCB1.CCMP;
47
  TCB2.CCMP;
48
  TCB0.INTFLAGS = TCB_CAPT_bm;   // Clear the interrupt flag
49
}

: Bearbeitet durch User
von Gerhard H. (Gast)


Lesenswert?

Interessante Info. Der Interrupt für TCB0 löst dann beim 48Bit Overflow 
aus?

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Gerhard H. schrieb:

> Interessante Info. Der Interrupt für TCB0 löst dann beim 48Bit Overflow
> aus?

Nein, der 48bit-Overflow ist natürlich der von TCB2. Schau dir doch 
einfach die Verkettung an, die ist: TCB0->TCB1->TCB2.

Aber egal, dieser Overflow kann ja sowieso frühestens nach ca. 204 Tagen 
Laufzeit relevant werden ;o)

von Veit D. (devil-elec)


Lesenswert?

Ob S. schrieb:
> Gerhard H. schrieb:
>
>> Interessante Info. Der Interrupt für TCB0 löst dann beim 48Bit Overflow
>> aus?
>
> Nein, der 48bit-Overflow ist natürlich der von TCB2. Schau dir doch
> einfach die Verkettung an, die ist: TCB0->TCB1->TCB2.

Falsch.

von Veit D. (devil-elec)


Lesenswert?

Gerhard H. schrieb:
> Interessante Info. Der Interrupt für TCB0 löst dann beim 48Bit Overflow
> aus?

Ein Overflow löst hier keinen Interrupt aus. Weil bei keinem Timer der 
Overflow Interrupt aktiviert ist. Es ist nur der Capture Interrupt von 
TCB0 aktiviert. Zeile 21. Es wird nur das Overflow Ereignis an den 
nächsten Timer weitergereicht. Oder man könnte einen Overflow Interrupt 
in Software pollen ohne Overflow ISR. Hier aber nicht sinnvoll. Es kommt 
hier nur auf das Eingangssignal an was man vermessen möchte. In dem Fall 
mit der Konfig die steigende Flanke. Wenn es hier zu einem Overflow der 
48 Bit kommen würde, würde man das nicht mitbekommen, dann wäre der 
Zählumfang zu kurz. Wenn man einen Überlauf überwachen möchte könnte man 
auf den Overflow vom letzten (höchstwertigen) Timer pollen oder dessen 
Overflow Interrupt aktivieren. Vielleicht hilft es auch zu wissen das 
die ISR von TCBn eine Sammel-ISR ist. Wenn man beide Interrupts 
aktivieren würde und man müsste wissen welcher ausgelöst hat, müsste man 
das in der ISR abfragen.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Veit D. schrieb:

> Ob S. schrieb:
>> Nein, der 48bit-Overflow ist natürlich der von TCB2. Schau dir doch
>> einfach die Verkettung an, die ist: TCB0->TCB1->TCB2.
>
> Falsch.

Wieso meinst du, das wäre falsch?

Da steht's doch:
1
  EVSYS.CHANNEL3 = EVSYS_CHANNEL3_TCB0_OVF_gc;      //
2
  EVSYS.USERTCB1COUNT = EVSYS_USER_CHANNEL3_gc;
3
4
  EVSYS.CHANNEL4 = EVSYS_CHANNEL4_TCB1_OVF_gc;      //
5
  EVSYS.USERTCB2COUNT = EVSYS_USER_CHANNEL4_gc;

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Veit D. schrieb:

> Vielleicht hilft es auch zu wissen das
> die ISR von TCBn eine Sammel-ISR ist. Wenn man beide Interrupts
> aktivieren würde und man müsste wissen welcher ausgelöst hat, müsste man
> das in der ISR abfragen.

Das allerdings ist richtig. Immerhin gibt es aber bei den Dx wenigstens 
das Flag zum abfragen.

von Veit D. (devil-elec)


Lesenswert?

Ob S. schrieb:
> Wieso meinst du, das wäre falsch?
>
> Da steht's doch:
>
>
1
>   EVSYS.CHANNEL3 = EVSYS_CHANNEL3_TCB0_OVF_gc;      //
2
>   EVSYS.USERTCB1COUNT = EVSYS_USER_CHANNEL3_gc;
3
> 
4
>   EVSYS.CHANNEL4 = EVSYS_CHANNEL4_TCB1_OVF_gc;      //
5
>   EVSYS.USERTCB2COUNT = EVSYS_USER_CHANNEL4_gc;
6
>

Ich will mich hier nicht streiten und nicht verkomplizieren. Original 
bezog sich die Nachfrage auf den 48Bit Overflow Interrupt auf TCB0, so 
habe ich das verstanden, der jedoch bei keinem Timer aktiviert ist und 
damit auch in der TCB0 ISR nicht auslösen kann. In der TCB0 ISR löst nur 
der Capture Interrupt aus. Die gezeigten Codezeilen betrifft nur das 
Eventsystem für die Kaskadierung.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Veit D. schrieb:

> Ich will mich hier nicht streiten und nicht verkomplizieren. Original
> bezog sich die Nachfrage auf den 48Bit Overflow Interrupt auf TCB0, so
> habe ich das verstanden

Genau. Und da isser eben definitiv falsch, weil sich eben aus der 
Verkettung ergibt, dass, wenn überhaupt, nur der Overflow von TCB2 in 
Frage kommt, um den 48-Bit Übertrag mitzubekommen.

Dass der dazu auch aktiviert werden muss und dass in der ISR verzweigt 
werden muss, weil es halt nur einen Vector für TCB2 gibt, steht außer 
Frage und war nie Thema der Diskussion.

von Gerhard H. (Gast)


Lesenswert?

Veit D. schrieb:
> In der TCB0 ISR löst nur der Capture Interrupt aus.

Danke, soweit verstanden :)
Gut erklärt.

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.