Forum: Mikrocontroller und Digitale Elektronik AVR Assembler Hardwareinterrupt entprellen


von Leon (Gast)


Lesenswert?

Hallo allerseits,

ich suche eine Möglichkeit Hardwareinterrupts im Assembler zu 
entprellen.

Die Aufgabe ist:
Ein Lauflicht soll durchlaufen. Wenn ein Taster gedrückt wird wird der 
Hardwareinterrupt Int0 ausgelöst, nun soll auf der 7-Segmentanzeige 
inkrementiert werden.

Das Problem:
Wenn der Taster gedrückt wird zählt die 7-Segmentanzeige manchmal um 
mehr als einen Schritt rauf.

Ich habe schon versucht, dies mit einer Delayschlaufe, Mehrfachabfrage, 
... zu lösen aber bin bis jezt noch auf kein Ergebnis gekommen.

Ich wäre froh wenn mir jemand helfen kann.

Freundliche Grüsse Leon

: Gesperrt durch User
von Schwafelhexenfluorid (Gast)


Lesenswert?

ext. Interrupt ausmachen, Timer aufsetzen und die Entprellroutine von 
Peter Dannegger aus dem Forum kopieren. 
http://www.mikrocontroller.net/articles/Entprellung

von Jobst M. (jobstens-de)


Lesenswert?

Leon schrieb:
> Die Aufgabe ist:

> Wenn ein Taster gedrückt wird wird der
> Hardwareinterrupt Int0 ausgelöst

Ist das eine Schulaufgabe? Und der Taster am Hardwareinterrupt gehört 
dazu?

Dann hat Dein Lehrer keinerlei praktische Erfahrung mit µC. Du hast 
mittlerweile mehr Erfahrung. Denn diese hast Du zumindest schon gemacht.

Wenn Dein Lehrer sagt, daß das mit sw gelöst werden soll, dann hat er 
auch keine theoretische Erfahrung - Warterei in einem Interrupt ist zwar 
nicht unmöglich, aber ungeschickt. (Würde dann so aussehen, daß zu 
Beginn des IRQs 10ms gewartet wird und wenn das Portbit dann immer noch 
einen gedrückten Taster anzeigt Euer Zähler Inkrementiert wird, wenn er 
dann nicht gedrückt ist, wird der IRQ einfach wieder verlassen.)

1. Möglichkeit: Den Taster per Hardware entprellen. (Ihr könnt dann auch 
einen Hardwarezähler benutzen und Euch den µC sparen.)

2. Möglichkeit: Wie schon beschrieben, den Timerinterrupt benutzen.


EDIT:
Leon schrieb:
> Delayschlaufe

Wie lange hast Du gewartet?
Schlaufe finde ich schön :-)


Gruß

Jobst

von oldmax (Gast)


Lesenswert?

Hi
Egal ob Schulaufgabe oder Hobby... einen Taster mit einem Interrupt  zu 
erfassen ist unklug und überhaupt nicht erforderlich. Wie schnell kannst 
du einen Taster drücken und loslassen ? 100m Sek oder gar 10 mSek.? 
Beides Zeiten, in dem ein Controllersich  auch bei umfangreichen 
Programmen mehrfach überschlagen hat. Völlig ausreichend, Taster im 
Polling zu erfassen. Erst, wenn du ganz kurze Signale erfassen willst, 
dann ist ein Interrupt angesagt. Angenommen, du nimmt ein Rad und machst 
an eine Speiche einen Magneten. Diesen erfaßt du mit einem Reedkontakt 
und willst die Umdrehung zählen. Auch wenn dein Rad relativ langsam 
dreht, ist der Reedkontakt nur vielleicht 1/2 Grad geschaltet, das heißt 
bei einer Umdrehung nur ein 720stel. Also, 1 Umd/Sek bedeutet ein 
auswertbares Signal von 1/720 Sek, also rd. 1,3 mSek. Nur wenn dein 
Programmzyklus kürzer als 1,3 mSek ist, wird der Impuls erfasst. Da aber 
auch höhere Umdrehungen einbezogen werden müssen, kannst du nicht mehr 
davon ausgehen, das der Impuls vom Reedkontakt erkannt wird und dann 
macht ein Interrupt Sinn.
Grup oldmax

von Jobst M. (jobstens-de)


Lesenswert?

oldmax schrieb:
> Egal ob Schulaufgabe oder Hobby... einen Taster mit einem Interrupt  zu
> erfassen ist unklug und überhaupt nicht erforderlich.

Nein. Egal ist es nicht. Wenn er es für sein Hobby macht, kann er die 
Anforderung ändern. Wenn es eine Schulaufgabe ist, wonach es sich für 
mich anhört, müsste er diese Anforderung erfüllen - so dämlich sie ist.


Gruß

Jobst

von Der E. (rogie)


Lesenswert?

oldmax schrieb:
> ... Wie schnell kannst
> du einen Taster drücken und loslassen ? 100m Sek oder gar 10 mSek.?
> ...
> Grup oldmax


Frag mal nen Hardcore Gamer, die merken sogar Verzögerungen von 10 us.

[iRonie]

von Leon (Gast)


Lesenswert?

Nein, es ist keine Schulaufgabe. Ich muss dies im Geschäft machen.
Dass warten in einer Interruptroutine nicht schöhn ist weiss ich. Ich 
wollte nur ausprobieren ob es so funktionieren würde. (Ich habe ungefähr 
10mal so lange gewartet, wie der Taster Prellt.)
Zur Idee mit einer Hardwareentprellung und Zähler... <- Es geht ja um 
Interrupts und das Entprellen! Ich muss programmieren lernen, Hardware 
war leztes Jahr dran.

Die Idee mit dem Timerinterrupt finde ich gut, werde diese Variante mal 
ausprobieren.

von oldmax (Gast)


Lesenswert?

Hi
Zum einen ist es das Prellen, möglicherweise aber auch die direkte 
Abfrage des Tastersignales.
EVA sagt dazu "Einlesen" "Verarbeiten" und "Ausgeben"
Das ist im Prinzip deine Programmschleife. Wenn du nun deine Taster 
betätigst, dann erkennt der µC bei jedem Durchlauf "Aha, ein ganz 
schlauer.... " und zählt fröhlich hoch. Also brauchst du die Flanke des 
Signales "Taster gedrückt" und das erhälst du mit einer EOR-Verknüpfung 
des alten Zustandes.
Angenommen, dein Taster war nicht gedrückt und der alte Zustand ist "0".
Nun drückst du drauf und bekommst eine "1".
Exclusiv-Oder = 0 und 1 = 1. Das ist deine Flanke. Anschließend setzt du 
Alt = neu, also Alt auf "1"
Du kannst nun den taster halten, bis du alt und grau wirst, es gibt 
keine neue "1" da Exclusiv Oder "1" und "1" = 0 ist
Diese "1" aus dem vorherigen Ergebnis benutzt du, um das Kriteriun für 
den Zählimpuls zu haben. Dann setzt du diese "1" zurück. Eine neue "1" 
gibt es erst, wenn du die taste losläßt und erneut drückst.
Hier mal die Wahrheitstabelle einer Exclusiv-Oder Verknüpfung:
    E 1    E 2     A
     0      0      0
     1      0      1
     0      1      1
     1      1      0

Daran erkennst du, das das Ergebnis "A" nur "1" ist, wenn "E 1" und "E 
2" unterschiedlich sind.
Gruß oldmax

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Leon schrieb:
> Nein, es ist keine Schulaufgabe. Ich muss dies im Geschäft machen.
> Dass warten in einer Interruptroutine nicht schöhn ist weiss ich. Ich
> wollte nur ausprobieren ob es so funktionieren würde. (Ich habe ungefähr
> 10mal so lange gewartet, wie der Taster Prellt.)

In einem Interrupt warten macht man nicht. Du könntest in der ISR 
checken, wie lange der letzte Interrupt vergangen ist und dann den 
aktuellen Interrupt einfach ignorieren, wenn er innerhalb x msec 
eingetroffen ist.

Zur Realisierung bräuchtest Du dann noch zusätzlich(!) einen 
Timerinterrupt, damit Du die vergangene Zeit mitzählen kannst. Und wenn 
Du dann schon einen Timerinterrupt hast, kannst Du die INT0-ISR kicken 
und direkt auf Polling übergehen...

Ich hoffe, ich habe Dich im letzten Abschnitt von der Sinnlosigkeit 
eines INT0-Interrupts für eine Tastenabfrage überzeugt ;-)

von Preller (Gast)


Lesenswert?

@oldmax

Mit einer XOR-Verknüpfung erkennt er zwar die Flanke und kann diese 
Auswerten. Beim Prellen des Tasters kommt es aber zu mehreren Flanken 
(an-aus-an-aus-an-aus, deshalb ja prellen), welche dann auch einzelln 
gezählt werden.
Um eine Verzögerung nach einer Flanke kommt man nicht herum. Diese durch 
einen Timer zu erledigen ist natürlich besser als eine Delayschleife zu 
benutzen. Wenn der Taster über Interupts ausgelesen wird, ist es am 
einfachsten diese an und ab zu schalten.

-> Flanke erkannt dann Timer starten und Interupt aus
-> Timer abgelaufen Interupt wieder an

von Karl H. (kbuchegg)


Lesenswert?

Dazu kommt, dass in einem realen Programm sowieso in >95% aller Fälle 
ein Timer in der einen oder anderen Form involviert ist. D.h. du hast 
die Maschinerie im Grunde schon im Gang.

Da du Lauflicht erwähnt hast: Auch so etwas macht man sinnvollerweise 
mit einem Timer! Da du keinen Timer erwähnt hast, geh ich davon aus, 
dass du das Lauflicht mit _delay_ms gemacht hast, was dann wiederrum 
dazu geführt hat, dass du meinst, du müsstest einen Taster an einen 
externen Interrupt hängen. So führt dann ein Fehldesign zum nächsten.

Timer sind deine Arbeitspferde! Immer dann wenn es um Zeiten oder 
zeitliche Koordinierungen geht, ist ein Timer involviert.

von Karl H. (kbuchegg)


Lesenswert?

Preller schrieb:

> -> Flanke erkannt dann Timer starten und Interupt aus
> -> Timer abgelaufen Interupt wieder an


Da kannst du es aber auch gleich bleiben lassen und im Timerinterrupt 
pollen. Ist in Summe um einiges einfacher als dieser 'Zusammenhang'.

von Peter D. (peda)


Lesenswert?


von oldmax (Gast)


Lesenswert?

Hi

>Mit einer XOR-Verknüpfung erkennt er zwar die Flanke und kann diese
>Auswerten. Beim Prellen des Tasters kommt es aber zu mehreren Flanken
>(an-aus-an-aus-an-aus, deshalb ja prellen), welche dann auch einzelln
>gezählt werden.

Natürlich geh ich davon aus, das das viel beschriebene Prellen erledigt 
wird, bevor man sich an die Flankenauswertung setzt.
Deshalb hab ich es j auch erwähnt, das nicht nur das Prellen für ein 
unkontrolliertes Zählen verantwortlich ist.
Gruß oldmax

von Stefan (Gast)


Lesenswert?

Schalte mal einfach einen 100nF Kondensator parallel zum Taster, dann 
kannst Du Dir den Programmieraufwand sparen.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Stefan schrieb:
> Schalte mal einfach einen 100nF Kondensator parallel zum Taster, dann
> kannst Du Dir den Programmieraufwand sparen.

Für manche Leute ist das zwar verpöhnt, hat aber zusätzlich den Vorteil, 
das der Taster mit einigem Strom geschaltet wird. Ich erinnere mal an 
diesen Thread:
Beitrag "Mindeststrom bei Taster/Schalter für sicheren Betrieb?"

Allerdings muss der Kondensator ja über den Pullup des AVR wieder 
geladen werden, deswegen erscheint mir 100n ein wenig hoch. 4n7 - 22n 
sind da auch o.k.
Noch ein Vorteil ist, das etwaige Störungen von der LED Schalterei nicht 
auf den INT zurückwirken.

von Karl H. (kbuchegg)


Lesenswert?

Für manche Leute ist es vor allen Dinge verpöhnt, einen 5 Monate alten 
Thread aus der Versenkung zu holen. Noch dazu zu einem Thema, welches 
jede Woche mindestens 8 mal auf der Agenda steht.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.