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
volatilebooleana=0;
2
3
voidPIOA_handler()
4
{
5
a=!a;
6
}
7
8
voidsetup()
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*/
AFAIK muss Du im PIOA_Handler auch das entsprechende Interrupt Flag
zurück setzen, sonst landest Du sofort wieder im Handler.
Dadurch kann lopp() nicht mehr ausgeführt werden.
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.
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
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.
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.
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?!
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)
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
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:
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.
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.