Forum: Mikrocontroller und Digitale Elektronik XMega: 32Bit-Timer geht nicht im "Frequency Capture" Modus ?


von Hagen R. (hagen)


Lesenswert?

Hi

ich benutze nachfolgenden Code auf einem XMega A1:
1
EVSYS.CH0MUX = EVSYS_CHMUX_RTC_OVF_gc;
2
EVSYS.CH1MUX = EVSYS_CHMUX_TCC0_OVF_gc;
3
4
TCC1.PER = 0xFFFF;
5
TCC1.CTRLD = TC_EVSEL_CH0_gc | TC_EVACT_FRW_gc | TC1_EVDLY_bm;
6
TCC1.CTRLB = TC1_CCAEN_bm;
7
TCC1.CTRLA = TC_CLKSEL_EVCH1_gc;
8
9
TCC0.INTCTRLB = TC_CCAINTLVL_HI_gc;
10
TCC0.PER = 0xFFFF;
11
TCC0.CTRLD = TC_EVSEL_CH0_gc | TC_EVACT_FRW_gc;
12
TCC0.CTRLB = TC0_CCAEN_bm;
13
TCC0.CTRLA = TC_CLKSEL_DIV1_gc;
14
15
PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;

Die zwei Timer TCC0 und TCC1 werden zu einem 32Bit Timer über Event 
Channel #1 verknüpft und sollen ein "Frequency Capture" vom Event 
Channel #0 durchführen. Event #0 wird ausgelösst durch den RTC Overflow, 
wobei die RTC mit externem 32kHz Uhrenquarz getaktet wird und der OVF 
jede Sekunde kommt. Die Timer laufen mit 32MHz Takt.

Ich messe also die Anzahl an CPU Takten die die RTC alle Sekunde 
benötigt.

Ich habe nun fest gestellt das der normale Input Capture 
(TC_EVACT_CAPT_gc) und Pulse Width Capture (TC_EVACT_PW_gc) 
funktionieren. Beide liefern das gleiche Ergebnis. Mit denen könnte ich 
letzendlich leben und die ISR() sähe dann so aus:
1
volatile uint32_t ticks = 0;
2
volatile uint8_t  update = 0;
3
4
ISR(TCC0_CCA_vect) {
5
6
    static uint32_t last = 0;
7
    uint32_t f = TCC0.CCA | (uint32_t)TCC1.CCA << 16;
8
    ticks = f - last;
9
    last = f;
10
    update++;
11
}

Allerdings müsste auch der "Frequency Capture" funktionieren, man sollte 
also die Frequenz des Eintreffens eines Events ausmessen können. Das 
würde natürlich die ISR vereinfachen, weil der Timer Counter in diesem 
Modus automatisch zurück gesetzt wird.
1
ISR(TCC0_CCA_vect) {
2
3
    ticks = TCC0.CCA | (uint32_t)TCC1.CCA << 16;
4
    update++;
5
}

Ich bekomme aber diesen Capture Modus nicht an's laufen.

Hat jemand eine Idee was ich falsch machen könnte oder ob das generell 
nicht geht ? Und wenn warum nicht ?

Gruß Hagen

PS: übrigens ist das ein Test zu den Fähigkeiten der DFLLs und der 
Kalibrierung der internen Oszillatoren mit Hilfe des externem 32kHz 
Uhrenquarzes. Erstes Ergebnis: externer Quarz ist bei weitem stabiler.

von Gad Z. (gad)


Angehängte Dateien:

Lesenswert?

Hallo Hagen,
deine Frage ist zwar schon etwas her, aber vielleicht interessiert es 
trotzdem noch.
Allerdings programmiere ich alles in asm, aber das sollte auch kein 
Problem sein für C-Programmierer.


Im Anhang ist die Konfiguration.
TCE0/TCE1 sind konfiguriert als 32 Bit Timer im Frequency Capture Mode.
TCE0 Clock Source ist der Systemtakt
TCE0 Caputue Ereignis kommt vom Quadrature Encoder und ist auf Event 
Channel 0.
TCE1 Clock Source ist der Überlauf von TCE0 (Ereignis liegt auf Event 
Channel 1).
TCE1 Capture Ereignis ist das gleiche wie bei TCE0 (Event Channel 0).

Damit werden beide Timer über das selbe Capture Ereignis getriggert.

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.