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 | }
|