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
ext. Interrupt ausmachen, Timer aufsetzen und die Entprellroutine von Peter Dannegger aus dem Forum kopieren. http://www.mikrocontroller.net/articles/Entprellung
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
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
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
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]
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.
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
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 ;-)
@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
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.
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'.
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
Schalte mal einfach einen 100nF Kondensator parallel zum Taster, dann kannst Du Dir den Programmieraufwand sparen.
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.
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.