Forum: Mikrocontroller und Digitale Elektronik Taster Entprellen [Interrupt]


von Schüler E. (william97)


Angehängte Dateien:

Lesenswert?

Hallo liebe Community!:)

Ich habe hier mein erstes Script geschrieben, mit welchem man durch 
Tastendruck eine LED ein- bzw. ausschalten kann.
Jetzt habe ich das Problem, dass meine Taster "bouncen".
Habe mir schon mehrere Beiträge durchgelesen, jedoch meistens nicht 
genau verstanden oder die Beiträge waren mit Interrupts inkompatibel.
Könnte mir jemand eine gute Seite empfehlen oder mein Script 
vervollständigen und mir erklären welcher Befehl was macht?

Danke im Vorraus!:)

1
#include <avr/io.h>
2
3
#include <avr/interrupt.h>       // enthält alle Routinen
4
                                 //für die Interruptverarbeitung
5
6
7
                                 //ISR (Interrupt-Service-Routine) für
8
                                 //Interrupt 0
9
     
10
{
11
   PORTD |= (1<<PD7);            //setze PortD 7 (Lampe an)
12
}
13
 
14
                                  //ISR (Interrupt-Service-Routine) für 
15
                                  //Interrupt 1
16
17
{
18
   PORTD &= ~(1<<PD7);            //lösche PortD 7 (Lampe aus)
19
}
20
21
22
int main(void)
23
{
24
 DDRD |= (1<<PD7)
25
 PORTD|= (1<<PD2) | (1<<PD3)
26
27
 MCUCR |= (1<<ISC10) | (1<<ISC11); //Interrupt 1 wird konfigriert    
28
29
                                    //Interrupt 0 wird konfiguriert
30
31
  GICR |=(1<<INT0)  | (1<<INT1);     //INT0 und INT1 aktiviren
32
33
  sei();                             //Interrupts global aktivieren
34
  
35
  while(1)
36
  {
37
38
  }
39
40
}

: Bearbeitet durch User
von spontan (Gast)


Lesenswert?

>Ich habe hier mein erstes Script geschrieben, ...
> ... mir erklären welcher Befehl was macht?

Unsinn, entweder selbst geschrieben, oder kopiert und nicht verstanden. 
Was nun?

Ließ doch mal hier das Tutorial zum Einlesen von Tasten.

von Max H. (hartl192)


Lesenswert?

Wenn du einen Eingang für Ein und einen für Aus, also wie ein 
RS-FlipFlop,  verwendest stört das Prellen nicht, außer dass es ein 
bisschen Rechenzeit verbraucht.

Schüler E. schrieb:
> Könnte mir jemand eine gute Seite empfehlen
AVR-GCC-Tutorial

: Bearbeitet durch User
von Schüler E. (william97)


Lesenswert?

Ich habe das Script selber geschrieben und verstanden? Ich möchte nur 
eine Erklärung wie ich das "Entprellen" einbauen kann.
Das Problem ist ich soll das ganze in Scriptform abgeben mit Erklärung 
und allem, Teil 1 also Interrupts allgemein hab ich fertig, das 
Software Entprellen gäbe noch paar extra Punkte, deshalb würde ich das 
ganz gerne machen.

von Max H. (hartl192)


Lesenswert?

Mit dem flankengesteuertem Interrupt kann man den Taster nicht gut 
entprellen, da jede Prell-Flanke ein Interrupt auslöst. Für gewöhnlich 
nimmt man ein Timer Interrupt und fragt den Zustand in der ISR ab.
Siehe --> Entprellung <--

Habe ich das richtig verstanden, dass du die LED mit einer Taste ein- 
und mit einer anderen ausschaltest, also wie ein RS-FlipFlop? Wenn ja 
ist entprellen nicht notwendig. Dein einziges Problem ist dass die ISR 
durch das Prellen öfters aufgerufen wird und Rechenzeit verbraucht. Das 
kannst du wenn du flankengesteuerte Interrupts verwendest nur in 
Hardware lösen.

: Bearbeitet durch User
von Schüler E. (william97)


Lesenswert?

Stimmt wenn ich es genau überdenke ist ein Entprellen gar nicht 
notwendig.
Danke erstmal dafür :)

Ich würde jedoch gerne bei der Verwendung der externen Interrupts 
bleiben, ist es möglich den Taster so abzufragen das nach Betätigung die 
Interrupts global deaktiviert werden "cli();" und dann nach 100ms 
einfach wieder aktiviert werden "sei();". Wäre zwar keine genaue Methode 
aber für mich ausreichend.

von Max H. (hartl192)


Lesenswert?

Schüler E. schrieb:
> ist es möglich den Taster so abzufragen das nach Betätigung die
> Interrupts global deaktiviert werden "cli();" und dann nach 100ms
> einfach wieder aktiviert werden "sei();"
Bitte komm NICHT auf die Idee ein Delay in die ISR zu stecken, das ist 
ein ABSOLUTES NO-GO. Du könntest es so machen, dass du in der ISR 
INT0/INT1 deaktivierst und einen Timer, der nach 100ms überläuft, 
startest und in der Timer ISR das entsprechende Interrupt wieder 
aktivierst.

: Bearbeitet durch User
von Schüler E. (william97)


Lesenswert?

Ok dann werde ich das mit dem delay schnell wieder vergessen :D
Ich werde mir mal "Timer Interrupts" anschauen und mich später wieder 
melden, habe bisher nur die externen Interrupts behandelt.

von Nosnibor (Gast)


Lesenswert?

Wozu der Timer? Wenn man separate Tasten fürs Ein- und Ausschalten hat, 
ist Entprellen nicht nötig, da immer nur die erste Flanke von genau 
einem Eingang interessiert.

Also:

Interrupt0:
 - Int.0 sperren
 - Licht an
 - Int.1 einschalten

Interrupt 1:
 - Int.1 sperren
 - Licht aus
 - Int.0 einschalten

Solange das Licht an ist, bekommt der Prozessor dann natürlich nicht 
mehr mit, wenn die Einschalttaste nochmal gedrückt wird (Interrupt 0 ist 
ja deaktiviert). Aber das macht nichts; der Prozessor würde ja sowieso 
nichts für den Benutzer wahrnehmbares tun.

von Karl H. (kbuchegg)


Lesenswert?

Nosnibor schrieb:
> Wozu der Timer? Wenn man separate Tasten fürs Ein- und Ausschalten hat,
> ist Entprellen nicht nötig, da immer nur die erste Flanke von genau
> einem Eingang interessiert.
>
> Also:
>
> Interrupt0:
>  - Int.0 sperren
>  - Licht an
>  - Int.1 einschalten
>
> Interrupt 1:
>  - Int.1 sperren
>  - Licht aus
>  - Int.0 einschalten
>

Und wenn man sich das mal genau überlegt, erhebt sich die Frage, wozu 
man da überhaupt externe Interrupts braucht.
Nur dazu, damit man eine Flankenerkennung gratis bekommt. Die ist aber 
so kompliziert auch wieder nicht. Und wenn es nur darum geht ein Licht 
mit 2 Tastern ein bzw. aus zu schalten, braucht man noch nicht mal das.

Alles was man braucht ist eine Variable, die festhält ob das Licht 
brennen soll oder nicht. Wobei man sogar die noch einsparen könnte, bzw. 
in das Bit des Portregisters legen kann, mit der die LED verbunden ist.
1
int main()
2
{
3
.....
4
5
  while( 1 )
6
  {
7
    if( !(PIND & ( 1 << PD0 )) )
8
      PORTB |= ( 1 << PB1 );
9
10
    if( !(PIND & ( 1 << PD1 )) )
11
      PORTB &= ~( 1 << PB1 );
12
  }
13
}

fettich.

Wobei: ordentliches Einlesen von Tastendrücken und deren Entprellung ist 
eine Technik, die man irgendwann sowieso braucht. Aber sicher nicht ...
1
... Ich habe hier mein erstes Script geschrieben.
... in dieser Situation. Tastendrücke zu erkennen (im Gegensatz zu 'ist 
eine Taste gedrückt') ist erstaunlicherweise nicht so einfach. Lediglich 
das Stichwort 'externer Interrupt' zu benutzen, greift da deutlich zu 
kurz.

: Bearbeitet durch User
von Max H. (hartl192)


Lesenswert?

Und die Frage wieso man einen uC braucht. Zwei einfache NOR oder NAND 
können das auch...

von Karl-Otto (Gast)


Lesenswert?

> Interrupt0:
>  - Int.0 sperren
>  - Licht an
>  - Int.1 einschalten
>
> Interrupt 1:
>  - Int.1 sperren
>  - Licht aus
>  - Int.0 einschalten

Wenn die beide IRQ-Routinen schnell genug durchlaufen werden, dann sorgt 
eine lange Prellzeit dafür, dass das Ganze ein Zufallsgenerator ist 
(Licht ist AN oder AUS).

von Nosnibor (Gast)


Lesenswert?

Karl-Otto schrieb:
> Wenn die beide IRQ-Routinen schnell genug durchlaufen werden, dann sorgt
> eine lange Prellzeit dafür, dass das Ganze ein Zufallsgenerator ist
> (Licht ist AN oder AUS).

Nur wenn der Benutzer beide Tasten gleichzeitig (im Sinne von: die 
zuerst gedrückte Taste prellt noch, während die zweite gedrückt wird) 
drückt.
Selber schuld, wenn er sich nicht entscheiden kann.

von spontan (Gast)


Lesenswert?

Auf alle Fälle ist es der Welt dümmster Ansatz, prellende Tasten per 
Interrupt zu behandeln.
Würd ich meinem Lehrer sagen und auch begründen können.

Haben die denn keine besseren Beispiele parat, wenn die Behandlung von 
Interrupts im Unterricht besprochen wird????

von Dirk K. (dekoepi)


Lesenswert?

Ich habe das grade mal probiert und kann bestätigen - per Interrupt 
Taster entprellen ist eine schlechte Idee. Habe das jetzt so weit 
getrieben:
- Interrupt auf steigende Flanke an PinB3 (Taster zieht mit 150Ohm auf 
Vcc; Pin hat 10k Pulldown auf GND).
- Erste Schnellschussfassung: Bis 3 zählen (also 3 Interrupts abwarten) 
und erst das als Tastendruck erkennen. Kommt bei etwa 75% der 
Tastendrücke hin. Aber immer noch ein ziemlicher Zufallsgenerator.
- Ich merke mir TasteGedrückt beim ersten Druck, werfe einen Timer an 
und in dessen ISR führe ich meine Sachen aus. Dazu deaktiviere ich die 
erste Interrupt-Routine. Idee: damit warte ich das Prellen einfach ab.
Ist aber ein viel schlimmerer Zufallsgenerator; erzeugt immer 2-3 
erkannte Tastendrücke, die dann nach der Wartezeit ausgeführt werden. 
Hätte gedacht, dass die durch das Deaktivieren des ISR nicht aufgenommen 
würden, war aber nichts.

Ich glaube so langsam, entprellen in Software ist doch nicht trivial ;)

Ich brauche die Interrupts, weil mein Programm weiterlaufen und der 
Prozessor in einer Stellung sogar im Powerdown schlafen soll (Strom 
sparen). Per ISR geht das, und der Prozi wird wieder geweckt.

: Bearbeitet durch User
von Alexander S. (esko) Benutzerseite


Lesenswert?

Lest euch mal den Artikel Entprellung durch, dort steht geschrieben, 
welche Möglichkeiten es in Software (und Hardware) gibt und welche zu 
bevorzugen sind.

von Peter D. (peda)


Lesenswert?

Dirk K. schrieb:
> Ich brauche die Interrupts, weil mein Programm weiterlaufen und der
> Prozessor in einer Stellung sogar im Powerdown schlafen soll (Strom
> sparen). Per ISR geht das, und der Prozi wird wieder geweckt.

Zum Aufwachen ist der Interrupt geeignet. Danach wird dann normal 
entprellt.
Programmfunktion und Sleepmode/Aufwachen sind quasi 2 eigenständige 
Tasks, die man auch getrennt entwickelt:

Beitrag "AVR Sleep Mode / Knight Rider"

von Teo D. (teoderix)


Lesenswert?

@Dirk K.
Du musst schon 10-50mS abwarten, je nach verwendeten Taster. Man darf 
aber auch nicht vergessen das Taster auch beim loslassen prellen 
können!

von Peter II (Gast)


Lesenswert?

Teo Derix schrieb:
> aber auch nicht vergessen das Taster auch beim loslassen prellen
> können!

wie kann man sich der erklären? Oder meinst du einen öffner kontakt?

von Peter D. (peda)


Lesenswert?

Peter II schrieb:
> Teo Derix schrieb:
>> aber auch nicht vergessen das Taster auch beim loslassen prellen
>> können!
>
> wie kann man sich der erklären?

Wie beim Dribbeln, Du schlägst auf den Ball und er kehrt wieder zur Hand 
zurück.
Die Kontaktfeder speichert beim Betätigen Energie und gibt sie als 
gedämpfte Schwingung ab.

Bei Tasten ohne Schnappmechanik (Druckpunkt) kann auch Deine 
Muskelbewegung eine Mehrfachbetätigung auslösen. Muskeln werden ja 
gepulst.

von Peter II (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Wie beim Dribbeln, Du schlägst auf den Ball und er kehrt wieder zur Hand
> zurück.
> Die Kontaktfeder speichert beim Betätigen Energie und gibt sie als
> gedämpfte Schwingung ab.

schon klar, aber sie schwinkt doch wohl nie so stark das sich die 
kontakte wieder verbinden.

von Karl H. (kbuchegg)


Lesenswert?

Peter II schrieb:
> Peter Dannegger schrieb:
>> Wie beim Dribbeln, Du schlägst auf den Ball und er kehrt wieder zur Hand
>> zurück.
>> Die Kontaktfeder speichert beim Betätigen Energie und gibt sie als
>> gedämpfte Schwingung ab.
>
> schon klar, aber sie schwinkt doch wohl nie so stark das sich die
> kontakte wieder verbinden.

Wenn du Kontakte stark genug abgenudelt sind, kann alles mögliche 
passieren.
Mit der PeDa Entprellung ist das ja kein Problem. Die entprellt in 
beiden Richtungen.

von Peter D. (peda)


Lesenswert?

Peter II schrieb:
> schon klar, aber sie schwinkt doch wohl nie so stark das sich die
> kontakte wieder verbinden.

Ist eine Frage der Konstruktion. Die Schnappmechanik speichert deutlich 
mehr Energie, als für das reine Bewegen der Kontaktfeder nötig ist.
Zusätzlich werden Taster immer kleiner (billiger), d.h. kleiner 
Kontaktabstand, kleine Federn. Die Betätigungskraft des Menschen bleibt 
aber gleich.

Ein weiterer Prellgrund, Tasten altern, d.h. es bilden sich kleine 
isolierende Bereiche (Staub, Oxydschicht) die beim darüber Bewegen den 
Strom unterbrechen.

Das Heimtückische am fehlenden Enprellen ist, daß fabrikneue Tasten oft 
kaum prellen. Und nach einem halben Jahr Benutzung geht dann das Drama 
los.

von Dirk K. (dekoepi)


Lesenswert?

Peter Dannegger schrieb:
> Programmfunktion und Sleepmode/Aufwachen sind quasi 2 eigenständige
> Tasks, die man auch getrennt entwickelt:

Darüber hatte ich nur kurz sinniert und bin noch zu keiner für mich 
schlüssigen Umsetzung gekommen (Programm ist wie ein Artikel für mich: 
Der muss im Kopf fertig sein und wird dann nur noch am Ende auf Papier 
geworfen.)

Danke für den Tipp, war die Richtung also gar nicht so verkehrt. Werde 
das mal umsetzen - ist zwar nur ein Lernstück für mich selber (quasi ein 
LED-Throwie mit RGB-LED und Taster an 'nem ATtiny85 mit Speisung aus 
CR2032), aber genau diesen Zweck (lernen, Probleme machen) erfüllt es 
trotz eigentlich größter Simplizität hervorragend.

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.