Hi, ich versuche gerade einen externen Interrupt an PORTC PIN 1 auszulösen und damit eine LED an PORTC zu togglen. Dieser wird aber nicht getriggered. Ich hab das Problem jetzt so weit reduziert dass ich nur noch das entsprechende Beispiel aus den XMega Application Notes von Atmel benutze aber auch das funktioniert leider nicht. Auslösen wollte ich mit 3,3V direkt von VCC auf den Pin. Ich komm einfach nicht drauf was ich falsch mach, zumindest das Beispiel müsste doch funktionieren. Korbi
Hab mal noch ein paar Versuche gemacht. Der Eingang ist richtig konfiguriert und funktioniert. PORTC.INTFLAGS wird auch passend auf INT0IF gesetzt. Die Erkennung funktioniert als scheinbar aber der Interrupt wird trotzdem nicht ausgeführt.
Servus Korbinian, teste mal meinen Code. Ist bei mir am Laufen. PORTD_DIRCLR = PIN0_bm; // PORTD_INT0 als Eingang PORTD.PIN0CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_FALLING_gc; PORTD.INTCTRL = (PORTD.INTCTRL & (~(PORT_INT1LVL_gm | PORT_INT0LVL_gm))) | PORT_INT1LVL_OFF_gc | PORT_INT0LVL_MED_gc; PORTD.INT0MASK=0x01; // !! das habe ich öfters vergessen !! ISR(PORTD_INT0_vect) { // Code } Gruß GG
Interessanter Weise habe ich ab und zu auch Ähnliche Probleme. Sogar getestete, 1:1 aus dem Internet kopierte Codes funktionieren nicht. Bissl aufs AVR-Studio geflucht und neu gestartet, dannach gings... Ursache unbekannt. Vielleicht hilfts ja. lg Niels
Servus Korbinian, GG schrieb: > teste mal meinen Code. Ist bei mir am Laufen. Habe den folgenden Code für den Interrupt vergessen! PORTD_DIRCLR = PIN0_bm; // PORTD_INT0 als Eingang PORTD.PIN0CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_FALLING_gc; PORTD.INTCTRL = (PORTD.INTCTRL & (~(PORT_INT1LVL_gm | PORT_INT0LVL_gm))) | PORT_INT1LVL_OFF_gc | PORT_INT0LVL_MED_gc; PORTD.INT0MASK=0x01; // !! das habe ich öfters vergessen !! // Interupt einschaltennach Gebrauch PMIC.CTRL |= PMIC_HILVLEN_bm; PMIC.CTRL |= PMIC_MEDLVLEN_bm; PMIC.CTRL |= PMIC_LOLVLEN_bm; sei(); ISR(PORTD_INT0_vect) { // Code }
Hi, die logische Reihenfolge bei der INT0MASK wäre aber eher so. Man setzt zuerst die Maske für die Pins des Portes die man als INT0 verwenden möchte und anschließend wird über PIN0CTRL definiert bei welcher Flanke der Interrupt ausgelöst werden soll. Nach dem Befehl von PIN0CTRL wird die maske wieder zurückgesetzt, wenn ich das im Datenblatt richtig verstanden hab. Rein Standardmässig ist INT1 auf off, die Anweisung könnte man sich im übrigen auch sparen. Gruß Flo
Hab den Code getestet funktioniert leider auch nicht. Ich verwende das EVAL-USB-256 von Boston Android und avrdude. Das richtige File und der aktuellste Code werden geflasht was ich mit einem LCD überprüft hab. Kanns mir langsam nicht anders erklären als dass der Chip ne Macke hat. Aber habe auch schon andere Ports getestet und der Interrupt Flag wird ja auch gesetzt. Aus irgendeinem Grund wird trotzdem nicht ausgelöst. http://www.bostonandroid.com/EVAL-USB-256.html Das getestete Program:
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | |
4 | ISR(PORTC_INT0_vect) |
5 | {
|
6 | PORTC.OUTTGL = 14; |
7 | }
|
8 | |
9 | |
10 | int main() |
11 | {
|
12 | PORTC_DIRCLR = PIN0_bm; // PORTC_INT0 als Eingang |
13 | PORTC.PIN0CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_FALLING_gc; |
14 | PORTC.INTCTRL = (PORTC.INTCTRL & (~(PORT_INT1LVL_gm | |
15 | PORT_INT0LVL_gm))) | |
16 | PORT_INT1LVL_OFF_gc | PORT_INT0LVL_MED_gc; |
17 | PORTC.INT0MASK=0x01; // !! das habe ich öfters vergessen !! |
18 | |
19 | // Interupt einschaltennach Gebrauch
|
20 | |
21 | PMIC.CTRL |= PMIC_HILVLEN_bm; |
22 | PMIC.CTRL |= PMIC_MEDLVLEN_bm; |
23 | PMIC.CTRL |= PMIC_LOLVLEN_bm; |
24 | |
25 | PORTC.DIRSET = 14; |
26 | |
27 | sei(); |
28 | while(1); |
29 | return 0; |
30 | }
|
Grade noch mit zweitem Board getestet - geht auch nicht. Sollte also kein Hardwaredefekt sein.
Servus, Korbinian S. schrieb: > Grade noch mit zweitem Board getestet - geht auch nicht. Sollte also > > kein Hardwaredefekt sein. soweit ich mich erinnere, triggert meine RTC-Baustein DS1338 von HIGH -> LOW. Versuche mal mit GND den PIN zu testen. Gruß GG
Servus, bin es nochmal GG schrieb: > Versuche mal mit GND den PIN zu testen. soweit ich mich erinnere, triggert meine RTC-Baustein DS1338 von HIGH -> LOW. *** lege mal über 4,7K 3,3 Volt an den besagten PIN und versuche mal mit GND den PIN zu testen. Sollte das in Ordnung sein, musst du nur den Parameter PORT_ISC_FALLING_gc gegen PORT_ISC_RISING_gc tauschen. Versuche je nach Polung des Pin's PORT_OPC_PULLDOWN_gc/PORT_OPC_PULLUP_gc zuverwenden. Gruß GG
Ich hab ja wie gesagt schon rausgefunden, dass das Interrupt Flag gesetzt wird. Es scheitert wohl nur am auslösen. Verwend ich vielleicht falsche includes?
Ich dreh noch durch, hab gedacht ich krieg heut ein paar Features gebacken und jetzt häng ich an solchen basics und mir fällt echt nix mehr ein. Welchen Grund kann es noch geben wenn das Flag gesetzt wird und der Interrupt nicht aufgerufen? sei ist drin, die ISR ist da und die Levels hab ich auch aktiviert. Ich glaub ich probiers etz mal mit dem eventsystem aus.
Was für eine Hardware verwendest du denn? Wie oben auch schon angemerkt, die Maske dient dazu, die Bits zu maskieren und anschließend mit PINOCTRL zu setzen. Gruß Flo
Hi, hier mal noch ein weiteres Beispiel. [c] /* * main.c * * Created on: 09.02.2010 * copyright by stromflo */ #include <avr/io.h> #include <avr/interrupt.h> //Interruptroutine ISR(PORTF_INT0_vect){ PORTE.OUTTGL = 255; } int main( void ) { // Globale Interruptfreigabe sei(); //Interrupts (Highlevel,Mediumlevel und Lowlevel freigeben) PMIC.CTRL |= PMIC_HILVLEN_bm |PMIC_MEDLVLEN_bm|PMIC_LOLVLEN_bm; //PORTF als Eingänge definieren PORTF.DIR = 0x00; //PORTE als Ausgänge definieren PORTE.DIR = 0xff; //Für alle Pins die Maske setzen PORTCFG.MPCMASK=0xFF; //Für alle Pins Pullup aktivieren PORTF.PIN0CTRL= PORT_OPC_WIREDANDPULL_gc; //LOW Level Interrupt PORTF.INTCTRL |= PORT_INT0LVL_LO_gc; // Maske setzen alles Pins die auf 1 gesetzt werden // werden anschließend als Interrupt definiert // In diesem Beispiel alle des PORTF PORTF.INT0MASK = 0xff; // Die Maske wird nun angewandt bei fallender // Flanke wird ein Interrupt ausgelöst PORTF.PIN0CTRL = PORT_ISC_FALLING_gc; // Setzt alle Ausgänge von PORTE auf High PORTE.OUT = 255; while (1){ } return 0; } [c] Dieses Beispiel und weitere Einführungen für den Xmega findest du auch in meinem Tutorial. http://www.stromflo.de/dokuwiki/doku.php?id=xmega-c-tutorial Gruß Flo
Hardware hatte ich oben mal verlinkt: http://www.bostonandroid.com/EVAL-USB-256.html Ist ein Evaluation Board mit nem ATXmega256A3, USB/Serial Converter und Bootloader zum flaschen. Die Maske zuerst zu setzen hab ich auch grade versucht aber macht keinen Unterschied ich probier mal noch dein Beispiel aus thx.
Ok, hat ich weiter oben übersehen. Musst halt schauen ob, das Beispiel dann für dich passt evtl. musst halt die Ports etc. anpassen. Auf dem AVR Xplain funktionierts aber. Gruß Flo
Habs gerade angepasst das Beispiel geht auch nicht. Hab versucht mit GND auszulösen da ja pull up und falling edge. Aber ich glaub eh schon seit ner Weile nicht mehr dass es an der Programmierung liegt. Habs jetzt 3 mal neu geschrieben und 4 Beispiele angepasst und auch alles an Pins und werten ausprobiert. Es scheitert jedes mal daran dass die Änderung des Flags keinen interrupt auslöst, als ob ich sei vergessen hätte oder das richtige Level nicht aktiviert aber das passt alles.
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | |
4 | //Interruptroutine
|
5 | ISR(PORTC_INT0_vect){ |
6 | PORTC.OUTTGL = 14; |
7 | }
|
8 | |
9 | |
10 | int main( void ) |
11 | {
|
12 | // Globale Interruptfreigabe
|
13 | sei(); |
14 | //Interrupts (Highlevel,Mediumlevel und Lowlevel freigeben)
|
15 | PMIC.CTRL |= PMIC_HILVLEN_bm |PMIC_MEDLVLEN_bm|PMIC_LOLVLEN_bm; |
16 | //PORTF als Eingänge definieren
|
17 | PORTC.DIR = 0x14; |
18 | //Für alle Pins die Maske setzen
|
19 | PORTCFG.MPCMASK=0xFF; |
20 | //Für alle Pins Pullup aktivieren
|
21 | PORTC.PIN0CTRL= PORT_OPC_WIREDANDPULL_gc; |
22 | //LOW Level Interrupt
|
23 | PORTC.INTCTRL |= PORT_INT0LVL_LO_gc; |
24 | // Maske setzen alles Pins die auf 1 gesetzt werden
|
25 | // werden anschließend als Interrupt definiert
|
26 | // In diesem Beispiel alle des PORTF
|
27 | PORTC.INT0MASK = 0x1; |
28 | // Die Maske wird nun angewandt bei fallender
|
29 | // Flanke wird ein Interrupt ausgelöst
|
30 | PORTC.PIN0CTRL = PORT_ISC_FALLING_gc; |
31 | // Setzt alle Ausgänge von PORTE auf High
|
32 | PORTC.OUT = 255; |
33 | |
34 | while (1){ |
35 | |
36 | }
|
37 | |
38 | return 0; |
39 | }
|
Ich hab dir den Code mal kurz compiliert, den du grad eingestellt hast. Vielleicht läuft da was schief... http://www.stromflo.de/datentransfer/xmega_interrupt_2.hex Gruß Flo
Das ist nett danke, habs grad getestet macht auch keinen Unterschied. Mein ganzes restliches Programm mit dem ich mir den Flag auf dem LCD anzeigen lassen hab uns so weiter ging ja auch schon daher war das unwahrscheinlich. Naja ich habs für heut erstmal aufgegeben, irgendwas komisches mach ich falsch aber heut schon lange genug damit beschäftigt.
Servus nochmal, ich habe dir nochmals eine Code beigelegt. Beide Möglichkeiten funktionieren. Einmal gegen GND und einmal gegen Plus schalten(siehe Kommentar). Wichtig ist der Zusammenhang PORT_OPC_PULLUP_gc, PORT_ISC_FALLING_gc -> GND und PORT_OPC_PULLDOWN_gc PORT_ISC_RISING_gc -> Plus int main(void) { PORTC.DIRTGL = PIN7_bm; PORTC.DIRCLR = PIN0_bm; //PORTC.PIN0CTRL = PORT_OPC_PULLUP_gc | PORT_ISC_FALLING_gc; // schalten gegen GND PORTC.PIN0CTRL = PORT_OPC_PULLDOWN_gc | PORT_ISC_RISING_gc;// schalten gegen Plus PORTC.INTCTRL = (PORTC.INTCTRL & (~(PORT_INT1LVL_gm | PORT_INT0LVL_gm))) | PORT_INT1LVL_OFF_gc | PORT_INT0LVL_MED_gc; PMIC.CTRL |= PMIC_MEDLVLEN_bm; sei(); PORTC.INT0MASK=0x01; while(true) { nop(); } return 0; } ISR(PORTC_INT0_vect) { PORTC.OUTTGL = PIN7_bm; } Gruß GG
Hmm geht leider auch nicht. Ich bin mir aber ja inzwischen auch schon sicher dass das auslesen des Pins und die Erkennung des Ereignis nicht das Problem sind. Das Flag wird ja schon gesetzt, Ich muss mal testen ob andere Interrupts gehen.
so ich glaub ich habs endlich, das timerinterrupt example geht. Also hab ich da noch zusätzlich den anderen Interrupt reingemacht und in dem Context ging der dann auch. Hab inzwischen rausgefunden dass ich noch
1 | PMIC_SetVectorLocationToApplication(); |
bzw
1 | uint8_t temp = PMIC.CTRL & ~PMIC_IVSEL_bm; |
2 | CCP = CCP_IOREG_gc; |
3 | PMIC.CTRL = temp; |
einfügen musste damit es geht. Merkwürdig nur dass es bei euch auch ohne ging. Danke trotzdem für all die Tips und Mühen. Korbi out =D
1 | ISR(PORTC_INT0_vect){ |
2 | PORTC.OUTTGL = 14; |
3 | }
|
meinst du da nicht 0x14?
Also ich kann dir da jetzt nicht ganz folgen, was hat ein timerinterrupt mit einem normalen Interrupt zu tun? Kann deinem Codeauschnitt ein paar Posts weiter oben nicht folgen! Welches Beispiel, hat denn funktioniert..... Gruß Flo
Habs nur mit 2 getestet aber ich vermute mal alle Beispiele funktionieren solbadl ich PMIC_SetVectorLocationToApplication(); einfüge.
Hab mir ein Programmiergerät gekauft seitdem klappt alles. Lag wohl am Bootloader.
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.