www.mikrocontroller.net

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


Autor: Korbinian S. (korbinian_s)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Korbinian S. (korbinian_s)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: GG (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Der kleine Niels (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falsche hex Datei ausgewählt zum Flashen?

Autor: GG (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

}

Autor: stromflo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Korbinian S. (korbinian_s)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <avr/io.h>
#include <avr/interrupt.h> 

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


int main() 
{
  PORTC_DIRCLR  = PIN0_bm; // PORTC_INT0 als Eingang
  PORTC.PIN0CTRL = PORT_OPC_TOTEM_gc | PORT_ISC_FALLING_gc;
  PORTC.INTCTRL =  (PORTC.INTCTRL & (~(PORT_INT1LVL_gm |
    PORT_INT0LVL_gm))) |
    PORT_INT1LVL_OFF_gc | PORT_INT0LVL_MED_gc;
  PORTC.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;
  
  PORTC.DIRSET = 14;

  sei();
  while(1);
  return 0;
}

Autor: Korbinian S. (korbinian_s)
Datum:

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

Autor: GG (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: GG (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Korbinian S. (korbinian_s)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Korbinian S. (korbinian_s)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: stromflo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: stromflo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Korbinian S. (korbinian_s)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: stromflo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Korbinian S. (korbinian_s)
Datum:

Bewertung
0 lesenswert
nicht 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.
#include <avr/io.h>
#include <avr/interrupt.h>

//Interruptroutine
ISR(PORTC_INT0_vect){
  PORTC.OUTTGL = 14;
}


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
  PORTC.DIR = 0x14;
  //Für alle Pins die Maske setzen
  PORTCFG.MPCMASK=0xFF;
  //Für alle Pins Pullup aktivieren
  PORTC.PIN0CTRL= PORT_OPC_WIREDANDPULL_gc;
       //LOW Level Interrupt
  PORTC.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
  PORTC.INT0MASK = 0x1;
  // Die Maske wird nun angewandt bei fallender
  // Flanke wird ein Interrupt ausgelöst
  PORTC.PIN0CTRL = PORT_ISC_FALLING_gc;
  // Setzt alle Ausgänge von PORTE auf High
  PORTC.OUT = 255;

  while (1){

  }

  return 0;
}

Autor: stromflo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Korbinian S. (korbinian_s)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: GG (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Korbinian S. (korbinian_s)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Korbinian S. (korbinian_s)
Datum:

Bewertung
0 lesenswert
nicht 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
PMIC_SetVectorLocationToApplication();
bzw
uint8_t temp = PMIC.CTRL & ~PMIC_IVSEL_bm;
CCP = CCP_IOREG_gc;
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

Autor: Maik Fox (sabuty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ISR(PORTC_INT0_vect){
  PORTC.OUTTGL = 14;
}

meinst du da nicht 0x14?

Autor: Korbinian S. (korbinian_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ne hatte 3 leds an ping 2 3 und 4 daher die 14.

Autor: stromflo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Korbinian S. (korbinian_s)
Datum:

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

Autor: Korbinian S. (korbinian_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab mir ein Programmiergerät gekauft seitdem klappt alles. Lag wohl am 
Bootloader.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.