Forum: Compiler & IDEs Softwareentprellung funktioniert nicht


von Patrick L. (socialsmoker)


Lesenswert?

Hallo

Ich versuche einen Tastersoftwareseitig zu entprellen:
1
ISR(INT1_vect)
2
{
3
  //Interrupts deaktivieren wegen Prellen
4
  cli();
5
  long_delay(750);
6
  
7
  //Taster immer noch gedrückt?
8
  if ((~PIND) & 0x8)
9
  {
10
    //stuff
11
  }
12
  //Interrupts aktivieren
13
  sei();
14
}
Allerdings scheint der Code nicht wirklich zu funktionieren. So ca alle 
5 mal wird der Taster doppelt interpretiert. Sieht jemand einen Fehler? 
Ich habe mal einen else-Teil hinzugefügt um zu überprüfen ob überhaupt 
etwas abgefangen wird. Das war jedoch nie der Fall, auch ein wenig 
komisch finde ich.

Danke im Voraus

von fail (Gast)


Lesenswert?

Verabschiede dich von dieser ISR
cli(); //sinnlos, da Interrupts zu diesem Zeitpunkt so und so gesperrt 
sind
delay in der ISR, soll das dein Ernst sein?
sei(); //sinnlos, da Interrupts nach der ISR automatisch wieder aktiv 
sind

Tip:
Timer laufen lassen und in der ISR den Timer abfragen.

von Patrick L. (socialsmoker)


Lesenswert?

Ah okay, dann fliegen cli() und sei() raus.

Und klar ist delay mein Ernst, zum Testen ob das Entprellen funktioniert 
geht das viel einfacher. Später hatte ich vor einen Timer zu benutzen.

Kann das Problem bei dem delay liegen?

von fail (Gast)


Lesenswert?

ok, zeig mal deine long_delay(750); Funktion
richtige Taktrate dem Compiler mitgeteilt?
Optimierung eingeschaltet?

von Karl H. (kbuchegg)


Lesenswert?

Patrick Liedtke schrieb:

> Und klar ist delay mein Ernst, zum Testen ob das Entprellen funktioniert
> geht das viel einfacher. Später hatte ich vor einen Timer zu benutzen.

Und was bringt dir dann der Test, wenn du eh danach alles ganz anders 
machst.

Immer dieselbe Leier. Tasten entprellen macht man am besten mit Pollen 
in einem Timer Interrupt.
Entprellung

von Karl H. (kbuchegg)


Lesenswert?

Patrick Liedtke schrieb:

> Ich habe mal einen else-Teil hinzugefügt um zu überprüfen ob überhaupt
> etwas abgefangen wird. Das war jedoch nie der Fall, auch ein wenig
> komisch finde ich.

Nicht wirklich 'komisch'. Nur weil in du in der ISR bist, prellt ja der 
Taster deswegen nicht weniger. Und wenn er prellt, wird der nächste 
Interrupt registriert, der dann ausgeführt wird, wenn diese ISR 
abgelaufen ist.

-> es ist ein Irrtum zu glauben, Taster an externem Interrupt 
vereinfacht die Sache. Stimmt ganz einfach nicht.

von Patrick L. (socialsmoker)


Lesenswert?

1
void long_delay(uint16_t ms)
2
{
3
  for(; ms>0; ms--) _delay_ms(1);
4
}

Die Taktrate kennt er (8Mhz).

von fail (Gast)


Lesenswert?

Karl Heinz Buchegger hat natürlich recht, außerdem kann man ohne die 
long_delay() Funktion nichts zu deinem Code sagen.

von schlauberger (Gast)


Lesenswert?

Also wenn ein externer interupt kommt den timer starten und nach ablauf 
der Zeit den Portpin nochmal abfragen... Oder immer den timerlaufen 
lassen und bei ubierlauf pimn abfragen?

von Patrick L. (socialsmoker)


Lesenswert?

> Nicht wirklich 'komisch'. Nur weil in du in der ISR bist, prellt ja der
> Taster deswegen nicht weniger. Und wenn er prellt, wird der nächste
> Interrupt registriert, der dann ausgeführt wird, wenn diese ISR
> abgelaufen ist.


Dafür war der delay() gedacht. Ich dachte das dann der Taster ja nicht 
mehr gedrückt wird, die if-Abfrage nicht zutrifft und der else-Teil 
ausgeführt werden muss. Nur wird er das nicht...

von fail (Gast)


Lesenswert?

@schlauberger
"immer den timerlaufen lassen und bei ubierlauf pimn abfragen?" genau 
das ist der Vorschlag von kbuchegg gewesen.
Ich hätte einen anderen nicht ganz so eleganten Vorschlag gehabt 
(ähnlich einer RTC).

von fail (Gast)


Lesenswert?

Wie ist der externe Interrupt konfiguriert, rising/falling edge? Code?

von schlauberger (Gast)


Lesenswert?

Wenn aber durchgehend der timer pollt, is das dann nicht sehr 
rechenlasstig wenn andauernd unterbrochen wird?? Is es da nicht besser 
erst wenn ein externer interrupt Eintritt diesen abzuarbeiten mit timer? 
Wozu soll sonst ein ext. Interrupt gut sein? ( ich programmiere 8051 
tiny mega xmega msp430 cortex m3...)

von Patrick L. (socialsmoker)


Lesenswert?

Der Interrupt soll bei steigender Flanke ausgelöst werden:
1
//Pin als Ausgang
2
DDRD &= ~(1<<DDD3);
3
//steigende Flanke
4
MCUCR |= (1<<ISC11) | (1<<ISC10);
5
//Interrupt int1 aktivieren
6
GICR |= (1<<INT1);

von fail (Gast)


Lesenswert?

Wenn man z.B. alle 50-100ms die Taster-Eingänge in der ISR des Timers 
abfragt, dann ist das nicht wirklich rechenlastig.
Was die beste Lösung ist, hängt auch immer mit dem jeweiligen Programm 
und dem eigenen Programmierstiel zusammen. Auch die Hardware des uC muss 
natürlich ausreichend sein.
Dass das da oben nicht wirklich gut ist, wird wahrscheinlich jedem klar 
sein.

@Patrick
hast du auch irgendwo Pullups aktiviert?
Dass 750 ms verdammt lange sind, ist dir hoffentlich auch klar?
DDRD &= ~(1<<DDD3); //DDD ?????????

von Patrick L. (socialsmoker)


Lesenswert?

ich habe ja einen externen PullUp, 10k zwischen dem Pin und VCC.

DDD3 ist eine Konstante um dem Pin einen Namen zu geben. Damit setze ich 
den Pin als Eingang

Und ja, ich weiß das 750ms verdammt viel sind, aber es scheint ja 
teilweise immer noch nicht zu reichen.

von fail (Gast)


Lesenswert?

kein Taster prellt eine dreiviertel Sekunde, 75ms wären schon verdammt 
lang!
Der Fehler muss irgendwo anders im Programm liegen.

Hast du kein Oszi, mit dem du der Sache auf den Grund gehen kannst?

von Karl H. (kbuchegg)


Lesenswert?

schlauberger schrieb:
> Wenn aber durchgehend der timer pollt, is das dann nicht sehr
> rechenlasstig wenn andauernd unterbrochen wird??


Die PeDa Routinen verbrauchen, wenn ich das noch richtig im Kopf hab, 
irgendwas um die 0.2% Rechenzeit bei 1Mhz Systemtakt. Wird der 
Systemtakt höher, geht die 'Belastung' entsprechend zurück.

Also nichts, was einem Kopfzerbrechen machen müsste.

von Patrick L. (socialsmoker)


Lesenswert?

Nein, ich steige grad erst in die Thematik Microcontroller ein und als 
Student fehlt da das Kleingeld für ein Oszilloskop...

Danke dir trotzdem soweit, ich werde weiter rumprobieren... falls mir 
noch was auffällt poste ich das nochmal, vielleicht ist das für jemanden 
ja der entscheidende Hinweis.

von fail (Gast)


Lesenswert?

Keine Ahnung, was in der ISR noch so passiert (//stuff), aber bedenke, 
dass du Variablen die noch an anderer Stelle genutzt werde, als volatile 
zu deklarieren sind.
Beim restlichen, bisher geposteten Code, habe ich keinen Fehler 
gefunden.

von fail (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> schlauberger schrieb:
>> Wenn aber durchgehend der timer pollt, is das dann nicht sehr
>> rechenlasstig wenn andauernd unterbrochen wird??
>
>
> Die PeDa Routinen verbrauchen, wenn ich das noch richtig im Kopf hab,
> irgendwas um die 0.2% Rechenzeit bei 1Mhz Systemtakt. Wird der
> Systemtakt höher, geht die 'Belastung' entsprechend zurück.
>
> Also nichts, was einem Kopfzerbrechen machen müsste.

Habe mal bei einer vergleichsweise komplexen Interrupt Routine (großes 
Array um x Positionen verschieben) mit dem Oszi nachgemessen. Selbst die 
hat sehr wenig Rechenzeit in Anspruch genommen (<1% bei 16Mhz). Über ein 
paar Taster abfragen würde ich mir da keine Gedanken machen.

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.