XMega: ISR wird nicht getriggered

OP #1696476
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
Angehängte Dateien:
Gast #1696589
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
Gast #1696596
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
Gast #1696618
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

}
Gast #1696624
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
OP #1696679
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
}
Gast #1696856
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
OP #1696872
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.
Gast #1696939
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
OP #1696948
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.
Angehängte Dateien:
OP #1696979
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
}
OP #1697061
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.
Gast #1697154
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
OP #1697817
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
Gast #1698367
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren