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
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.
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?
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
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.
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?
> 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...
@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).
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...)
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 ?????????
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.
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?
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.
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.
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.
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.