Forum: Mikrocontroller und Digitale Elektronik XMega: ISR wird nicht getriggered


von Korbinian S. (korbinian_s)


Angehängte Dateien:

Lesenswert?

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

von Korbinian S. (korbinian_s)


Lesenswert?

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.

von GG (Gast)


Lesenswert?

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

von Der kleine Niels (Gast)


Lesenswert?

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

von Simon K. (simon) Benutzerseite


Lesenswert?

Falsche hex Datei ausgewählt zum Flashen?

von GG (Gast)


Lesenswert?

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

}

von stromflo (Gast)


Lesenswert?

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

von Korbinian S. (korbinian_s)


Lesenswert?

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
}

von Korbinian S. (korbinian_s)


Lesenswert?

Grade noch mit zweitem Board getestet - geht auch nicht. Sollte also 
kein Hardwaredefekt sein.

von GG (Gast)


Lesenswert?

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

von GG (Gast)


Lesenswert?

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

von Korbinian S. (korbinian_s)


Lesenswert?

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?

von Korbinian S. (korbinian_s)


Lesenswert?

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.

von stromflo (Gast)


Lesenswert?

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

von stromflo (Gast)


Lesenswert?

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

von Korbinian S. (korbinian_s)


Angehängte Dateien:

Lesenswert?

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.

von stromflo (Gast)


Lesenswert?

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

von Korbinian S. (korbinian_s)


Lesenswert?

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
}

von stromflo (Gast)


Lesenswert?

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

von Korbinian S. (korbinian_s)


Lesenswert?

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.

von GG (Gast)


Lesenswert?

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

von Korbinian S. (korbinian_s)


Lesenswert?

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.

von Korbinian S. (korbinian_s)


Lesenswert?

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

von Maik F. (sabuty) Benutzerseite


Lesenswert?

1
ISR(PORTC_INT0_vect){
2
  PORTC.OUTTGL = 14;
3
}

meinst du da nicht 0x14?

von Korbinian S. (korbinian_s)


Lesenswert?

ne hatte 3 leds an ping 2 3 und 4 daher die 14.

von stromflo (Gast)


Lesenswert?

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

von Korbinian S. (korbinian_s)


Lesenswert?

Habs nur mit 2 getestet aber ich vermute mal alle Beispiele 
funktionieren solbadl ich PMIC_SetVectorLocationToApplication(); 
einfüge.

von Korbinian S. (korbinian_s)


Lesenswert?

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
Noch kein Account? Hier anmelden.