Forum: Mikrocontroller und Digitale Elektronik AVR32 Timer Interrupt -> RC Trigger funktioniert nicht!?


von Kossi (Gast)


Lesenswert?

Hallo Leute,
folgendes Problem, ich programmiere einen Atmel 32UC3A1512.

Jede ms soll ein Wert vom ADC eingelesen werden. Hierzu rufe ich jede ms 
eine ISR mittels Timer-Interrupt auf. Der Timer läuft in Waveform-Mode.

Ausschnitt aus Main:
1
int main(void)
2
{
3
4
...
5
6
static const tc_interrupt_t TC_INTERRUPT =  // OPTIONEN Interrupts
7
{
8
...
9
  .cpcs  = 1,  // Compare RC    <--
10
11
... // sonst alle 0
12
};
13
14
static const tc_waveform_opt_t TC_WAVEFORM =
15
{
16
... 
17
// Werte hiervor sind alle: TC_EVT_EFFECT_NOOP,
18
.wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,
19
...
20
.tcclks = TC_CLOCK_SOURCE_TC2 // fPBA/2 --> (fPBA = 48MHz)
21
};
22
23
...
24
25
tc_write_rc(&AVR32_TC, TC_CHANNEL, 24000);   // 1KHz
26
27
...
28
29
while(1)
30
{...}
31
32
return 0;
33
}

Das funktioniert auch alles, d.h. die ISR wird ausgeführt.
Die Option RC_Trigger bedeutet meines Erachtens, dass der Timerwert 
wieder auf Null gesetzt wird und der Timer neu startet wenn der Timer 
den Wert, der im Register C geladen wurde, erreicht. Ist das richtig?
Durch die Interrupt-Einstellungen wird bei Compare_RC in die ISR 
gesprungen.

Nun muss ich aber immer am Ende(!) der ISR den Software-Trigger 
ausführen, damit das Ganze funktioniert. Das finde ich komisch, da ja 
eigentlich dieser Trigger automatisch bei RC-Compare ausgeführt werden 
sollte..?!?!

Hier die ISR:
1
static void led_ISR(void)
2
{
3
... // Wert aus dem ADC auslesen
4
5
tc_read_sr(&AVR32_TC, TC_CHANNEL); // Interrupt Flag löschen
6
tc_software_trigger(&AVR32_TC, TC_CHANNEL);
7
}

Wie gesagt, das Ganze funktioniert, aber so wird ja nun nicht jede ms 
die ISR ausgeführt, sondern jede

ms + (Bearbeitungszeit der ISR)

Um diese Zeit wirklich auf 1ms schrumpfen zu lassen, müsste der Timer, 
nachdem er den Wert RC erreicht hat sofort wieder auf Null gesetzt 
werden und neustarten. Hier wird der Timer aber erst nach Abarbeitung 
der ISR genullt und neugestartet.
Kurios ist, wenn ich das Löschen des Interrups Flags und den Software 
Trigger am Anfang der ISR schreibe, dann wird die ISR zwar ein paar Mal 
aufgerufen (das erkenne ich weil ich eine LED toggeln lasse) aber dann 
ist die ISR tot bzw. sie wird nicht mehr aufgerufen (LED toggelt nicht 
mehr). Dieses Verhalten verstehe ich nun gar nicht mehr.

Ich hoffe, Ihr könnt mir ein wenig Aufschluß geben;)

von Kossi (Gast)


Lesenswert?

Schade, hat denn niemand eine Idee, die mir behilflich wäre?

Ich wäre wirklich sehr dankbar über einige Anregungen..

MfG Kossi

von Tom (Gast)


Lesenswert?

Mit den Timern beim AVR32 habe ich auch noch so meine Schwierigkeiten - 
mal vorweg, die RC Triggerung hat bei mir aber funktioniert ;o). Ich 
hatte folgende Einstellungen:
1
AVR32_TC.channel[0].CMR.capture.cpctrg = 1;
2
AVR32_TC.channel[0].CMR.capture.wave = 1;   
3
AVR32_TC.channel[0].CMR.capture.cpctrg = 1;  <-- das triggert den Counter
4
AVR32_TC.channel[0].rc = WERT;
5
AVR32_TC.channel[0].IER.cpcs = 1;
6
AVR32_TC.channel[0].CCR.clken = 1;

Ich habe das Problem, das der RB Interrupt nicht kommt! RA und RC 
funktionieren, aber der RB Interrupt wird nicht ausgelöst. Mir ist noch 
ein wenig unklar, was im Capture Mode funktioniert und was im Waveform 
Mode. Meine Einstellungen sind:
1
AVR32_TC.channel[0].CMR.waveform.wave = 1;
2
AVR32_TC.channel[0].CMR.waveform.tcclks = 1;
3
AVR32_TC.channel[0].IER.cpas = 1;
4
AVR32_TC.channel[0].IER.cpbs = 1;
5
AVR32_TC.channel[0].IER.cpcs = 1;

mfg
hamsti

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.