Forum: Mikrocontroller und Digitale Elektronik Taster mit externen Interrupt prellt


von Tom L. (munzi)


Lesenswert?

Hallo,


ich schreibe gerade ein Programm, welches die externen Interrupts 
INT0..2 benutzt um Taster auszuwerten. Leider muss ich auf externe 
Iterruptszurückgreifen, da ich den Controller so noch aus dem Schlaf 
wecken muss. Nun schaffe ich es leider nicht, die Taster zu etprellen. 
Im Beitrag zum Taster entprellen wird auf die externen Interrupts leider 
nicht eingegangen, aber diese zu benutzen ist Vorgabe.
Ich habe versucht einen Timer mit Auftreten des externen Interrupts zu 
aktivieren, den Interrupt dann auszuführen und am Ende der ISR 
Interrupts zu deaktivieren und nach Ablauf einer bestimmten Zeit bedingt 
durch den Timer die Interrupts wieder zuzulassen. Leider funktionert 
dies nicht.
Der Interrupt wird in der Zeit nach Tastendruck und vor Ablaufen der 
Timerzeit immer wieder ausgeführt.
1
#define F_CPU 2000000UL
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include <avr/interrupt.h>
5
#include <avr/usart.c>
6
7
volatile uint8_t tick;
8
9
ISR(TIMER0_OVF_vect){
10
  tick++;
11
  if (tick==5){  
12
    tick=0;
13
    sei();
14
    TCCR0=0;
15
    usart_putc('y');
16
  }
17
}
18
19
ISR(INT0_vect){
20
  cli();
21
  TCCR0=(1<<CS02)|(1<<CS00);
22
  usart_putc('x');
23
}
24
25
int main(void){
26
    sei();
27
    usart_init();
28
    TIMSK=(1<<TOIE0);
29
    GICR=(1<<INT0);
30
    MCUCR=(1<<ISC01);
31
    
32
  while(1){
33
  }
34
  return 0;
35
}
36
37
//Ausgabe:
38
//xyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy
39
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy
40
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy
41
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy
42
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy
43
//xxxxxxxxyxxxxxxxxxxyxxxxxxxxxxxy
44
//xxxxxxxxxxxxxyxxxxxxxxxxxxxxy
45
//xxxxxxxxxxxxxxxxyxyxyxyxxxyxxxxxy
46
//xxxxxxyxxxxxxxy

Ich denke mir wäre sehr geholfen, wenn ich wüsste, was der Controller in 
der Zwischenzeit macht, bzw. was ich grundlegend falsch mache.

Danke
Tom

von 1.8T-Passat (Gast)


Lesenswert?

So wird das nichts. cli () und sei() haben in einer ISR nichts zu 
suchen. Beim verlassen der ISR werden Interrupts wieder enabled. Setz 
ein flag in der ISR, und schalte dann in der main-Routine den INT ab, 
und nach einer Zeit wieder an.

von Gastofatz (Gast)


Lesenswert?

>Leider muss ich auf externe
>Iterruptszurückgreifen, da ich den Controller so noch aus dem Schlaf
>wecken muss.

Das verbietet Dir aber nicht, die Tasten ansonsten ganz normal in einem 
festen Zeitraster abzufragen und nach einer der bewährten Methoden zu 
entprellen.

von Wilhelm F. (Gast)


Lesenswert?

Das ist schon richtig, daß jede einzelne Prellung den Interrupt wieder 
auslöst.

Falls der Interrupt nicht besonders zeitkritisch ist, und das bei der 
Vorgabe keine Rolle spielt:

Dann bau eine Software-Entprellschleife in die ISR ein, die die Prellung 
am Pin kontrolliert und eine Variable herunter zählt. Sobald die Taste 
nicht mehr prellt, wird die Entprellschleife verlassen. Zeitverzögerung 
dürfte im Bereich unter 10ms liegen, je nach Tastenart.

Eleganter sind zyklische Abfragen von Tasten aus dem Timer-Interrupt, 
aber das ist ja nicht das Thema.

von Peter D. (peda)


Lesenswert?

Tom Linz schrieb:
> Nun schaffe ich es leider nicht, die Taster zu etprellen.

Weil Du versuchst, 2 verschiedene Sachen zusammen zu mähren.

Mach das Aufwachen mit dem externen Interrupt, das ist richtig.
Und das Entprellen nach bewährter Methode im Timerinterrupt, dann 
funktioniert alles super.


Peter

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.