atxmega und externer interrupt

Gast #5811424
Lesenswert?

Hallo,

ich habe ein Problem mit meinem externen interrupt am Atxmega16D4. Ich 
habe folgenden Code:
1
PORTC.INTCTRL |= 0x03;                     
2
PORTC.INT0MASK |= PIN0_bm;                  
3
PORTC.PIN0CTRL |= PORT_ISC_RISING_gc;    
4

5
PMIC.CTRL |= PMIC_HILVLEN_bm; 
6
SREG |= 0x80;    
7
sei();
8

9
ISR(PORTC_INT0_vect)  
10
{                    
11
 //mache irgendwas für zwei µs
12
}

Im Grunde funktioniert das Ganze. Bei einer steigenden Flanke am Pin 
springt der Controller eine Mikrosekunde später in die ISR. Soweit OK.

Das Problem ist jedoch, dass mein Signal am Pin in dieser Mikrosekunde 
an Reaktionszeit bereits ein zweites mal mit steigender Flanke an diesem 
Pin anlag, sodass der Controller direkt nachdem er die ISR verlassen 
hat, sofort erneut in die ISR springt. Wie kann ich das vermeiden?
Gast #5811579
Lesenswert?

Ich habe ein Bild erstellt, vielleicht hilft das weiter.

Die zweite Flanke soll nicht ausgewertet werden.
Das Signal am Pin0 wiederholt sich alle 5 Millisekunden und ich möchte 
stets nur auf die erste Flanke reagieren. D.h. ich möchte alle 5 
Millisekunden lediglich nur einen ISR Durchlauf haben, unabhängig davon, 
wie stark das Signal gestört ist.
Angehängte Dateien:
Gast #5811658
Lesenswert?

In deinem Fall genügt es vielleicht schon, wenn du am Ende der ISR die 
Interrupt Flags löschst, indem du eine 1 an die Bitposition schreibst:
1
PORTC.INTFLAGS = INT0IF_bm;

Wenn die zweite dich störende Flanke während der ersten ISR auftritt, 
dann würdest du das Flag löschen und aus der ISR zurückkehren. Das Flag 
ist allerdings gelöscht, also wird die ISR nicht nochmal aufgerufen.

Wenn die Interrupts zu schnell nacheinander getriggert werden, aber 
nicht innerhalb der ersten ISR, dann kann Olivers Vorschlag helfen: In 
der Ext. Interrupt ISR startest du einen Timer und deaktivierst du die 
Ext. Int. ISR. (INT0MASK löschen). In der Timer ISR, deaktivierst du den 
Timer und aktivierst die Ext. Int. ISR.
(Firma: L-E-A) #5811661
Lesenswert?

Klarst schrieb:

> Die zweite Flanke soll nicht ausgewertet werden.
> Das Signal am Pin0 wiederholt sich alle 5 Millisekunden und ich möchte
> stets nur auf die erste Flanke reagieren.

Wenn die Signale stets paarweise auftreten, würde ich einfach ein 
D-Flipflop vorschalten. Beim ersten Einschalten ggf. das Signal pollen 
und den Reset des FFs erst freigeben, wenn der kurze Puls erkannt wurde.

Grüßle
Volker

Nachtrag: Oder arbeite mit zwei Interrupts, also das Signal an zwei Pins 
führen, die jeweils einen Interrupt auslösen. Der Handler des ersten 
sperrt seinen eigenen Interrupt und gibt den zweiten fei. Dieser machts 
dann genau andersherum und sperrt sich, gibt aber den ersten wieder 
frei. Vor der Freigabe die jeweiligen Flags löschen.

Die unterschiedlichen Pulse können recht elegant durch einen Timer im 
Pulse-Width-Capture-Modus unterschieden werden. Die Pulsweite steht dann 
direkt im zugh. Capture-Register.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren