Forum: Mikrocontroller und Digitale Elektronik Global Interruptflag


von Martin M. (mctech)


Lesenswert?

Guten Abend zusammen,
versuche verzweifelt bei einem Arduino Leonardo (Atmega32U4) den Timer 1 
zu verwenden. Programmiere in Atmel Studio 6 und benutze nur den 
Bootloader des Arduino.
Mein Problem liegt darin, dass ich mit sei() den Interrupt nicht 
aktiviert bekommen. Das Programm hängt sich einfach auf. Woran könnte es 
liegen, dass der Aufruf von sei() zum Absturz führt. Bin da zurzeit echt 
ratlos.

von Jim M. (turboj)


Lesenswert?

Ohne den Code zu sehen können wir hier nur raten. Meine Glaskugel ist 
leider in Reparatur.

von Coder (Gast)


Lesenswert?

Und was sollen wir machen...

von Martin M. (mctech)


Lesenswert?

naja hab mein code soweit reduziert, dass in der main nur noch der 
Aufruf sei() steht und eine Abfrage erfolgt, ob das Global Interrupt 
Flag gesetzt ist oder nicht. Mit Hilfe eines LCD lass ich mir anzeigen 
wo im Code ich mich gerade befinde.
Habe auch versucht das I-Bit direkt über SREG auf eins zu setzten aber 
auch dann bleibt er hängen.
Kann es sein das der Arduino Bootloader irgendwelche Interrupts noch 
aktiv geschaltet sind und durch sei() wieder aktiv werden. Da die 
passende ISR nicht programmiert ist, das Programm dann natürlich hängt.

von Purzel H. (hacky)


Lesenswert?

Den Timer sollte man vielleicht auch noch initialisieren... wie sieht 
das aus ?

von Martin M. (mctech)


Lesenswert?

ok das hab ich in meinem Testprogramm wieder alles entfernt. Der Befehl 
sei() muss doch auch ohne Timer-Initialisierung funktionieren oder liege 
ich da falsch.

von Stilz xor Rumpel (Gast)


Lesenswert?

Erst muss mal ein Interrupt initialisiert sein. Mit Vektor und so. Sei 
alleine macht gar nichts.

von Bernd (Gast)


Lesenswert?

Jim Meba schrieb:
> Ohne den Code zu sehen können wir hier nur raten.

hast du das gelesen und verstanden?

von Spess53 (Gast)


Lesenswert?

Hi

>Der Befehl sei() muss doch auch ohne Timer-Initialisierung funktionieren
>oder liege ich da falsch.

Ja, nein.

Wie stellst du denn fest, ob das I-Flag gesetzt ist?

MfG Spess

von Martin M. (mctech)


Lesenswert?

ich dachte sei() schaltet das I-Bit im SREG auf TRUE, womit alle 
Interrupts aktiviert bzw. scharf geschaltet werden. Wenn das Bit nicht 
gesetzt funktioniert doch auch kein Interrupt oder? Und genau beim 
Aufruf von sei() bzw SREG|=(1<<7), geht das Programm nicht weiter.

int main(void)
{
  char sreg;
  // Variablen
  lcd_init(LCD_DISP_ON_CURSOR_BLINK);
  lcd_clrscr();
  lcd_puts("Schleife");

  //sei()
    while(1)
    {

    if (SREG & (1<<7))
    {
      lcd_home();
      lcd_puts("   aktiv");
    }
    else
    {
      lcd_home();
      lcd_puts("notaktiv");
    }

  }

  return 0;
}

von Bernd (Gast)


Lesenswert?

das sei hat in deinem Programm keinerlei Auswirkung da die 
Interruptquellen auch noch einzeln freigegeben werden müssen,

UND:
du hast uns nicht alles gezeigt, der Fehler ist woanders

von Lötlackl *. (pappnase) Benutzerseite


Lesenswert?

Martin, lies bitte mal folgendes durch.
http://www.mikrocontroller.net/articles/Interrupt

mfg

von Martin M. (mctech)


Lesenswert?

doch das war der ganze code außer die include dateien. Wenn sei() keine 
Auswirkung hat, warum bleibt das Programm dann hängen. Sei 
auskommentiert Programm läuft weiter. Sei() im Programmcode vorhanden 
LCD zeigt "Schleife" und dann nichts mehr.

von Coder (Gast)


Lesenswert?

Mit sei() werden interrupts freigegeben, i.d.R. muss bei jede Peripherie 
ein interrupt enable gesetzt  werden... irgendwas passiert noch, das du 
uns noch nicht gezeigt hast.

von Thomas (kosmos)


Lesenswert?

so ein AVR bleibt in der Regel nicht stehen, dein Programm wird 
sicherlich nur falsch abbiegen.

Da du das AVR Studio nutzt wieso simulierst du das ganze nicht, dann 
siehst du ganz genau wohin es läuft.

STRG + F7 und danach kannst du mit F11 Schritt für Schritt durchs 
Programm gehen, wenn es etwas schneller gehen soll kannst du auch 
Breakpoints setzen und mit Autostep (Alt+F5) oder Run (F5) etwas 
schneller arbeiten und zwischendurch kannst du die Bits im SREG 
beobachten oder auch mal umschalten.

Mit C kenne ich mich nicht aus unter Assembler ist es aber auch ganz 
hilfreich den Interruptvektor  nicht auszulassen, damit ein nicht 
verwendetet Interrupt der vielleicht mal freigegeben wird aber nicht 
benutzt wird das Programm aus dem Tritt bringt.
1
.ORG  0x00
2
rjmp RESET             ; Reset handler
3
reti; rjmp EXT_INT0    ; IRQ0 handler
4
reti; rjmp PIN_CHANGE  ; Pin change handler
5
reti; rjmp TIM1_CMP1A  ; Timer1 compare match 1A
6
reti; rjmp TIM1_CMP1B  ; Timer1 compare match 1B
7
reti; rjmp TIM1_OVF    ; Timer1 overflow handler
8
reti; rjmp TIM0_OVF    ; Timer0 overflow handler
9
reti; rjmp USI_STRT    ; USI Start handler
10
reti; rjmp USI_OVF     ; USI Overflow handler
11
reti; rjmp EE_RDY      ; EEPROM Ready handler
12
reti; rjmp ANA_COMP    ; Analog Comparator handler
13
reti; rjmp ADC         ; ADC Conversion Handler

von Martin M. (mctech)


Lesenswert?

** Lötlackl schrieb:
> Martin, lies bitte mal folgendes durch.
> http://www.mikrocontroller.net/articles/Interrupt
>
> mfg

Danke für den Tipp. Der Artikel war mir schon bekannt.Vielleicht kannst 
du genauer sagen worauf ich achten soll. Das ist nicht der erste 
Interrupt/Timer denn ich programmiere und bisher ist noch kein Programm 
bei sei() hängen geblieben.

Coder schrieb:
> Mit sei() werden interrupts freigegeben, i.d.R. muss bei jede Peripherie
> ein interrupt enable gesetzt  werden... irgendwas passiert noch, das du
> uns noch nicht gezeigt hast.

nein leider nicht. Es wird ja nichts mehr in der main aufgerufen, was 
soll da noch passieren? Deshalb meine Vermutung mit dem Bootloader von 
Arduino. Das der irgendetwas konfiguriert hat, was mir jetzt Probleme 
macht.

Thomas O. schrieb:
> so ein AVR bleibt in der Regel nicht stehen, dein Programm wird
> sicherlich nur falsch abbiegen.
genau das Vermute ich auch, das eine Interrupt ausgelöst wird wozu ich 
keine ISR geschrieben habe.  Werde es die Tage mal mit simulieren 
versuchen. Nur wenn der Bootloader irgendetwas macht, kann ich es nicht 
simulieren oder?.

von Coder (Gast)


Lesenswert?

Mit anderen Worten, initialisiere deine Controller. Setze alles manuell, 
wie du es brauchts z.B. alle Peripherals disablen

von Martin M. (mctech)


Lesenswert?

Coder schrieb:
> Mit anderen Worten, initialisiere deine Controller. Setze alles manuell,
> wie du es brauchts z.B. alle Peripherals disablen

genau zu diesem Schluss bin ich jetzt auch gekommen. Danke nochmals an 
alle Antworter

von Bernd (Gast)


Lesenswert?

Martin Maier schrieb:
> genau das Vermute ich auch, das eine Interrupt ausgelöst wird wozu ich
> keine ISR geschrieben habe.

dann schreib dir entweder für alle Interrupts eine Routine oder sperre 
alle Interrupts einzeln

von Thomas (kosmos)


Lesenswert?

Mit den Möglichkeiten des Bootloaders kenne ich mich nicht so aus. Ich 
denke wenn man resettet und der AVR im normalen Flash losläuft dürften 
alle Interrupt die zuvor im Bootloader verwendung gefunden haben wieder 
deaktiviert sein.

Wenn du wirklich sicher gehen willst würde ich es in deinem Programm 
alle Interrupts einzeln sperren oder wie gesagt die Einsprungadressen 
mit einem reti besetzen damits wieder zum Programm zurückgeht.

von Thomas K. (t-kofler)


Lesenswert?

Kann es sein, dass es deinem LCD nicht gefällt, wenn du permanent in 
diesem Höllentempo Befehle sendest und du einfach deshalb nicht das 
gewünschte Ergebnis erhältst? Füge mal testweise ein delay ein.

von Martin M. (mctech)


Lesenswert?

war der eingeschaltete USB-Controller, der einen Interrupt ausgelöst 
hat. Nach abschalten des Controller läuft das Programm ohne Probleme 
durch. Nochmals dank an alle Hinweisgeber.
Euch allen ein frohes Weihnachtsfest

von Kopfschüttel (Gast)


Lesenswert?

Martin Maier schrieb:
> war der eingeschaltete USB-Controller, der einen Interrupt ausgelöst
> hat

wie man in dem gezeigten Code sehr gut erkennen konnte. :-(((

Wenn man selbst zu bl... ist, sollte man andere nicht auch für bl... 
verkaufen. Mit dem vollständigen Code hättest du die richtige Antwort 
innerhalb von 30s mit dem ersten Posting erhalten.

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.