Bin neu in der 8051 programmierung. Folgendes Problem: ich will den INT0-Interrupt zum umschalten von Funktionen nutzen. Aber es scheint, dass bei einem Tastendruck der interrupt 2 oder mehr mal aufgerufen wird. Ich nehme an, dass es mit dem typischen verhalten des Tasters zusammenhängt. Die klassische Lösung mit der verzögerung bringt nichts: auch wenn ich innerhalb des Handlers EA = 0; setze, 20ms aktiv-warten und erst dann wieder EA aktiviere, scheint es doppelt aufgerufen zu werden. Ich benutze den uC51-compiller. Was wäre die beste standartlösung? Danke
Taster nicht per Interrupt abfragen, sondern pollen. Dann kann man auch gleich entprellen. Wirklich kein neues Thema hier, einfach mal suchen. Wegen dem Mehrfach-Aufruf trotz Wartezeit: Mit EA sperrst du nur den Aufruf des Interrupthandlers. Wenn bei EA=0 das Interrupt-Ereignis auftritt, wird das zugehörige Interruptbit gesetzt, aber nix weiter unternommen. Sobald EA dann wieder da ist, werden die Handler aufgerufen.
Hallo, du solltest niemals in Interrupts solche Sachen wie Warteschleifen o.ä. einbauen. Interrupts müssen eigentlich so schnell wie möglich fertig sein, ausserdem blockst du damit unnötig andere Interrupts. Bei kleinen Projekten mag dies nicht ins Gewicht fallen, aber wenns mal komplexer wird, wunderst du dich dann, warum die Interrupts so langsam abgearbeitet werden oder womöglich Interrupts verloren gehen. Du kannst wie bereits von Thomas B. erwähnt per Polling arbeiten, das heisst, an bestimmten Stellen im Hauptprogramm prüfen, ob der Eingang aktiv ist. Wenn ja, dann wartest du 20ms, und prüfst nochmal. Wenn der Eingang dann immer noch aktiv ist, änderst du die Funktion. Das lässt sich in ein Unterprogramm packen, welches du dann immer per CALL-Befehl aufrufst. Eine Alternative mit Interrupts gibts natürlich auch, allerdings ist der INT0/1-Interrupt (=Externer Interrupt) dafür ungeeignet. Nimm besser einen der Timer-Interrupts. Du stellst den Timer-Interrupt auf 20ms ein. Wenn der Interrupt zuschlägt, prüfst du den Eingang, setzt/löschst entsprechend ein Bit und verlässt den Interrupt. Beim nächsten Timer-Interrupt prüfst du das Bit. Ist es gesetzt und der Eingang immer noch aktiv, dann signalisierst du über ein weiteres Bit dem Hauptprogramm, dass sich die Funktion geändert hat. Ist der Eingang nicht mehr aktiv gewesen, dann gibts auch keine Nachricht ans Hauptprogramm, und das "Merk"-Bit innerhalb des Interrupts wird gelöscht (Wird natürlich auch gelöscht, wenn das Hauptprogramm die Nachricht erhalten hat, denn dann hat es seinen Zweck erfüllt). Das Entprellen ist damit auch gelöst. Es gibt natürlich weitere Ansätze, die eben anders arbeiten. Ich verwende eben immer den Timer-Interrupt, wobei dieser eine kleinere Zeitbasis hat. Bei mir sind es etwa 138 µs. Über eine Vorteiler-Variable teile ich die Interrupt-Zeit in drei Abschnitte von jeweils 3,33ms. Jeder Abschnitt hat eine andere Aufgabe: Matrix-Tastatur-Abfrage, Software-Timer (10ms Auflösung) und Aktualisierung der Software-RTC. Da bei jedem Interrupt ein anderer Abschnitt drankommt, sind diese 3,33ms zueinander versetzt. Jeder Abschnitt kommt alle 10ms dran (3x3,33ms). Du siehst, jeder hat da so seine Lösungsart :) Wenn du Fragen dazu hast, ruhig zu. Ralf
Maverick wrote: > Die klassische Lösung mit der verzögerung bringt nichts: Das stimmt, man sollte daher von der klassisch schlechten Lösung sprechen. Die zuverlässige Lösung entprellt und flankenerkennt immer mindestens einen ganzen Port parallel (aufm 8-Bitter: 8 Tasten). Sie ist allerdings so gut, daß sie selbst für nur eine Taste die klassisch schlechte Lösung weit in den Schatten stellt. Sie benutzt den Timerinterrupt und tastet 4-mal ab: http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29 Für den 8051 muß man nur die Interruptsyntax, Timerinitialisierung und Portdefinitionen etwas anpassen. Peter
Wenn du ein mehrfaches aufrufen des interupts verhindern möchtest, musst du dann über software den interrupt sperren und dann später wieder freischalten. ich weiß nicht mehr genau den befehl, war nur ein tipp
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.