Forum: Mikrocontroller und Digitale Elektronik Kann Input Capture Flanke nicht umschalten


von Das D. (Gast)


Lesenswert?

Hallo Leute,

ich bin hier kurz vorm Verzweifeln.
Da gibt es dieses PWM-Signal, dessen Pulsbreite ich mittels Input 
Capture messen will. Das ganze auf einer Atmega 1280-Möhre.

Mein Problem ist, dass ich zwar nen Interrupt bekomme, wenn ich auf 
steigende Flanke prüfe und wenn ich auf fallende Flanke prüfe, aber 
beides in Kombination klappt nicht. Wenn ich nach der steigenden Flanke 
auf fallende umschalte, kommt der zweite Interrupt nicht mehr!

Als Vorbereitung mach ich diesen hier:
1
  // rising edge mode
2
  TCCR5B |= (1 << ICES5);
3
4
  pulse_on = TRUE;
5
6
  // enable input capture interrupt
7
  TIMSK5 |= (1 << ICIE5);
8
  sei();

In der ISR dann das hier:
1
ISR(TIMER5_CAPT_vect) {
2
  uint8_t temp = SREG;
3
    
4
  if (pulse_on) {
5
    // switch to falling edge mode
6
    TCCR5B &= ~(1 << ICES5);
7
8
    // clear ICF5 by writing logical 1
9
    TIFR5 |= (1 < ICF5);
10
    
11
    pulse_on = FALSE;
12
  } else {
13
    write("x");
14
  }
15
16
  SREG = temp;
17
}

Da kommt dann nur noch der erste Interrupt und dann nix mehr. Das 
Umschalten der Flankenerkennung scheint fehlzuschlagen. Dabei nudel ich 
doch extra noch die 1 auf das ICF, so wie das Datenblatt es mir befiehlt 
;)
Hat jemand eine Idee?

von Das D. (Gast)


Lesenswert?

.. oder hat jemand irgendein getestetes C- oder Assembler-Beispiel für 
die Flankenumschaltung?

von Anja (Gast)


Lesenswert?

Hallo,
habe ich jedoch für einen anderen Prozessor ATMEGA32
1
SIGNAL(SIG_INPUT_CAPTURE1)
2
{
3
    register uint16_t * ptr;
4
5
    /* interrupt latency 60-61 cy   (with reti but without call) */
6
7
    /* Interrupt flag is cleared automatically by call           */
8
    ptr = (uint16_t *) ICPInPoi; /* avoid warning from volatile  */
9
    *ptr++ = ICR1;               /* store ICP1-calue    */
10
    TCCR1B ^= (1 << ICES1);      /* switch to next edge */
11
12
    /* clear ICF1 flag after changing edge */
13
    TIFR = (1 << ICF1);
14
15
    /* switch to next buffer */
16
    if (ptr >= &ICP_RawVal[ICP_NUM_FIFO])
17
    {
18
       ptr = &ICP_RawVal[0];
19
    }
20
    ICPInPoi = ptr;
21
}

von Das D. (Gast)


Lesenswert?

Cool, danke!
Nen schönen Abend wünsch ich!

von STK500-Besitzer (Gast)


Lesenswert?

>TCCR5B &= ~(1 << ICES5);


Mach es am Ende der ISR so:
TCCR5B ^= (1 << ICES5);

Da muss man sich nicht mal "extern" merken, in welche Richtung die 
Flanke geschaltet ist.
Das Bit kann man auch abfragen, und darüber dann die Auswertung 
(innerhalb der ISR) machen.

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.