Forum: Mikrocontroller und Digitale Elektronik Taste in ISR entprellen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von M. G. (ixil96)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

in diesem Forum gibt es ja etliche Varianten zur Entprellung von Tasten. 
Dabei wird (fast) immer auch erwähnt, eine Tasten Entprellung NICHT in 
einer ISR durchzuführen.

Meine Frage ist warum eigentlich nicht?

Ich möchte z.B. eine Taste per INT0 entprellen und damit den UC auch 
gleichzeitig aus dem sleep Mode wecken.

Dafür habe ich folgende Routine geschrieben, welche eine ISR (INT0) bei 
gedrücktem Taster (active low) auslöst. In der ISR wird der Taster alle 
10µs abgefragt und auf einen stabilen low-Zustand verglichen. Erst wenn 
der low-Zustand 15x in Folge auftritt gilt der Taster als entprellt und 
eine LED toggelt.

Die Tasten Entprellung in der ISR dauert auch nur rund 280µs!
Gibt es an dieser Vorgehensweise etwas auszusetzen? Funktionieren tut 
die Sache prima.
1
#define keyStateIdle_low    1   // pushbutton = active low
2
#define keyStateIdle_high   0   // pushbutton = active high
3
#define keyStateStable      15  // represents the number of stable samples
4
#define sampleTime          5   // represents the delaytime between the samples
5
6
uint8_t sample, i, lowCounter = 0;
7
8
CY_ISR (INT0)
9
{
10
    Pin_Port3_Write(0);                         // P3[5] = low (Measurement Pin start iSR)
11
    
12
    CyGlobalIntDisable;                         // macro
13
    
14
    for (i=0; i<=50; i++)                       // do a maximum of 50 samples
15
    {
16
        sample = Pin_SW2_Read();                // read the pin value of the switch
17
        
18
        Pin_Port3_Write(1);                     // P3[5] only for measuremet
19
        Pin_Port3_Write(0);    
20
        
21
        if (sample != keyStateIdle_low)         // check against idle state of the pushbutton    
22
            lowCounter ++;                      // count the low-samples
23
        else
24
        {
25
            lowCounter = 0;                     // reset lowCounter while pushbutton is not stable
26
            sample = 0;                         // set sample = 0 to avoid an endless loop if sample get high-state
27
        }
28
        
29
        if (lowCounter >= keyStateStable)       // pushbutton is now in a stable condition
30
        {
31
            LED_red_Write (~LED_red_Read());    // toggle red debounced LED
32
            lowCounter = 0;
33
            break;
34
        }
35
        
36
        CyDelayUs(sampleTime);                  // wait for next sample
37
    }
38
39
    INT0_ClearInterrupt();
40
    CyGlobalIntEnable;                          // Enable global interrupts
41
    
42
    Pin_Port3_Write(1);                         // P3[5] = high (Measurement Pin end of iSR)
43
}
44
45
int main()
46
{
47
    CyGlobalIntEnable; /* Enable global interrupts. */
48
49
    Pin_INT0_ISR_StartEx(INT0);
50
    
51
    LED_red_Write (0);
52
    Pin_Port3_Write(1);     // P3[5] = high
53
    
54
    for(;;)
55
    {  
56
        asm("NOP");
57
    }
58
}

: Bearbeitet durch User
von Joachim B. (jar)


Bewertung
0 lesenswert
nicht lesenswert
M. G. schrieb:
> Dabei wird (fast) immer auch erwähnt, eine Tasten Entprellung NICHT in
> einer ISR durchzuführen.
>
> Meine Frage ist warum eigentlich nicht?

interessiert mich auch, ich habe PeDas Entprellroutine in der ISR immer 
gut einsetzen können.

Zykliche ISR Timer 10ms als Taktgeber für anderes

: Bearbeitet durch User
von m.n. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
M. G. schrieb:
> In der ISR wird der Taster alle
> 10µs abgefragt und auf einen stabilen low-Zustand verglichen. Erst wenn
> der low-Zustand 15x in Folge auftritt gilt der Taster als entprellt und
> eine LED toggelt.
>
> Die Tasten Entprellung in der ISR dauert auch nur rund 280µs!
> Gibt es an dieser Vorgehensweise etwas auszusetzen? Funktionieren tut
> die Sache prima.

Die Zeit ist viel zu kurz!

Wie Aufwecken und Entprellen per ISR geht, kannst Du hier sehen:
http://mino-elektronik.de/power_at90s/powerat90s.htm
Zudem sind einige Kurven von realem Prellen eines Tasters gezeigt und 
nicht irgendwelche Kritzeleien von Lieschen Müller.
Das eigentliche Entprellen erledigt ein RC-Glied, welches nach Erkennen 
einer Pegeländerung aktiv aufgeladen oder entladen wird.

von Philipp K. (philipp_k59)


Bewertung
0 lesenswert
nicht lesenswert
Joachim B. schrieb:
>> Dabei wird (fast) immer auch erwähnt, eine Tasten Entprellung NICHT in
>> einer ISR durchzuführen.

Ich denke das ist eher Symbolisch für die aufgeführten Beispiele, dabei 
nicht zuviel in einer ISR zu verarbeiten.

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
M. G. schrieb:
> In der ISR wird der Taster alle
> 10µs abgefragt und auf einen stabilen low-Zustand verglichen. Erst wenn
> der low-Zustand 15x in Folge auftritt gilt der Taster als entprellt und
> eine LED toggelt.

Tastenprellen findet auf ms-Zeitskalen statt. Nimm ein Oszilloskop mit 
Single-Trigger oder einen Logikanalysator und guck dir mal eine 
prellende Taste oder Relaiskontakte damit an.

Wenn dich nur interessiert, ob eine Taste überhaupt betätigt wurde, 
reicht es, beim ersten Wackler zu reagieren und die Taste anschließend 
für die nächsten 100ms zu ignorieren. Zum Zählen von Tastendrücken ist 
es natürlich etwas anderes.

von Gering Schätzer (Gast)


Bewertung
1 lesenswert
nicht lesenswert
m.n. schrieb:
> Zudem sind einige Kurven von realem Prellen eines Tasters gezeigt und
> nicht irgendwelche Kritzeleien von Lieschen Müller.

Wolfgang schrieb:
> Nimm ein Oszilloskop mit
> Single-Trigger oder einen Logikanalysator und guck dir mal eine
> prellende Taste oder Relaiskontakte damit an.

Was soll dieser Unsinn?

Die beiden Bilder des TO sind mit Sicherheit reale Oszillogramme und 
keine "Kritzeleien"!
Auf deren Grundlage hat er ein Programm geschrieben und das funktioniert 
offenbar. Ich selbst tue es auf die gleiche Weise -mit dem gleichen 
Erfolg.
(Wenn auch in einer anderen Programmiersprache)

Der Eindruck verfestigt sich immer mehr: Nur nicht die Arbeit von 
Anderen gutheißen! Alles madig machen und in Frage stellen, wenn es 
nicht von einem selbst erstellt wurde.
:(

von Wolfgang (Gast)


Bewertung
2 lesenswert
nicht lesenswert
Gering Schätzer schrieb:
> Die beiden Bilder des TO sind mit Sicherheit reale Oszillogramme und
> keine "Kritzeleien"!

Die Frage ist, wie das Signal ein paar tausend Betätigungen später oder 
bei einem anderen Tastentyp aussieht und ob die Routine dann auch noch 
funktionieren soll. Daher mein Hinweis, dass er sich doch mal andere 
prellende Kontakte ansehen und auf die Zeitskalen achten soll. Wenn man 
sich bei Googlesuche nach "tastenprellen" verschiedene 
Zeitaufzeichnungen ansieht, kann ein Zeitfenster von insgesamt 150µs 
schon arg knapp sein.

War nur gut gemeint, sorry.

von Walter S. (avatar)


Bewertung
2 lesenswert
nicht lesenswert
Gering Schätzer schrieb:
> Alles madig machen und in Frage stellen, wenn es
> nicht von einem selbst erstellt wurde.

ich bezweifele nicht die Messung eines einzelnen neuen Tasters, ich kann 
dir aber beliebig viele Taster zeigen die deutlich länger prellen, ist 
das madig machen?

von Thomas E. (picalic)


Bewertung
0 lesenswert
nicht lesenswert
Gering Schätzer schrieb:
> Auf deren Grundlage hat er ein Programm geschrieben und das funktioniert
> offenbar.

Die Frage ist: Funktioniert es auch noch, wenn der Taster schon ein 
halbes Jahr in Betrieb ist? Oder wenn der Taster mal ein paar Wochen 
nicht betätigt wurde? Oder - falls der TO Entwickler eines 
Serienproduktes ist - bei welchem Prozentsatz der gebauten Geräte 
funktioniert es, zumindest über die Gewährleistung?

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
p.s.
Auserdem möchte man solche Abfrage- und Delay-Schleifen i.A. nicht 
systemblockierend in der ISR haben. Aber da kommt es natürlich drauf an, 
ob der µC sonst noch etwas zu tun hat und wie zeitkritisch das ist.

von Rudolph R. (rudolph)


Bewertung
0 lesenswert
nicht lesenswert
Der Punkt ist ja nicht, das grundsätzlich nicht in einer ISR zu machen.
Der Punkt ist der, das nicht in einer Pin-Change ISR zu machen um nicht 
xxx Interrupts zu bekommen.

Wofür drölfzig Interrupts generieren lassen die alles andere aufhalten, 
wenn eine Reaktion innerhalb xx ms völlig ausreichend ist?

Joachim B. schrieb:
> interessiert mich auch, ich habe PeDas Entprellroutine in der ISR immer
> gut einsetzen können.
> Zykliche ISR Timer 10ms als Taktgeber für anderes

Das ist eine ganz andere Lösung, vollkommen in Ordnung so wenn das 
nicht-wartend implementiert ist und an dem vorbei was Entprellung per 
ISR zum Problem macht.

von M. G. (ixil96)


Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:
> Gering Schätzer schrieb:
>> Auf deren Grundlage hat er ein Programm geschrieben und das funktioniert
>> offenbar.
>
> Die Frage ist: Funktioniert es auch noch, wenn der Taster schon ein
> halbes Jahr in Betrieb ist? Oder wenn der Taster mal ein paar Wochen
> nicht betätigt wurde? Oder...

Die Routine passt sich dem Prellverhalten des Tasters automatisch an!
Solange ein stabiles Signal (hier low) nicht mindestens 15Mal in Folge 
erkannt wurde, wird der Zähler mit lowCounter=0 zurück gesetzt und die 
Geschichte beginnt von vorne.
1
if (sample != keyStateIdle_high)        // check against idle state of the pushbutton  
2
            highCounter ++;                     // count the low-samples
3
        else
4
        {
5
            highCounter = 0;           // reset lowCounter while pushbutton is not stable
6
            sample = 0;    // set sample = 0 to avoid an endless loop if sample get high-state
7
        }
Damit passt sich auch die Länge der Entprellzeit (so kurz wie möglich 
und so lange als nötig) an den jeweiligen Taster an. Für extrem 
prellende Taster müsste die Anzahl der Durchläufe und Samples 
entsprechend erhöht werden.

von Joachim B. (jar)


Bewertung
0 lesenswert
nicht lesenswert
M. G. schrieb:
> Dafür habe ich folgende Routine geschrieben, welche eine ISR (INT0) bei
> gedrücktem Taster (active low) auslöst. In der ISR wird der Taster alle
> 10µs abgefragt und auf einen stabilen low-Zustand verglichen. Erst wenn
> der low-Zustand 15x in Folge auftritt gilt der Taster als entprellt und
> eine LED toggelt.

so schnell ist kein Mensch und auch kein Taster, es ist also unnötig 
alle 10µs abzufragen und 15x -> 150µs(gesamt 280µs) braucht keiner.

PeDas 4x Abtastung bullet proof alle 10ms reicht dicke damit kein 
Tastendruck entgeht und die Belastung in der ISR alle 10ms hält sich für 
mich mit wenigen µs in Grenzen, sogar die IRMP kommt noch durch, bzw. 
kann eingeschachtelt werden, sowie die RTC lesen um den 10ms Counter zu 
synchronisieren.

: Bearbeitet durch User
von m.n. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Gering Schätzer schrieb:
> Die beiden Bilder des TO sind mit Sicherheit reale Oszillogramme und
> keine "Kritzeleien"!

Die meinte ich garnicht, sondern so etwas: 
https://www.mikrocontroller.net/wikifiles/2/26/Entprellen.png

Rudolph R. schrieb:
> Der Punkt ist der, das nicht in einer Pin-Change ISR zu machen um nicht
> xxx Interrupts zu bekommen.

Mit einem zusätzlichen RC-Glied bekommt man genau einen Interrupt. Siehe 
oben.

M. G. schrieb:
> Die Routine passt sich dem Prellverhalten des Tasters automatisch an!
> Solange ein stabiles Signal (hier low) nicht mindestens 15Mal in Folge
> erkannt wurde, wird der Zähler mit lowCounter=0 zurück gesetzt und die
> Geschichte beginnt von vorne.

Das reicht aber nicht aus, denn 150 µs konstanter Pegel ist keine 
ausreichende Zeit. Interessant wird die Geschichte nämlich dann, wenn 
man eine Taste gedrückt hält und sie in diesem Zustand Prellen erzeugt. 
Diese Knackfroschtaster mit schnell rostenden Kontakten sind ein schönes 
Beispiel dafür.
Nimm 1 ms als Abfrageintervall, aber dann wird die Zeit im Interrupt 
deutlich zu lang.

Gering Schätzer schrieb:
> Der Eindruck verfestigt sich immer mehr: Nur nicht die Arbeit von
> Anderen gutheißen! Alles madig machen und in Frage stellen, wenn es
> nicht von einem selbst erstellt wurde.

Wenn ich das vorgehabt hätte, wäre ich auf das Programm selber 
eingegangen.
Ausgehend von einem AVR ist diese Anweisung zum Beispiel unsinnig:

    CyGlobalIntDisable;                         // macro

Joachim B. schrieb:
> so schnell ist kein Mensch und auch kein Taster, es ist also unnötig
> alle 10µs abzufragen und 15x -> 150µs(gesamt 280µs) braucht keiner.

Wenn man ein bißchen über den Tellerrand schaut, können durchaus kurze 
Reaktionzeiten erforderlich sein. Beispielsweise um die Schaltkontakte 
von Relais' insbesondere Reedrelais' auszuwerten. Es muß ja keine Person 
sein, die etwas drückt, sondern z.B. auch ein 'vorbeifliegender' Magnet.

von Rudolph R. (rudolph)


Bewertung
0 lesenswert
nicht lesenswert
m.n. schrieb:
>> Der Punkt ist der, das nicht in einer Pin-Change ISR zu machen um nicht
>> xxx Interrupts zu bekommen.
>
> Mit einem zusätzlichen RC-Glied bekommt man genau einen Interrupt. Siehe
> oben.

Ja, wenn das richtig dimensioniert ist.
Nur, das ist dann keine Entprellung in Software mehr und somit ebenfalls 
am "Problem" vorbei.

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
M. G. schrieb:
> Ich möchte z.B. eine Taste per INT0 entprellen und damit den UC auch
> gleichzeitig aus dem sleep Mode wecken.

Hier mal Entprellen mit Sleep. Es sind 2 völlig eigenständige Tasks. 
Daher behindern sie sich nicht gegenseitig und das Programm läßt sich 
gut erweitern.

Beitrag "AVR Sleep Mode / Knight Rider"

von m.n. (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
Rudolph R. schrieb:
> Nur, das ist dann keine Entprellung in Software mehr und somit ebenfalls
> am "Problem" vorbei.

Um das zu beurteilen, solltest Du Dir die Software auch ansehen und 
verstehen. Die Software sorgt fürs Aufwachen und die deutliche Erhöhung 
der Hysterese.

Will man es in Hardware machen, sieht es so aus: 
Beitrag "Taster per Hardware entprellen – alternative Schaltung"

von Thomas E. (picalic)


Bewertung
0 lesenswert
nicht lesenswert
M. G. schrieb:
> Gibt es an dieser Vorgehensweise etwas auszusetzen? Funktionieren tut
> die Sache prima.

Und wo ist die Entprellung für das Loslassen der Taste? Wenn eine 
gedrückte Taste schon als "stabil" erkannt wurde, und nur ein einziges 
Sample nochmal High-Pegel liefert, führt das schon zum Erkennen eines 
erneuten Tastendrucks - oder habe ich was übersehen?

von Rudolph R. (rudolph)


Bewertung
1 lesenswert
nicht lesenswert
m.n. schrieb:
>> Nur, das ist dann keine Entprellung in Software mehr und somit ebenfalls
>> am "Problem" vorbei.
>
> Um das zu beurteilen, solltest Du Dir die Software auch ansehen

Ein zusätzliches RC-Glied ist keine Software.

von m.n. (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
Thomas E. schrieb:
> Und wo ist die Entprellung für das Loslassen der Taste?

Schon wieder einer, der alles madig machen will ;-)

Rudolph R. schrieb:
>> Um das zu beurteilen, solltest Du Dir die Software auch ansehen
>
> Ein zusätzliches RC-Glied ist keine Software.

Wenn Du nicht vertstehen kannst/willst, laß es sein.

von Rudolph R. (rudolph)


Bewertung
1 lesenswert
nicht lesenswert
m.n. schrieb:
>> Ein zusätzliches RC-Glied ist keine Software.
>
> Wenn Du nicht vertstehen kannst/willst, laß es sein.

Die Kindergarten-Rethorik kannst Du Dir sparen und noch mal gaaaanz 
langsam nachlesen.

von Winfried M. (win)


Bewertung
0 lesenswert
nicht lesenswert
M. G. schrieb:
> eine Tasten Entprellung NICHT in
> einer ISR durchzuführen.
>
> Meine Frage ist warum eigentlich nicht?

Du verschenkst mit deiner Vorgehensweise sehr viel Zeit. So Daumenregel 
ist, in einer ISR so kurz wie möglich zu verbringen. Wenn ich da 
Abfrageschleifen sehe, wo x-mal ein Pin abgefragt wird, schrillen bei 
mir die Alarmglocken.

Dein Ansatz ist auch schlecht zeitlich anpassbar. Wenn du einen 
Prozessor mit schnellem Takt hast, müsstest du Zeitschleifen in deiner 
ISR einbauen. Ebenso, wenn du stark prellende Tasten hast.

Mag sein, dass im konkreten Anwendungsfall es keine Rolle spielt, wenn 
du mal einige ms in einer ISR hängen bleibst. Aber Tastenentprellung ist 
ja stark wiederverwendbarer Code, den man immer und überall wieder 
einbaut. Das sollte dann schon universeller Code sein, der in jeder 
Situation funktioniert und nicht das Hauptprogramm ausbremst.

Das sind so einige Gründe, warum sich ein Konzept über eine Timer-ISR 
als viel günstiger erweist.

von A. S. (achs)


Bewertung
0 lesenswert
nicht lesenswert
Ich fasse also zusammen:

a) Zum aufwecken und irgendwas tun braucht es kein entprellen. Es reicht 
das das erste Low und danach 100ms ignoriere (abschalten).

b) 100ms ist die Zeit, die Mensch von einem zum nächsten Tastendruck 
braucht, bzw. die Zweit zwischen 2 Drücken.

c) Wenn man keine Entprellung braucht und auch keine ISR (z.B. für 
Uarts), dann kann man in der ISR auch entprellen.

d) Wenn man Tastendrücke zählen muss (um z.B. nach genau 5 Drücken etwas 
zu tun), dann reichen 10ms Timerinterrupts und 2-3 gleiche Signale. Wenn 
es viel prellt, dann auch gerne 5ms und 4-5 gleiche Signale, sowohl für 
High- als auch für Low.

e) Es gibt eine Technik bei Knackfröschen, die Zeit für einen 
Tastendruck (b) zu halbieren. Indem man wie bei einem Rubbellos hin und 
her rubbelt. Wenn man das unterstützten will (z.B. um lange Listen mit 
einer Taste durchzugehen), dann muss man die Zeiten oben ebenso 
halbieren.

von Reiner W. (reiner_w)


Bewertung
0 lesenswert
nicht lesenswert
Die verwendeten Macros CyGlobalIntDisable etc. deuten auf ein PSoC 
Cypress Umfeld hin.
Je nach verwendetem Baustein haben die zur Entstellung ja Debouncer 
und/oder Glichtfilter Komponenten integriert, die das perfekt erledigen.
Ich habe mich vor einiger Zeit mal in die Teile eingearbeitet. Was bei 
den damaligen Versuchen hängen blieb, ist die schlechte 
Reproduzierbarkeit von "Prellen". Je nach Schalter/Taster/Kraft beim 
Drücken usw. ergaben sich immer andere Zeiten - wobei die Alterung noch 
gar nicht berücksichtigt wurde.
Eine Abtastung von ca. 1ms war ziemlich optimal.

Sicher kann man das auch in der ISR wie im Beispiel machen. Allerdings 
ergibt sich per Abtastung i.d.R. eine geringere Systemlast.
Und es spricht auch nichts dagegen Abtastung (Timer ISR) und Taster-IR 
zu kombinieren.
Taster IR startet den Abtasttimer, der dann für x ms läuft.
Das mach ich bei Drehgebern seit einiger Zeit so, falls ich nicht 
ohnehin einen ms Timer-Event im Programm brauche.

von Sebastian S. (amateur)


Bewertung
0 lesenswert
nicht lesenswert
Es gibt nur einen Grund das Entprellen in einer ISR zu verbieten:
Der Grübler hat sonst noch was zu tun.

Für einen Menschen bedeutet diese kurze Zeit der Blockade Garnichts. 
Wenn aber im Hintergrund noch was abgeht z.B. eine schnelle, serielle 
Übertragung oder ähnlicher Schweinkram, dann kann es schon mal sein, 
dass ein Zeichen im Nirwana landet. Das Tastenprellen dauert ja nicht 
Mikrosekunden, sondern Millisekunden – und zwar einige. Nach Murphy 
kommt es genau in dieser Zeitspanne zum Empfangspufferüberlauf, oder bei 
einer großen Masse zum Kontakt mit einem Endschalter.

Aber wie gesagt: Hat das Teil nichts zu tun ist das auch kein Problem.

von Joachim B. (jar)


Bewertung
0 lesenswert
nicht lesenswert
Sebastian S. schrieb:
> Es gibt nur einen Grund das Entprellen in einer ISR zu verbieten:
> dass ein Zeichen im Nirwana landet. Das Tastenprellen dauert ja nicht
> Mikrosekunden, sondern Millisekunden – und zwar einige

ich bin sicher du hast das überhaupt nicht verstanden

in der ISR dauert Portlesen und auswerten keine Millisekunden sondern 
nach letzten Messungen irgenwas im kleinen einstelligen µs Bereich, 
inclusive PaDas Berechnung.

Wer innerhalb von diesen einstelligen µs was verliert hat andere 
Probleme oder falsch programmiert, Zeichen im Nirwana? wie soll das 
gehen.

In der ISR gehört natürlich kein delay

man liest die Taste xodert und gut ist

Im main loop liest man die Taste bei Bedarf löscht das gesetzte Bit und 
gut ist.

Vielleicht erklärst du deine Bedenken verständlicher, mir ist da noch 
nichts passiert oder aufgefallen was an PeDas Entprellroutine in der ISR 
gestört haben soll.

von Axel S. (a-za-z0-9)


Bewertung
0 lesenswert
nicht lesenswert
Die Menge an Halbwissen in diesem Thread ist mal wieder besonders 
ergötzlich. Das geht schon beim TE los:

> Dabei wird (fast) immer auch erwähnt, eine Tasten Entprellung NICHT in
> einer ISR durchzuführen.

Und wiederholt sich in 1001 Variationen von:

Joachim B. schrieb:
> In der ISR gehört natürlich kein delay

Das Problem ist, daß keiner auch nur einen Gedanken an den Kontext 
dieser Beschränkung verschwendet. Wenn es um einen µC geht, der gerade 
aktiv eine Aufgabe erledigt und diese Aufgabe für eine ISR unterbricht, 
dann ist es vollkommen richtig, daß mal in der ISR tunlichst kein 
delay() - oder jegliche andere Variante von blockierendem Warten - 
verwenden sollte.

ABER

Der TE schreibt ja gleich darauf, daß die Taste den µC aus dem Schlaf 
wecken soll. Das heißt der µC tut nichts. Und hat auch nichts zu tun, 
solange bis er sicher weiß, daß die Taste wirklich gedrückt wurde und 
ihn nicht nur ein Störimpuls aus der womöglich verseuchten Umgebung 
geweckt hat. Und dann ist es vollkommen legitim, in der ISR die Taste 
zu entprellen oder delay() zu verwenden. Es gibt ja schließlich nichts 
anderes zu tun.

---

OK, ob es nun besonders clever ist, in der ISR zu blockieren, steht 
natürlich nochmal auf einem anderen Blatt. Wenn die Taste die einzige 
Möglichkeit ist, den µC aus dem Schlaf zu wecken, dann muß man in der 
ISR gar nichts machen, sondern kann im Hauptprogramm direkt nach dem 
Aufruf von sleep_cpu() davon ausgehen, daß man an diese Stelle im 
Programm nur dadurch gelangt sein kann, daß die Taste gedrückt wurde. 
Und dann schreibt man die Entprellung genau dahin:

1
int main()
2
{
3
  initialisierung();
4
  while (1) {
5
    sleep_cpu();
6
    if (entprelle_taste()) {
7
      tu_was();
8
    }
9
    else {
10
      /* vermutlich nichts */
11
    }
12
  }
13
}

Oder man will den µC in dem Dutzend Millisekunden das die Entprellung 
braucht, ein bißchen weniger Strom verbrauchen lassen. Dann kann man mit 
einem Timer entprellen und schickt den µC zwischen den Timer-Interrupts 
zumindest in den idle Mode.

Das sind alles valide Gründe, es anders zu machen. Aber die 
Daumenregel "kein delay() in einer ISR" greift hier mal gar nicht.

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Axel S. schrieb:
> Der TE schreibt ja gleich darauf, daß die Taste den µC aus dem Schlaf
> wecken soll. Das heißt der µC tut nichts.

Aber nur unter der Voraussetzung, dass das Aufwecken die einzige 
Funktion ist, die der Taster haben soll. So wie der Code oben steht, 
bleibt der Interrupt aber nach dem Aufwecken an, also kann auch 
jederzeit im laufenden Betrieb durch einen Tastendruck der Interrupt 
ausgelöst werden, und das Programm bleibt für die Dauer der Entprellung 
stehen.

von m.n. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Aber nur unter der Voraussetzung, dass das Aufwecken die einzige
> Funktion ist, die der Taster haben soll.

Wenn man kein Angsthase ist und weiß, was man tut, kann man in einer ISR 
alle anderen ISRs global auch wieder freigeben und blockiert diese damit 
nicht. Aber das hatten wir ja schon alles an anderen Stellen.

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
m.n. schrieb:
> Rolf M. schrieb:
>> Aber nur unter der Voraussetzung, dass das Aufwecken die einzige
>> Funktion ist, die der Taster haben soll.
>
> Wenn man kein Angsthase ist und weiß, was man tut, kann man in einer ISR
> alle anderen ISRs global auch wieder freigeben und blockiert diese damit
> nicht.

Das ändert nichts daran, dass das Hauptprogramm so lange stehen bleibt. 
Besser, als zu versuchen, die Auswirkungen von Murks mit noch mehr Murks 
zu umgehen, ist, es gleich richtig zu machen.

> Aber das hatten wir ja schon alles an anderen Stellen.

Ja.

von Joachim B. (jar)


Bewertung
0 lesenswert
nicht lesenswert
Axel S. schrieb:
> Das sind alles valide Gründe, es anders zu machen. Aber die
> Daumenregel "kein delay() in einer ISR" greift hier mal gar nicht.

wenn nur der µC von der Taste aufgeweckt werden soll und sonst nie 
abgefragt wird hast du Recht, aber dann brauchts auch keine Entprellung, 
in sofern verstehe ich deine Aussage absolut nicht!

µC pennt, Taste an /INT0 fertig, evtl. noch ein RTI bzw. leerer IRQ0 
Vector der aus einem weiteren /Int0 IRQ einfach zurück kommt nach dem 
Prellen, so denke ich mir das gerade, kann mich auch irren, dann würde 
ich um mehr Info bitten.

von m.n. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Joachim B. schrieb:
> µC pennt, Taste an /INT0 fertig, evtl. noch ein RTI bzw. leerer IRQ0
> Vector der aus einem weiteren /Int0 IRQ einfach zurück kommt nach dem
> Prellen, so denke ich mir das gerade, kann mich auch irren, dann würde
> ich um mehr Info bitten.

Damit kann jeder Störimpuls den µC ein- und ggf. auch wieder 
ausschalten.
Will man das?

von Joachim B. (jar)


Bewertung
0 lesenswert
nicht lesenswert
m.n. schrieb:
> Joachim B. schrieb:
>> µC pennt, Taste an /INT0 fertig, evtl. noch ein RTI bzw. leerer IRQ0
>> Vector der aus einem weiteren /Int0 IRQ einfach zurück kommt nach dem
>> Prellen, so denke ich mir das gerade, kann mich auch irren, dann würde
>> ich um mehr Info bitten.
>
> Damit kann jeder Störimpuls den µC ein- und ggf. auch wieder
> ausschalten.
> Will man das?

??? deine Gedanken bitte etwas deutlicher.

Es soll ja pullups geben, auch externe wenns nötig ist und sollten diese 
ominösen Störimpulse mal stärker sein nimmt man einen 1 Ohm pullup und 
einen 5A Taster, wenn dann noch ein Störimpuls durchkommt dann dürfte 
der Chip vom EMP eh gegrillt werden.

Man kann auf alles eine negierte Antwort liefern, nur sind sie nicht 
immer sinnvoll.

: Bearbeitet durch User
von m.n. (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Joachim B. schrieb:
> Man kann auf alles eine negierte Antwort liefern, nur sind sie nicht
> immer sinnvoll.

Stimmt ;-)
Du kannst auch einen Schalter verwenden. Je kleiner die Welt, desto 
einfacher die Lösungen.

von Yalu X. (yalu) (Moderator)


Bewertung
0 lesenswert
nicht lesenswert
Axel S. schrieb:
> Das Problem ist, daß keiner auch nur einen Gedanken an den Kontext
> dieser Beschränkung verschwendet.

Die altbekannte Regel

1
  Der Interrupthandler darf nur minimal Rechenzeit verbrauchen.

stammt ursprünglich aus der Programmierung unter Multitasking-
Betriebssystemen, wo sie durchaus ihre Berechtigung hat.

Bei der Bare-Metal-Programmierung, wie sie auf Mikrocontrollern (vor
allem auf kleineren) üblich ist, gilt diese Regel nur eingeschränkt und
hängt – wie du geschrieben hast – stark vom jeweiligen Kontext ab.
Trotzdem wird sie von vielen als strenges Gesetz (mit mindestens 1000
Peitschenhieben bei Zuwiderhandlung) angesehen.

Ähnlich sinnlos streng wird die folgende Regel gehandhabt:

1
Eine zyklische Aktivität muss durch einen (Timer-)Interrupt gesteuert
2
werden.

Die Erfüllung beider "Gesetze" gleichzeitig führt dann zu Unfug wie
diesem hier (hier im Forum schon mehrfach erlebt):

1
bool flag;
2
3
ISR(TIMER0_OVF_vect) {
4
  flag = true;   // ISR enthält nur diese eine Anweisung
5
}
6
7
int main(void) {
8
  for(;;) {
9
    if(flag) {
10
      flag = false;
11
      // tu was
12
    }
13
    // tu was anderes (oder auch nicht)
14
  }
15
}

Gerade (aber nicht nur) bei der Mikrocontrollerprogrammierung ist
Nachdenken wichtiger als stumpfes Befolgen von (meist zweifelhaften)
Regeln.

m.n. schrieb:
> Wenn man kein Angsthase ist und weiß, was man tut, kann man in einer ISR
> alle anderen ISRs global auch wieder freigeben und blockiert diese damit
> nicht.

Dafür ist die zweite Bedingung (wissen, was man tut) schon aureichend :)
Und ja, es ist überhaupt nichts Schlimmes und durchaus üblich, einen
Interrupthandler unterbrechen zu lassen.

Rolf M. schrieb:
> Das ändert nichts daran, dass das Hauptprogramm so lange stehen bleibt.

Bei mir steht das Hauptprogramm in praktisch jeder etwas komplexeren
Anwendung fast ständig. Für Interessierte veröffentliche ich hier den
(sogar wiederverwendbaren) Quellcode dazu:

1
int main(void) {
2
  init();
3
  for(;;)
4
    sleep_cpu();
5
}

Trotzdem käme ich nie auf die Idee, die Aussage

1
Das Hauptprogramm darf fast nichts tun.

als Regel (oder gar als Gesetz) zu verabschieden, denn es gibt durchaus
(wenn auch nicht sehr häufig) µC-Anwendungen, wo die 100%-ige Nutzung
der Rechenkapazität sinnvoll ist.

von Axel S. (a-za-z0-9)


Bewertung
0 lesenswert
nicht lesenswert
Joachim B. schrieb:
> m.n. schrieb:
>> Joachim B. schrieb:
>>> µC pennt, Taste an /INT0 fertig, evtl. noch ein RTI bzw. leerer IRQ0
>>> Vector der aus einem weiteren /Int0 IRQ einfach zurück kommt nach dem
>>> Prellen, so denke ich mir das gerade, kann mich auch irren, dann würde
>>> ich um mehr Info bitten.
>>
>> Damit kann jeder Störimpuls den µC ein- und ggf. auch wieder
>> ausschalten. Will man das?
>
> Es soll ja pullups geben, auch externe wenns nötig ist und sollten diese
> ominösen Störimpulse mal stärker sein nimmt man einen 1 Ohm pullup und
> einen 5A Taster

Störimpulse unterdrückt man nicht mit niederohmigeren Pullups. Schon 
eher mit RC-Gliedern (das wäre dann die "Mino-Methode") oder - wenn man 
sowieso schon einen µC hat - mit ein paar Zeilen Code.

Diese Diskussion findest du in nahezu jedem Thread zum Thema "Tasten 
entprellen - Hardware oder Software?"

Womit du allerdings recht hast und was auch weiter oben schon mehrfach 
gesagt wurde: wenn es nur darum geht, den µC per Taste einzuschalten, 
dann muß man die Taste gar nicht komplett entprellen. Meint: man muß 
nicht warten, bis das Prellen aufgehört hat. Man muß nur lange genug 
testen, bis man weiß daß es wirklich ein Tastendruck ist und keine 
Störung. Die eigentliche Entprellung muß man für das Loslassen der 
Taste machen. Denn erst wenn die Taste das Prellen nach dem Loslassen 
beendet hat, darf man den Interrupt zum Aufwachen aus dem Schlaf wieder 
scharf machen.

von Bernd B. (bbrand)


Bewertung
0 lesenswert
nicht lesenswert
Axel S. schrieb:
> Das Problem ist, daß keiner auch nur einen Gedanken an den Kontext
> dieser Beschränkung verschwendet.

Muss man auch nicht. Idealerweise sollte ein Programm bzw. eine Funktion 
oder eben ein Interrupthandler so geschrieben werden, dass die 
einwandfreie Funktion immer gegeben ist und nicht vom aktuellen 
Kontext abhängt, sonst fängt man sich bei einer eventuellen späteren 
Änderung Probleme ein.

Ist im übertragenen Sinn genauso wie die Verwendung von 
Abblockkondensatoren. Nur weil eine Schaltung auch ohne funktioniert, 
heißt das noch lange nicht, dass man sie einfach weglassen sollte.

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Yalu X. schrieb:
> Die Erfüllung beider "Gesetze" gleichzeitig führt dann zu Unfug wie
> diesem hier (hier im Forum schon mehrfach erlebt):
>
> bool flag;
>
> ISR(TIMER0_OVF_vect) {
>   flag = true;   // ISR enthält nur diese eine Anweisung
> }

Was soll daran Unfug sein, das mache ich in allen Programmen so. Nur 
macht der Timerinterrupt nebenbei noch andere Sachen (z.B. Uptime 
zählen, Entprellen, Encoder einlesen).
Das Flag gibt dann dem Main die Struktur, nicht alles unnötig oft zu 
machen bzw. in einem definierten Zeitraster (PID-Regelung, LED blinken).

Yalu X. schrieb:
> Bei mir steht das Hauptprogramm in praktisch jeder etwas komplexeren
> Anwendung fast ständig.

Sleep kommt generell in keines meiner Programme, erstmal muß die 
Funktion stabil laufen, das hat absoluten Vorrang.
Nur wenn es auch einen Nutzwert hat (Batteriebetrieb, 
Kondensatornetzteil, Busspeisung), kommt das Sleep ganz zum Schluß dazu:

Beitrag "AVR Sleep Mode / Knight Rider"

von Yalu X. (yalu) (Moderator)


Bewertung
0 lesenswert
nicht lesenswert
Peter D. schrieb:
> Was soll daran Unfug sein, das mache ich in allen Programmen so.

Wenn der Interrupthandler nichts weiter tut, als ein Software-Flag zu
setzen, braucht man keinen Interrupt, sondern fragt stattdessen im
Hauptprogramm das Hardware-Flag ab.

> Nur macht der Timerinterrupt nebenbei noch andere Sachen (z.B. Uptime
> zählen, Entprellen, Encoder einlesen).

Das ist ja völlig in Ordnung. Aber der Anfänger, dem tausendmal
eingeredet wird, den Interrupthandler möglichst kurz halten, wird
versuchen, auch solche Dinge im Hauptprogramm – gesteuert durch ein
Software-Flag – abzuarbeiten.

> Sleep kommt generell in keines meiner Programme, erstmal muß die
> Funktion stabil laufen,

Man kann für Tests das sleep auch weglassen. Dann bleibt die main-
Funktion einfach leer und läuft nach Beendigung in eine Endlosschleife.
Das ändert nichts an der Tatsache, dass main praktisch nichts tut.

von Winfried M. (win)


Bewertung
0 lesenswert
nicht lesenswert
Axel S. schrieb:
> Das Problem ist, daß keiner auch nur einen Gedanken an den Kontext
> dieser Beschränkung verschwendet.

Damit liegst du definitiv falsch. Ich kenne meine Gedanken. ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.