Interupt Handler auf Arduino DUE

Gast #4292310
Lesenswert?
• ▲
▼
Hallo zusammen,

Ich versuche nun seit einiger Zeit einen Interrupt an dem PORTA des 
Arduino bei einem Flankenwechsel zu generieren. Ich arbeite mit der 
Arduino-IDE, möchte dazu aber nicht die funktion attachInterrupt() 
nutzen.
Daher habe ich mich mit Hilfe des Datenblattes an die Konfiguration der 
Interrupts gemacht, jedoch ohne erfolg.
Es wird kein Interrupt generiert. Wenn die Codezeile "Enables Periphal 
Clk" wie unten im Beispiel angegeben genutzt wird ist die Kommunikation 
über den seriellen Port auch nicht mehr möglich. HAt jemand erfahrung 
mit diesen Problemen?
1
volatile boolean a=0;
2

3
void PIOA_handler()
4
{
5
  a=!a;
6
}
7

8
void setup() 
9
{
10
 Serial.begin(115200);
11

12
/*Enables the PIO to control the corresponding pin*/
13
REG_PIOA_PER = REG_PIOA_PER | 0x3018FC80;
14

15
/*Enables the Input Change Interrupt on the I/O line*/
16
REG_PIOA_IER = REG_PIOA_IER | 0x3018FC80;
17

18
/*Enables PIO Controller Clock, Enables Periphal Clk on PIOA-PIOD*/
19
REG_PMC_PCER0 = REG_PMC_PCER0 | 0x00007800; 
20

21
/*Enables Interrupts on PIOA-PIOD*/
22
NVIC_EnableIRQ(PIOA_IRQn);
23
}
24

25
void loop() 
26
{
27
Serial.println(a);
28
}
Gast #4292482
Lesenswert?
• ▲
▼
Ok das klingt erstmal sehr gut. Das bit wird ja durch auslesen des "PIO 
Controller Interrupt Status Register" asugeführt. Also müsste es sich 
doch durch hinzufügen in der ISR leicht ändern lassen.
Ich habe folgenden code ergänzt aber das gleiche problem.
1
volatile boolean a = 0;
2
volatile int state=0;
3

4
void PIOD_handler()
5
{
6
  state=REG_PIOD_ISR;
7
  a=!a;
8
}
Gast #4292750
Lesenswert?
• ▲
▼
Hallo,

ich bin mir nicht sicher ob das so einfach ist. Du müsstest ja deinen 
Handler erst Registrieren. Dazu müsste dus in die exception_table 
eintragen.

Diese findest du eigentlich in der "startup_sam3xa.c" Datei.
Aber ich kann dir nicht direkt sagen ob diese noch bei Arduino 
existiert.

Sonst hab ich auf GitHub ein Projekt für ein OS für das Due, da kannst 
du dir zumindest etwas abgucken.
https://github.com/CsharpLassi/DueOS im Branch Develop.

Also wenn du die internen Funktionen nicht nutzen möchtest musst du 
direkt den Arduino Quellcode etwas abändern.

viele grüße
Lassi
#4293051
Lesenswert?
• ▲
▼
Lassi schrieb:
> ich bin mir nicht sicher ob das so einfach ist. Du müsstest ja deinen
> Handler erst Registrieren. Dazu müsste dus in die exception_table
> eintragen.

Nein, die stehen da normalerweise schon als weak Reference drin.

Aaaber: Damit die korrekt aufgelöst wird, muss der Name stimmen.

Und da dürfte ein Fehler sein: "void PIOD_handler()" ist möglicherweise 
falsch geschrieben.

Versuche es mal mit "void PIOD_Handler()", Groß- und kleinschreibung 
beachten!

Schau ansonsten direkt im Startup Code nach was da für Namen verwendet 
werden.
Gast #4293642
Lesenswert?
• ▲
▼
Lassi schrieb:
> Diese findest du eigentlich in der "startup_sam3xa.c" Datei.
> Aber ich kann dir nicht direkt sagen ob diese noch bei Arduino
> existiert.

Diese Datei ist nicht vorhanden.

Jim M. schrieb:
> Und da dürfte ein Fehler sein: "void PIOD_handler()" ist möglicherweise
> falsch geschrieben.
>
> Versuche es mal mit "void PIOD_Handler()", Groß- und kleinschreibung
> beachten!

Danke das ist auf jedenfall ein wichtiger Fehler gewesen. Allerdings 
läuft es trotzdem noch nicht.
Sobald ich die Periphal CLock wie im obigen Beispiel gezeigt aktiviere 
werden keine Daten mehr über die serielle Schnittstelle gesendet.
1
REG_PMC_PCER0 = REG_PMC_PCER0 | 0x00007800;
Gast #4293692
Lesenswert?
• ▲
▼
OK ich habs. Zunächstmal danke für eure Hilfe.

Jannus schrieb:
> Sobald ich die Periphal CLock wie im obigen Beispiel gezeigt aktiviere
> werden keine Daten mehr über die serielle Schnittstelle gesendet.

Mit einem Multimeter und dem einschalten eines digitalen Pins in der ISR 
habe ich festgestellt, das der Interrupt sehr wohl ausgelöst wird.

Das Problem ist, das die ISR immer wieder aktiv wird und so die loop() 
mit dem Serial.print() gar nicht aktiv wird. Das ist der Grund warum 
keine Daten gesendet werden.

Das näcshte Rätsel ist jetzt jedoch, warum der Interrupt immer wieder 
auslöst, obwohl ich den Pin zur Generierung auf Masse gelegt habe. Evtl. 
wird das ISR Register nicht richtig gelöscht?!
Gast #4293694
Lesenswert?
• ▲
▼
Hi,
bitte sagt doch mal was das werden soll:
1
REG_PMC_PCER0 = REG_PMC_PCER0 | 0x00007800;

Das Reg PCER0 IST GLEICH Gott und die Welt ODER 0x00007800

'Gott und die Welt' ist für das kleine Register zu groß und wird 
bestimmt nicht beachtet und es bleibt nur dein Wert übrig!
1
REG_PMC_PCER0 = REG_PMC_PCSR0 | 0x00007800;

Sollte doch das eigentlich richtigere sein oder?

Im Datenblatt des SAM3X Seite 538 gibt es eine Tabelle mit den 
Eigenschaften der Register!!! Einige sind nur für das aktivieren oder 
deaktivieren oder das LESEN der Werte zuständig! (unter Access zu 
finden)
Gast #4293732
Lesenswert?
• ▲
▼
Stephan schrieb:
> 'Gott und die Welt' ist für das kleine Register zu groß und wird
> bestimmt nicht beachtet und es bleibt nur dein Wert übrig!
> REG_PMC_PCER0 = REG_PMC_PCSR0 | 0x00007800;

Das Register REG_PMC_PCSR0 ist für die Aktivierung der Peripheral Clock 
Control zuständig. Diese ist erfprderlich, um am korespondierenden PORT 
Interrupts zu generieren.
Im Kapitel 9.1 Peripheral Identifiers des Datenblattes kann die 
zugehörige ID der gewünschten Peripherie entnommen werden. Für den PIOD 
ist das folgende Adresse: 0x00004000
Die von mir verwendete Adressierung (0x00007800) ist für die aktivierung 
von PIOA-PIOD, wobei hier halt PIOD reichen würde
Gast #4293763
Lesenswert?
• ▲
▼
Hi Jannus,

Jannus schrieb:
> Das Register REG_PMC_PCSR0 ist für die Aktivierung der Peripheral Clock
> Control zuständig.
NEIN! :-)
1
REG_PMC_PCSR0 -> nur das Status Register, NUR zum Lesen der Information!
2
REG_PMC_PCER0 -> DIES ist für die *Aktivierung* der Peripheral Clock Control zuständig.
3
REG_PMC_PCDR0 -> DIES ist für die *Deaktivierung* der Peripheral Clock Control zuständig.

Mir ging es nur darum das du nicht alle Register lesen kannst, ich weiß 
nicht was dir dein MC zurück gibt. Im besten Fall eine NULL, im 
schlimmsten Fall eine unbekannte Zahl(Zufall).

Um nun dein Peripheral Clock zu aktivieren reicht es eigentlich so zu 
schreiben:
1
REG_PMC_PCER0 = PMC_PCER0_PID10 | PMC_PCER0_PID11 | PMC_PCER0_PID12 | PMC_PCER0_PID13;

Die beiden Register PMC_PCER0 und PMC_PCDR0 arbeiten nur aktive mit 
einer 1, eine NULL wird ignoriert!!!
Gast #4293834
Lesenswert?
• ▲
▼
Stephan schrieb:
> Um nun dein Peripheral Clock zu aktivieren reicht es eigentlich so zu
> schreiben:
> REG_PMC_PCER0 = PMC_PCER0_PID10 | PMC_PCER0_PID11 | PMC_PCER0_PID12 |
> PMC_PCER0_PID13;
>
> Die beiden Register PMC_PCER0 und PMC_PCDR0 arbeiten nur aktive mit
> einer 1, eine NULL wird ignoriert!!!

Ja ich meine ja auch das REG_PMC_PCER0 und habe auch dieses verwendet. 
Habe ich irgendwo das REG_PMC_PCSR0 erwähnt? Wenn ja war es ein 
Versehen.

Das aktivieren hat ja auch der Peripheral Clock hat ja auch 
funktioniert. Aber aus für mich unerklärlichen Gründen wird die ISR 
immer und immer wieder ausgeführt, obwohl der zugerhörige Interrupt Pin 
auf Masse liegt.
Das bedeutet nach Meiner Meinung nach, das im Interrupt Status Register 
(REG_PIOC_ISR) der ausgelöste Interrupt nicht gelöscht wird.
Gast #4293877
Lesenswert?
• ▲
▼
Hi,
könntest du die Init für den PIO Interrupt bitte noch mal zeigen. (das 
von oben also richtig machen)

lt. Datasheet bleibt ja nur noch ein Konfig-Fehler übrig:

>When the software reads PIO_ISR, all the interrupts are automatically cleared.
>This signifies that all the interrupts
>that are pending when PIO_ISR is read must be handled. When an Interrupt is 
>enabled on a “Level”, the interrupt
>is generated as long as the interrupt source is not cleared, even if some read
>accesses in PIO_ISR are performed.

Der MC kann dir ja auch sagen welche Art von INT er gesehen hat:
Flanken Erkennung, Level Erkennung!
Da in den zugehörigen Status Registern könntest du noch nachsehen, 
vielleicht hilft das ja.
Gast #4293896
Lesenswert?
• ▲
▼
Das war ja soweit schon richtig. Ich habe das nun in eine Funktion zur 
Initialisierung gepackt.
1
void Initalize_Interrupt()
2
{
3
 /*Enables PIO Controller Clock, Enables Periphal Clk on PIOD*/
4
 REG_PMC_PCER0 = REG_PMC_PCER0 | 0x00004000; 
5

6
 /*Enables the PIO to control the corresponding pin*/
7
 REG_PIOD_PER = REG_PIOD_PER | 0x00000001;
8

9
 /*Enables the Input Change Interrupt on the I/O line*/
10
 REG_PIOD_IER = REG_PIOD_IER | 0x00000001;
11
 REG_PIOD_IDR = REG_PIOD_IDR | 0xFFFFFFFE;
12

13
 /*Enables Interrupts on PIOD*/
14
 NVIC_EnableIRQ(PIOD_IRQn);
15
}

Dazu habe ich den Interrupt Handler geändert, wobei der Großteil des 
Codes natürlich nur Dem Testzweck dient.
1
void PIOD_Handler()
2
{
3
  /*Read Interrupt Status Register*/
4
  state=REG_PIOC_ISR;
5
  
6
  a=!a;
7
  if(a==1)
8
  {
9
    REG_PIOC_SODR=0x00000002;
10
  }
11
  else{
12
    REG_PIOC_CODR=0x00000002;
13
  }
14
}
Gast #4293906
Lesenswert?
• ▲
▼
Hi Jannus,

DIE Register REG_PMC_PCER0 und REG_PIOD_PER kann man NICHT lesen!
(andere hab ich nicht nach gesehen!)

so sollte das aussehen:
1
 /*Enables PIO Controller Clock, Enables Periphal Clk on PIOD*/
2
 REG_PMC_PCER0 = 0x00004000; 
3

4
 /*Enables the PIO to control the corresponding pin*/
5
 REG_PIOD_PER = 0x00000001;

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.