Taster am ISR-PIN entprellen

OP #2280659
Lesenswert?

Guten Tag zusammen,

Ich habe einen Taster an einem Interupt-PIN und wenn ich diesen Taster 
Drücke, löse ich einen Interupt aus, und das Programm springt in die 
ISR.
Aber wie entprelle ich dies? Wenn ich den Taster ohne Interupt nutze 
geht das mit debounce. Aber wie mache ich es, wenn ich den Taster als 
Interupt nutzen möchte?

Gruß und Danke
Snatch
#2280703
Lesenswert?

Oliver H. schrieb:
> Na dann bleibt mir nur die
> Hardwareentprellung.

Nö.
Du nimmst einfach die bewährte Entprellroutine mit Timerinterrupt 
(4-fach Abtastung, bis zu 8 Tasten parallel).
Und die Auswertung der wichtigen Taste machst Du gleich am Ende des 
Timerinterrupts.

Du mußt aber beachten, daß Du das Main unterbrochen hast an irgendeiner 
völlig zufälligen Stelle. Die Aktionen im Interrupthandler müssen daher 
sehr überlegt erfolgen.
Daher vermeidet man gerne solchen fehlerträchtigen Programmierstil und 
teilt die Mainloop in kleine Tasks auf, damit sie schnell wieder zur 
Tastenabfrage kommt.


Peter
Moderator (Firma: Titel) Persönliche Seite #2280712
Lesenswert?

Oliver H. schrieb:
> Ja, aber die funktion die ich damit schalte ist ein sehr wichtige und
> diese muss IMMER egal wo und wie und was das Programm macht gehen. Daher
> habe ich den Interupt verwendet.
Ich vermute eher, dein Programmkonzept ist falsch.
Die Hauptschleife eines Programms muß in bestimmter Zeit (z.B. 20ms) 
mindestens einmal durchlaufen werden. Dann mußt du in einer 
Interruptroutine nur ein Flag setzen, und das in der Mainloop abfragen. 
Spätestens nach 20ms wird die Routine aus der Hauptschleife 
angesprungen. Wenn deine Hauptschleife länger braucht, dann ist das 
(bzw. hast du noch irgendwo) einen Fehler im Programm.
OP #2280834
Lesenswert?

Naja, kann sein.
Aber ich habe z.B. ein Menü, welches in einer While Schleife läuft und 
so lange ich im Menü bin ist nichts mit Hauptschleife. Ich wüsste nun 
auch nicht, wie ich das auch die schnelle anders lösen sollte.

Des weiteren frage ich einige Senoren ab, schreibe ins EEprom und 
versende und empfange Daten über RS232 was auch in den jeweiligen Subs 
einiges ein Zeit in Anspruch nimmt. Wie soll ich es da gewährleisten, 
dass mind. alle 20 ms die do-loop-schleife angesprungen wird?

Gruß
Snatch
OP #2280836
Lesenswert?

Dietrich L. schrieb:
> Peter Dannegger schrieb:
>> Garnicht.
>
> So hart würde ich das nicht sagen.
>
> Man kann z.B. in der ISR diesen Interrupt abschalten und einen Timer
> starten. Nach Ablauf der Zeit wird das Interrupt-Flag gelöscht und der
> Interrupt wieder eingeschaltet.
>
> Ich habe das noch nicht gemacht, nur so eine Idee, daher ohne Garantie.
>
> Gruß Dietrich

Ich habe so etwas ähnliches mal versucht. Ich habe in der ISR ganz oben 
den Interupt deaktiviert und ganz unten wieder aktiviert. Hat aber 
leider nichts geklappt.
#2280842
Lesenswert?

Oliver H. schrieb:
> Ich habe so etwas ähnliches mal versucht. Ich habe in der ISR ganz oben
> den Interupt deaktiviert und ganz unten wieder aktiviert. Hat aber
> leider nichts geklappt.

Das ist aber nicht etwas "ähnliches", sondern etwas völlig anderes. Der 
Interrupt soll erst nach Ablauf eines Timers wieder angeschaltet werden, 
wenn sichergestellt ist, dass sie Prellphase vorüber ist.
#2280865
Lesenswert?

Oliver H. schrieb:
> Naja, kann sein.
> Aber ich habe z.B. ein Menü, welches in einer While Schleife läuft und
> so lange ich im Menü bin ist nichts mit Hauptschleife. Ich wüsste nun
> auch nicht, wie ich das auch die schnelle anders lösen sollte.


In der Menüschleife kann man die wichtigen Tasten ja auch noch 
zusätzlich auswerten. Ob du jetzt nur auf Oebn/Unten/Links/Rechts und 
Enter prüfst oder zusätzlich noch den Notaus mit in die Tastenauswertung 
reinnimmst, ist auch schon egal.

> Des weiteren frage ich einige Senoren ab, schreibe ins EEprom und
> versende und empfange Daten über RS232 was auch in den jeweiligen Subs
> einiges ein Zeit in Anspruch nimmt. Wie soll ich es da gewährleisten,
> dass mind. alle 20 ms die do-loop-schleife angesprungen wird?

Gar nicht.
Diese Dinge passieren IN der do-loop.
Das ist ja der ganze Trick an der Sache.
Persönliche Seite #2280934
Lesenswert?

So könntest du das dann lösen (BASCOM):
1
Dim Button1 As Bit
2
Dim Button1_flag As Bit
3

4
Do
5
  'Bei jedem Tastendruck toggeln
6
  If Button1 = 1 Then
7
    Toggle PORTB.1
8
    Button1 = 0
9
  End If
10
  
11
  'Solange an, wie der Taster gedrückt ist
12
  If Button1_flag = 1 Then
13
    PORTB.2 = 1 
14
  Else
15
    PORTB.2 = 0
16
  End If
17
Loop
18

19
Isr:
20
  If PINB.0 = 0 Then
21
    If Button1_flag = 0 Then Button1 = 1
22
    Button1_flag = 1
23
  Else
24
    Button1_flag = 0
25
  End If
26
Return

Button1 wird nur ein Mal jedes Drücken gesetzt. Button1_flag bleibt so 
lange gesetzt, wie der Taster gedrückt ist.


Gruß
Jonathan

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