Forum: Mikrocontroller und Digitale Elektronik Sperren des externen Interrupts für gewisse Zeit


von Jens (Gast)


Lesenswert?

Hallo zusammen,
ich habe folgende Aufgabe zu lösen (AT90USB1287):

nachdem ein externer Interrupt (fallende Flanke) vom MC detektiert 
wurde, soll der externe Interrupt-Eingang für 100ms für weitere Flanken 
gesperrt werden und nach Ablauf der Zeit wieder für den Empfang 
freigegeben werden.

Anbei meine beiden Interruptroutinen:
1
startflag = true;
2
ext_int = true;
3
4
ISR(INT0_vect)  // Interrupt routine for 
5
{
6
  if( (startflag == true) && (ext_int == true) ){
7
    EIMSK = 0x00;    // Stop external Interrupt
8
    counter = counter + 1;  //  Do something important
9
    TCNT1 = 0x0000;    // Reset Counter  
10
    TCCR1B |= (1<<CS12);  // Start Timer
11
    PORTD |= (1<<1);  // Yellow LED on
12
    ext_int = false;  // Set Interrupt Lock
13
  }
14
}
15
16
17
ISR(TIMER1_COMPA_vect)
18
{
19
  TCCR1B &= ~(1 << CS12);    // Stop Timer  
20
  EIMSK = 0x01;      // Start external Interrupt  
21
  ext_int = true;      // Reset Interrupt Lock
22
  PORTD &= ~(1<<1);    // Yellow LED off
23
}

Sobald ein externer Interrupt empfangen wird, wird durch die zugehörige 
Interruptroutine das Maskregister auf 0 gesetzt und ein Timer aktiviert. 
Nach 100ms erfolgt ein Timerinterrupt, welcher die Sperrung des externen 
Interrupts rückgängig machen soll. Allerdings funktionieren die Routinen 
nicht so wie sie sollen, da innerhalb der Totzeit auf weitere externe 
Flanken reagiert wird.

Was mache ich falsch?

Gruß Jens

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Jens schrieb:
> Nach 100ms erfolgt ein Timerinterrupt, welcher die Sperrung des externen
> Interrupts rückgängig machen soll. Allerdings funktionieren die Routinen
> nicht so wie sie sollen, da innerhalb der Totzeit auf weitere externe
> Flanken reagiert wird.

Bevor du den Interrupt wieder frei gibst solltest du das Interruptflag 
löschen.

Gruß,
Magnetus

von Jens (Gast)


Lesenswert?

Hi Magnetus,

muss das Löschen des Interruptflags also direkt vor
1
EIMSK = 0x01;      // Start external Interrupt
 erfolgen ?

Wie kann ich dieses Flag zurücksetzten?

Gruß Jens

von Stefan W. (swessels)


Lesenswert?

1
ext_int
 sollte
1
volatile
 sein.

Gruß,
Stefan

von Werner B. (werner-b)


Lesenswert?

Jens schrieb:
> Wie kann ich dieses Flag zurücksetzten?

Eine 1 reinschreiben.
(Siehe Manual/Datenblatt)

von Jens (Gast)


Lesenswert?

Danke noch mal an alle,

hier noch mal der Happen, der gefehlt hat zu meinem Feierabendbier:
1
  EIFR = (1<<INTF0);    // Reset Interrupt Flag
2
  EIMSK = 0x01;      // Start external Interrupt

Gruß Jens

von Peter (Gast)


Lesenswert?

Stefan Weßels schrieb:
> ext_int
>  sollte volatile
>  sein.

nein muss nicht, weil der compiler es überhaupt nicht optimierne kann, 
weil es beides ISR sind, volatile macht es nur langsamer.

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.