Guten Tag, ich habe mir einen arduino due angeschafft und möchte mihc nun mit dem thema interrupts vertraut machen. Ich habe gelesen das der Due alle Pins für externe Interrupts nutzen kann. Ein einzelner Interrupt ist nicht so das problem. Angenommen ich möchte an mehreren Pins Interrupts generieren, wie läuft das dann mit prioritäten und wie legt man diese fest?
Hallo Jannus, schau in das Datenblatt deinen Atmel AVR µC, den wir nicht kennen, dort sind alle Interrupts beschrieben. Und es gibt i.a. INT0-INTn die habe ihre eigenen Interrupt Einsprünge und dann i.a. auch noch die PCINTn Interrupts. Der PCINTn ist eine Zusammenfassung eines Port auf einem Interrupt Einsprung. Hier muss Dein Programm dann herausfinden, welcher der 8 Eingänge eine Ports es gerade war und auch noch zu Checken welcher Spannungslevel dieser Eingang gerade hatte, denn PCINTn Interrupts "zünden" immer auf einen Signalwechsel als L->H UND H->L. Den Rest Erklärungen überlasse ich dem Datenblatt.
Das ist keine DUE-Sache sondern des jeweilig verbauten µP. Das zugehörige Datenblatt gibt hierzu Auskunft.
Karl M. schrieb: > deinen Atmel AVR µC Der Arduino Due ist ein SAM3X8E, ein Cortex-M3 Jannus schrieb: > Ein einzelner Interrupt ist nicht so das problem. Angenommen ich möchte > an mehreren Pins Interrupts generieren, wie läuft das dann mit > prioritäten und wie legt man diese fest? Je niedriger die Zahl, desto hoeher die Prioritaet. Eine Prioritaet setzt du mit:
1 | NVIC_SetPriority(TC0_IRQn, 5); // setzen der prioritaet |
2 | NVIC_EnableIRQ(TC0_IRQn); // interrupt einschalten |
3 | |
4 | NVIC_SetPriority(TRNG_IRQn, 10); |
5 | NVIC_EnableIRQ(TRNG_IRQn); |
Der TC0 IRQ erhaelt hier die Prioritaet 5, der Interrupt fuer den Zufallszahlengenerator die Prio 10. Das heisst: TC0 unterbricht TRNG. Die Prioritaeten gehen (glaube ich) von 1 bis 15. 1 -> ganz wichtig, 15 -> ueberhaupt gar nicht wichtig Nimmst du die Arduinoe IDE oder Atmel Studio?
Jannus schrieb: > Oder gibt das Schwierigkeiten und AVR Studio ist geeigneter für diesen > zweck? Was ist Dein 'Zweck'?
Jeder Port kann genau einen Interrupt auslösen, egal wie viele Pins du dort mit Interrupt konfiguriert hast. Wenn ein GPIO also einen Interrupt auslöst, musst du das ISR lesen, dort sind dann alle Bits gesetzt, die einen Interrupt ausgelöst haben (könnten). Daraus folgt, dass ein Port nur eine einzige Interruptpriorität für alle Pins an diesem Port hat. Du kannst aber pro Port eine Priorität im NVIC vorgeben.
Es ist aber doch genau so möglich, das jeder Pin einen Interrupt auslöst. So versteh ich zumindest die Funktionen AttachInterrupt() von Arduino. https://www.arduino.cc/en/Reference/AttachInterrupt
Die Hardware kann durchaus einen Interrupt für jeden Pin auslösen. Es wird aber für alle Pins an Port A der PIOA-Interrupt aufgerufen, für alle Pins an Port B der PIOB-Interrupt und so weiter. Wie die Arduino-Bibliotheken damit umgehen, weiß ich nicht (und interessiert mich auch eher nicht). Es kann gut sein, dass das, was ich beschrieben hatte, dadrin schon erledigt wird und die Interrupts dann auf verschiedene "Interrupt-Handler" verteilt wird, je nachdem, an welchem Pin sie aufgetreten sind.
Jannus schrieb: > m.n. schrieb: >> Was ist Dein 'Zweck'? > > steht doch oben alles Interrupts als Selbstzweck? Das kann ich nicht nachvollziehen. Wie das Atmel-Studio das Debugging unterstützt, weiß ich nicht. Wenn man genau sehen will, wie der µC intern tickt, sind Demo-IDEs von Keil oder IAR sehr sinnvoll: im laufenden Betrieb kann man sich Variablen und Flags ansehen und ändern. Das nennt sich 'live watch' (bei IAR).
Jannus schrieb: > Es ist aber doch genau so möglich, das jeder Pin einen Interrupt > auslöst. Ja, jeder Pin kann einen Interrupt auslösen, aber für einen Port gibt es nur einen Interrupt-Handler, soll heißen: Alle Pins an Port A lösen den Port A Interrupt aus, und du musst im Interrupt-Handler abfragen, welcher Pin den Interrupt ausgelöst hat.
1 | Interrupt_Handler_PortA() // weiss gerade nicht wie der genau heisst |
2 | { |
3 | if(war es Pin 0) |
4 | { |
5 | } |
6 | else if(war es Pin 1) |
7 | { |
8 | } |
9 | ... |
10 | else if(war es Pin 31) |
11 | { |
12 | } |
13 | } |
Das selbe gilt z.B. auch für den UART/USART. Beim AVR gibt es zwei interrupts, einen für senden, einen für empfangen. Beim Due gibt es nur einen Interrupt, und du musst feststellen, welcher interrupt es war.
1 | UART_Interrupt() |
2 | { |
3 | if(war es der empfangs interrupt) |
4 | { |
5 | } |
6 | |
7 | if(war es der sende interrupt) |
8 | { |
9 | } |
10 | } |
Kaj schrieb: > Ja, jeder Pin kann einen Interrupt auslösen, aber für einen Port gibt es > nur einen Interrupt-Handler, soll heißen: Alle Pins an Port A lösen den > Port A Interrupt aus, und du musst im Interrupt-Handler abfragen, > welcher Pin den Interrupt ausgelöst hat. Angennommen ich schreibe folgende Programmzeile: attachInterrupt(pin, state, CHANGE); Wenn ich hierzu jetzt die ISR aufrufe weiß ich doch auch das an genau diesem Pin ein Interrupt ausgelöst wurde. Oder ist es so, das ich pro Port immer die gleiche ISR aufrufe? Sprich das es so umgesetzt werden muss. attachInterrupt(pin1, state, CHANGE); //Pin 1 an PortA attachInterrupt(pin2, state, CHANGE); //Pin 2 an PortA Oder geht es auch so: attachInterrupt(pin1, state1, CHANGE); //Pin 1 an PortA attachInterrupt(pin2, state2, CHANGE); //Pin 2 an PortA
Jannus schrieb: > attachInterrupt(pin, state, CHANGE); > > Wenn ich hierzu jetzt die ISR aufrufe weiß ich doch auch das an genau > diesem Pin ein Interrupt ausgelöst wurde. Oder ist es so, das ich pro > Port immer die gleiche ISR aufrufe? Eines der schönen Dinge bei Computern ist es, dass es dem Computer völlig egal ist, wenn du ein wenig herumprobierst. Warum probierst du es nicht einfach aus? Installier den Interrupt, häng einen Taster an den Pin (und einen zweiten Taster an einen anderen Pin vom selben Port), mach noch eine LED an einen anderen Port, lass das Programm laufen und drück auf den Taster der eigentlich keinen Interrupt auslösen sollte. Dann weisst du es genau. Und das schönste: du hast es selbst herausgefunden. Ein bisschen mehr Eigeninitiative! Du wirst noch auf 1000-ende Dinge stossen, die auf den ersten Blick ein paar Fragen aufwerfen. Willst du jedesmal wen fragen oder willst du lernen, wie man sich selbst Antworten erschliesst und wie man Testszenarien so entwirft, dass sie einem Antworten liefern? Der Lerneffekt ist ungleich intensiver, wenn man selbst auf Dinge drauf kommt. Dann passiert es dir auch nicht, dass du nach Dingen fragst, die jetzt schon x mal beantwortet wurden.
:
Bearbeitet durch User
Jannus schrieb: > Angennommen ich schreibe folgende Programmzeile: > > attachInterrupt(pin, state, CHANGE); Eigenlich solltest du den Pin über die Funktion digitalPinToInterrupt() dem Interrupt zuordnen bzw. beim Due nur 0 übergeben.
1 | attachInterrupt(digitalPinToInterrupt(pin), ISR, mode); |
https://www.arduino.cc/en/Reference/AttachInterrupt p.s. Ich weiss, das Manual zu lesen ist uncool
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.