Hallo zusammen, vielleicht kann mir jemand bei meinem Programm Problem helfen. Eigentlich soll je nach dem welcher Taster(PB0 bis PB2 ) gedrückt wurde eine LED (PC0 bis PC2) eingeschaltet werden. Das ganze soll über einen jeweiligen Interrupt ausgelöst werden. Allerdings wird nur die ISR (PCINT0_vect) aufgerufen. Egal welchen Taster ich drücke. Hab ich hier einen Denkfehler?
Flo. W. schrieb: > Hab ich hier einen Denkfehler? Einen gewaltigen. Die PC Ints beziehen sich immer auf den ganzen Port. Hast du mehrere Pins eines Ports maskiert, musst du in der ISR oder an sonst einer geeigneten Stelle gucken, welcher es war. Aber Taster und Interrupt ist sowieso nicht so toll. Normalerweise wird man in diesem Forum dafür gesteinigt. Frag die Taster mittels Timer ab und entprell sie vernünftig. Sonst wirst du damit ohnenhin kein Freude haben. Wie man das richtig macht, kannst du im Tutorial nachlesen.
:
Bearbeitet durch User
Danke für die schnelle Hilfe. Dann werde ich mir mal das Tutorial anschauen.
Ich verstehe den Text im Datenblatt jedoch anders: "Each PCINT7..0 bit selects whether pin change interrupt is enabled on the corresponding I/O pin. If PCINT7..0 is set and the PCIE0 bit in PCICR is set, pin change interrupt is enabled on the corresponding I/O pin. If PCINT7..0 is cleared, pin change interrupt on the corresponding I/O pin is disabled." Da steht nichts von ganzen Ports. Allerdings bestätigt dieses Tutorial, was "Thomas Eckmann" geschrieben hat: https://thewanderingengineer.com/2014/08/11/arduino-pin-change-interrupts/
Stefan U. schrieb: > Da steht nichts von ganzen Ports. Darum geht es ja auch nicht. 1 bis 8 Pins an PORTx, je nachdem, welche maskiert sind, lösen ein und den selben Interrupt aus. Nämlich den, der zu diesem Port gehört.
Ja, habe ich (nach dem Lesen des Tutorials) auch so verstanden. Das Datenblatt finde ich in dieser Hinsicht sehr unklar, da könnte man meinen, daß PCINT1 zum gleichnamigen Pin gehört. Wenn man beim Ausprobieren mit PCIN0 anfängt, merkt man nichtmal den Irrtum. Das ist echt fies!
Der Sachverhalt wird spätestens dann klar, wenn man die dazugehörenden Interruptvektoren sucht und feststellt, dass es beim ATmega328 davon nur drei gibt.
Stefan U. schrieb: > Da steht nichts von ganzen Ports. da nicht, aber z.B. da: Pin Change Interrupt PCI0 triggers if a pin in PCINT[7:0] is toggled while enabled
Kann man überhaupt sicher feststellen, von welchem Pin der IRQ ausgelöst wurde, oder hat sich der Pinzustand dann vielleicht schon geändert, wenn der ISR-Code startet?
Hi >Kann man überhaupt sicher feststellen, von welchem Pin der IRQ ausgelöst >wurde, oder hat sich der Pinzustand dann vielleicht schon geändert, wenn >der ISR-Code startet? Klar man muss nur den Stand bei jeden Interrupt Speichern. Dann reicht ein einfaches XOR. MfG Spess
batman schrieb: > Kann man überhaupt sicher feststellen, von welchem Pin der IRQ > ausgelöst > wurde, oder hat sich der Pinzustand dann vielleicht schon geändert, wenn > der ISR-Code startet? Das ist genau das Problem, wenn man Taster ohne Entprellung abfragt und sich nur auf den INT verlässt. Bei einem Taster bräuchte man ja nicht einmal nachgucken, welcher es war. Der INT könnte aber auch von einem sehr kurzen Störsignal ausgelöst worden sein. In der Praxis hat es sich daher bewährt, den oder mehrere PCINT nur zum Aufwecken des Controllers aus dem Sleep Mode zu benutzen, danach die PCINTs abzuschalten und die normale Entprellung ablaufen zu lassen. Nach Ausführung der dem Taster zugeordneten Aktion schaltet man die PCINTs dann wieder ein und legt den Controller wieder schlafen. Bis zum nächsten Tastendruck. Damit hält die Batterie in einer Fernbedienung dann eine kleine Ewigkeit. Ich meine, mal gelesen zu haben, daß Atmel die Pinchange Funktionalität genau für sowas eingeführt hat.
Hmm naja, etwas unsauber gelöst. Da hätte Atmel ruhig noch ein Latchregister für die genaue IRQ-Quelle spendieren können. Wenn man so ein batteriebetriebenes AVR-Gerät durch einen kurzen Tastendruck aus dem Power-Down einschaltet (was schon einige ms dauern kann), wird dann manchmal noch die Tastenfunktion ausgelöst oder auch nicht - je nachdem wie lange man drückt.
batman schrieb: > was schon einige ms dauern kann) Wie kommst du darauf? Das dauert ein paar µs. Diese Zeit ist bei Tastendrücken vernachlässigbar.
So schnell kann das nicht gehen, wenn z.B. ein Quarz-Oszillator gestartet werden muß. Aus dem DB, Power-Down Mode: The wake-up period is defined by the same CKSEL Fuses that define the Reset Time-out period, as described in ”Clock Sources” on page 28. Hier findet man Zeiten bis 65ms.
batman schrieb: > Hier findet man Zeiten bis 65ms. Das ist richtig. Aber als Anwendung in diesem Fall nicht sinnvoll. Prädestinert ist der Betrieb mit internem RC.
batman schrieb: > wird dann > manchmal noch die Tastenfunktion ausgelöst oder auch nicht - je nachdem > wie lange man drückt. Nur wenn man es ungeeignet programmiert. Ist der Puls zu kurz, kann es passieren, daß der Pin im Interrupthandler wieder auf dem alten Pegel ist oder auch, daß der Interrupthandler gar nicht erst angesprungen wird. Bei Entprellung im Timerinterrupt führt beides nicht zu einer Fehlerkennung der Taste. Der MC wacht einfach nur auf und geht wieder schlafen, wenn der Timerinterrupt keine Änderung festgestellt hat. Ich nehme für das Aufwachen immer einen EMPTY_INTERRUPT, d.h. der Interrupthandler besteht nur aus einem RETI.
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.