Forum: Mikrocontroller und Digitale Elektronik Fragen zur Taster Entprellung von PeDa


von avr (Gast)


Lesenswert?

Hi,
Ich hab grad mal versucht, die Tasterentprellung von PeDa in der 
C-Version nachzuvollziehen und hab zwei Fragen dazu:

1.) Im Worst-Case wird der Tastendruck erst "prelldauer" + 4*10ms später 
registriert, richtig? Für mich liest sich das so, dass erst, wenn 4x 
nacheinander der gleiche Zustand gelesen wird, dieser als gültig 
angenommen wird. Und gelesen wird alle 10ms. Stimmt das so?

2.) cli() wird in jedem Schleifendurchlauf der main 4x aufgerufen - 
wahrscheinlich in deutlich kürzeren Intervallen, als 10ms. Bei jedem 
dieser Aufrufe werden doch die Interrupts gestoppt. Wieso wird dann die 
Interrupt Routine überhaupt mal aufgerufen?!

Viele Grüße

:
von Andreas B. (bitverdreher)


Lesenswert?

avr schrieb:

> 1.) Im Worst-Case wird der Tastendruck erst "prelldauer" + 4*10ms später
> registriert, richtig? Für mich liest sich das so, dass erst, wenn 4x
> nacheinander der gleiche Zustand gelesen wird, dieser als gültig
> angenommen wird. Und gelesen wird alle 10ms. Stimmt das so?

Ja, aber nicht nur im Worst case.

> 2.) cli() wird in jedem Schleifendurchlauf der main 4x aufgerufen -
> wahrscheinlich in deutlich kürzeren Intervallen, als 10ms. Bei jedem
> dieser Aufrufe werden doch die Interrupts gestoppt. Wieso wird dann die
> Interrupt Routine überhaupt mal aufgerufen?!

Wo steht da ein cli()? Auf welche Beschreibung beziehst Du Dich? Ich 
verwende die Peda Routine öfters, aber ein cli habe ich nirgends im HP 
stehen.

Gruz
Andreas

von avr (Gast)


Lesenswert?

> Ja, aber nicht nur im Worst case.

Naja, es kann ja auch sein, dass durch Zufall während dem Prellen schon 
ein oder zwei mal der richtige Zustand gelesen wird, dann müsste man 
nach der Prellzeit nur noch 3 bzw 2 mal 10ms warten.

>> 2.) cli() wird in jedem Schleifendurchlauf der main 4x aufgerufen -
>> wahrscheinlich in deutlich kürzeren Intervallen, als 10ms. Bei jedem
>> dieser Aufrufe werden doch die Interrupts gestoppt. Wieso wird dann die
>> Interrupt Routine überhaupt mal aufgerufen?!
>
> Wo steht da ein cli()? Auf welche Beschreibung beziehst Du Dich? Ich
> verwende die Peda Routine öfters, aber ein cli habe ich nirgends im HP
> stehen.
>

Also nicht direkt, aber es wird ja get_key_short aufgerufen, das 
wiederum get_key_press aufruft, das cli() aufruft. Auf diese Art kommt 
es zu 4 Aufrufen von cli().

von Forist (Gast)


Lesenswert?

avr schrieb:
> ... die Tasterentprellung von PeDa ...
Das ist doch mal eine saubere Quellenangabe. :-(

Soll jetzt jeder Hilfswille hier suchen, wie die Routine genau aussieht?

von Carl D. (jcw2)


Lesenswert?

> ... Mit den 4 Aufrufen von cli() ..

... nach denen dann immer eine Funktion gerufen wird, die eine sei() 
beinhaltet.

Und während der cli()-sei()-Phase werden anfallende Timer-INT's nicht 
vergessen, sondern nur (hier nicht mal 1μs) verzögert. Es geht nur 
darum, daß die Leseroutine ungestört Änderungen am "Zustand" der 
Tastenabfrage machen kann.

von avr (Gast)


Lesenswert?

Sorry, dachte irgendwie, ich hätte den Link gepostet. Es geht um das 
hier: 
http://www.mikrocontroller.net/articles/Entprellung#Timer-Verfahren_.28nach_Peter_Dannegger.29

@jcw2: Ahh, das wusste ich nicht, dass die Interrupts nur verzögert 
werden. Danke! Kann ich mir das dann so vorstellen, dass der Timer 
stehen bleibt, aber nicht zurückgesetzt wird, und bei Aufruf sei() 
wieder weiter läuft?

von Andreas B. (bitverdreher)


Lesenswert?

Ein cli() verhindert lediglich, daß der Interupt bis zum sei() ausgelöst 
wird.

Gruß
Andreas

von avr (Gast)


Lesenswert?

Okay. Habe jetzt gerade gelesen, dass der Timer ja trotzdem weiter 
läuft. Wenn der Timer dann also einen Interrupt auslösen würde, aber 
nicht kann, weil cli() aufgerufen wurde, wird dieser Interrupt 
gespeichert und sofort ausgeführt, sobald sei() aufgerufen wird, 
richtig?

Was, wenn in der Zeit mehrere Interrupts passieren, zB von 2 
verschiedenen Timern? Wird dann einer "vergessen", oder gibts da so ne 
Art Queue? Wie läuft das?

von Carl D. (jcw2)


Lesenswert?

> Kann ich mir das dann so vorstellen, dass der Timer stehen bleibt,
> aber nicht zurückgesetzt wird, und bei Aufruf sei() wieder weiter
> läuft?

Wenn der Timer überläuft, dann wird lediglich ein Bit im TIFRn-Register 
gesetzt. Und (stark vereinfacht) prüft die CPU nach jeder 
Befehlausführung ob das I-Flag gesetzt ist, also Interrupts ausgeführt 
werden sollen, und dann ob es anstehende Interrupts gibt, also z.B. 
TIFR0-TOV0 gesetzt ist. Wenn ja wird
1
cli
2
call Timer0_Int_vector
ausgeführt. Letzteres ist der Bereich ab 0x0000 im Flash, wo dann 
üblicherweise ein Sprung zur wirklichen ISR steht. Die ISR endet dann 
mit einen reti, was das I-Flag wieder setzt und zur unterbrochenen 
Stelle zurückkehrt. Und der Fakt, daß nach Befehlsausführung geprüft 
wird, führt dazu, daß nach jedem Interrupt mindesten ein Befehl 
ausgeführt wird, selbst wenn andere Interrupt-Requests anstehen.

von Carl D. (jcw2)


Lesenswert?

Ach ja zur Frage "Queue": stehen mehrere an, dann werden diese in der 
Reihenfolge der Int-Vektoren abgearbeitet, also INT0 vor Timer0_OVF (so 
sind die meisten AVR IntVecTabellen aufgebaut)

von avr (Gast)


Lesenswert?

Vielen Dank schonmal für die Infos. Eine OT Frage hab ich noch: Macht es 
(von außen betrachtet) einen Unterschied, ob ich
a) TCNT0 preloade, überlaufen lasse und dann ISR(TIMER0_OVF_vect) 
aufrufe, oder
b) OCR0 setze, TCNT0 bei Match zurücksetze und dann 
ISR(TIMER0_COMP_vect) aufrufe?

von Carl D. (jcw2)


Lesenswert?

Naja, wenn es nicht einmalig sein soll, dann hat die Preload-Variante 
den Nachteil, daß der Preliad für den nächsten Zyklus in der ISR 
passiert, die ja nicht sofort laufen muß (wegen cli USW.), und auch wenn 
man den Preload auf TCNTn aufaddiert, bleibt ein Jitter den die 
Hardware-Variante CTC nicht hat. Nur wenn man einfach nur eine grobe 
Zeitbasis z.B. für PeDa braucht und/oder den Timer durchlaufen läst, 
würde ich auf CTC-Mode verzichten.
Wenn ich z.B. exakt 1ms brauche,
 dann 16MHz Quarz, Timer0 CTC /64 OCR0A=249

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

damit mir aber kein IRQ auch verzögert durch die Lappen geht, ich mache 
ja noch IRMP, zähle nach IRMP hoch bis 10ms und verzweige dann bei 10ms 
in Tastenauslesen, so habe ich keine 2 IRQ.

Es können mir dann in der Tastenroutine IRMP IRQ durch die Lappen gehen, 
hatte mal versucht im long IRQ Teil alle 10ms den IRQ wieder freizugeben 
mit sei() und bei Wiedereintritt durch ein Flag an der long IRQ 10ms 
vorbeizuhüpfen, ich habe das aber noch nicht vollständig ergründet, 
irgendwie funkioniert es.

: Bearbeitet durch User
von avr (Gast)


Lesenswert?

Okay, dann werde ich das mit CTC machen. Wenn ich jetzt statt deinen 
16MHz nur 8MHz hätte, müsste OCR0A ja nur halb so groß sein. Runde ich 
dann ab oder auf?

von Carl D. (jcw2)


Lesenswert?

16M  8  250 = 1k
Und von 0 ausgehend ist der 250te Takt der mit dem Wert 249 in TCNT0. 
CTC will den TOP-Wert im OCR0A, also 249.

Bei halbem Takt muß bis 125 gezählt werden, TOP ist also 124.

Wenn das 8MHz aus dem internen RC-Oszilator sind, dann ist es aber egal 
ob 124 oder 126 ;-)

: Bearbeitet durch User
von avr (Gast)


Lesenswert?

Danke. Ja, ich nutze den internen Takt. Hab auch schon festgestellt, 
dass die Sekunden damit bisschen kürzer sind ^^
Es ging mir nur um die Theorie dahinter :-)

von Joachim B. (jar)


Lesenswert?

avr schrieb:
> Danke. Ja, ich nutze den internen Takt. Hab auch schon festgestellt,
> dass die Sekunden damit bisschen kürzer sind ^^

wenn du ein Oszi hast kannst du ja trimmen auf 10ms +-Fehler

von avr (Gast)


Lesenswert?

Oszi hab ich noch keins, ist aber unterwegs aus China (DSO138). Naja, 
zum Taster entprellen muss das ja nicht 100% stimmen. Die Taster prellen 
ja auch nicht jedes Mal exakt gleich.

von Carl D. (jcw2)


Lesenswert?

Die 10ms von PeDa sind ja auch nur eine Hausmarke. Das ist eher das 
Raster für eine Zeitsteuerung, die man oft auch noch braucht. Wenn die 
Taster nicht zu schlecht sind und man keine 40ms Zeit hat zum Drücken 
(sind ja nur 25 Anschläge/s ;-), dann dürfen es auch 5ms sein, oder eben 
20ms.

von Joachim B. (jar)


Lesenswert?

Carl D. schrieb:
> Die 10ms von PeDa sind ja auch nur eine Hausmarke. Das ist eher das
> Raster für eine Zeitsteuerung, die man oft auch noch braucht. Wenn die
> Taster nicht zu schlecht sind und man keine 40ms Zeit hat zum Drücken
> (sind ja nur 25 Anschläge/s ;-), dann dürfen es auch 5ms sein, oder eben
> 20ms.

genau aus diesem Grund nimmt man ja 10ms Interrupts, nicht wegen der 
Taster, die funktionieren auch mit 8, 15, 20ms, aber alle 10ms einen 
Counter hochzählen ist ne schöe Zeitbasis.

Ich habe z.B. Aufgaben verteilt,
alle 330ms LCD aktualisieren, egal wann ich ins Schattenram schreibe, 
wozu öfter LCD update machen?
alle 250ms WS2812b aktualisieren
alle Minute bei >500ms prüfen ob was anderes nicht zeitkritisches zu 
machen ist

von avr (Gast)


Lesenswert?

@jar: Also du zählst dann in der ISR eine Variable hoch bis 33 und, wenn 
die 33 ist, aktualisierst du dein LCD, oder wie soll ich das verstehen?

Ergo, du sparst dir einen weiteren Timer

von Joachim B. (jar)


Lesenswert?

avr schrieb:
> @jar: Also du zählst dann in der ISR eine Variable hoch bis 33 und

genau, so flimmert das LCD weniger und trotzdem wird die aktuelle 
Uhrzeit geschrieben und ich brauche nie drüber nachzudenken das zuviele 
Schreibvorgänge aufs LCD zu verschiedensten Zeiten von verschiedenen 
Orten kommen, wäre ja auch doof mal Fenster hoch zu schreiben und kurz 
danach die Uhrzeit zu aktualisieren oder die Temperatur.

von Hannes L. (hannes)


Lesenswert?

avr schrieb:
> Ergo, du sparst dir einen weiteren Timer

Das ist Zweck der Übung. Aus dem schnellsten notwendigen Timer-Interrupt 
kann man durch Zählvariablen verschiedene Zeittakte ableiten. Dies spart 
Interrupts und die damit verbundenen Aufrufzeiten (Registersicherung 
usw).

Setzt man in der ISR für die verschienen abgeleiteten Takte Flags 
(Semaphores, Merker), so können die Jobs in der Mainloop laufen. Dies 
spart Rechenzeit in der ISR, was die Verzögerung weiterer Interrupts 
gering hält.

...

von Hannes L. (hannes)


Lesenswert?

Joachim B. schrieb:
> und ich brauche nie drüber nachzudenken das zuviele
> Schreibvorgänge aufs LCD zu verschiedensten Zeiten von verschiedenen
> Orten kommen,

LCD mit Schatten-RAM eignet sich auch hervorragend zum Debuggen, damit 
kann man sich sogar in schnellen ISRs Daten ausgeben lassen...

Mache ich auch so, wenn auch nicht in C, sondern in ASM.

...

: Bearbeitet durch User
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.