Interrupt Routine stoppt die Ausführung

OP #4382613
Lesenswert?
• ▲
▼
Hallo Leute,

ich habe folgendes einfaches Programm für meinen Atmega328p:
1
#define F_CPU 16000000UL
2

3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <avr/interrupt.h>
6

7

8

9
void main (void) {
10
    DDRD = (1<<PD3);
11
    DDRB = (1<<PB0);
12
    cli();
13
    TCCR2A = (1<<WGM21) | (1<<WGM20) | (1<<COM2B1);
14
    OCR2B = 0;
15
    TIMSK2 = 0x01;
16
    sei();
17
  TCCR2B = (1 << CS20);
18
  
19
  while(1){
20
    //PORTD ^= (1<<PD3);
21
    PORTB ^= (1<<PB0);
22
    _delay_ms(1000);
23
    OCR2B +=10;
24
    //PORTD ^= (1<<PD3);
25
    PORTB ^= (1<<PB0);
26
    _delay_ms(1000);
27
  
28
  }
29
}
30

31
/*
32
ISR (TIMER2_OVF_vect)
33
{
34
  _delay_ms(1000);
35
  reti();
36
}
37

38
*/
Ein shell Skript erstellt und sendet das Programm:
1
echo "Compiler Object"
2
avr-gcc -c -Os -mmcu=atmega328p -o SimpleIO.o SimpleIO.c
3
echo "Compiler ELF"
4
avr-gcc SimpleIO.o -o SimpleIO.elf
5
echo "Compiler HEX"
6
avr-objcopy -O ihex -j .data -j .text SimpleIO.elf SimpleIO.hex
7
echo "AVRDUDE"
8
sudo avrdude -patmega328p -P usb -cusbasp-clone -Uflash:w:SimpleIO.hex:a

Wenn ich die ISR auskommentiert lasse wie oben, dann funktioniert es das 
PB0 blinkt und PD3 mittels Fast-PWM in 10er Schritten alle zwei Sekunden 
hochgezählt wird.

Sobald ich ISR verwende (egal ob mit delay, reti() oder leer) bleiben 
alle LED dunkel. Bisher konnte ich es also auf die Existenz der ISR 
zurück führen.

Bitte um eure Hilfe da ich dieses Problem noch nicht im Netz gefunden 
habe.

Danke im voraus,
Roman
Gast #4382650
Lesenswert?
• ▲
▼
Ist doch klar, der µC  triggert die ISR schneller, als deren Laufzeit 
beträgt. Somit ist das Ding immer in der ISR und kommt vielleicht pro 
ISR-Ausführung 1 Takt in der Hauptschleife weiter. Eine Wartesekunde in 
der Hauptschleife kostet 16000000 Takte, d.h. nach ca. 185 Tagen wird 
die LED zu leuchten beginnen :D
Musst nur etwas länger aufbleiben.1
#4382673
Lesenswert?
• ▲
▼
Wenn deine ISR aktiv ist, dann wird sie praktisch dauerhaft aktiv sein.
Das delay(1000) sorgt dafür, daß nach RETI() schon der nächste Int 
ansteht. In so einem Fall führt ein AVR genau einen Befehl in der 
Hauptschleife aus, bevor wieder die ISR dran ist. Und ein delay(1000) in 
der Hauptschleife muß 1..20 Millionen Taktzyklen "vernichten", von denen 
dann aber nur einer je Sekunde ausgeführt wird. Dauert also etwas 
länger!
Zudem wird Reti() dafür sorgen, daß je ISR-Aufruf einige Bytes auf dem 
Stack liegen bleiben. Nach einiger Zeit endet das bestenfalls in einem 
"Soft-Reset".

Also:
- ISR() braucht kein reti(), das macht es schon selbst
- delay() in ISR ist böse, denn
- delay() in Mainloop erwartet, daß die geplanten Takt auch von der
  Mainloop ausgeführt werden. Werden 50% davon in der ISR ausgeführt,
  dann dauert das delay doppelt so lang. Werden 99.999% der Takte in der
  ISR ausgeführt, dann ...
OP #4382892
Lesenswert?
• ▲
▼
MWS schrieb:
> Falsches Target?

Ich habe auch eine Vermutung das irgend eine Compiler Option diesen 
Effekt bewirkt. Welches wäre das richtige Target?

Kann sich jemand mein sh ansehen bzgl. der Optionen?

MWS schrieb:
> Eine Wartesekunde in
> der Hauptschleife kostet 16000000 Takte, d.h. nach ca. 185 Tagen wird
> die LED zu leuchten beginnen :D

Mit ist klar das dieser delay Unsinn ist. Eigentlich hatte ich auch noch 
die Led zum Toggeln drinnen. Etwas so:
1
ISR (TIMER2_OVF_vect)
2
{
3
  _delay_ms(1000);
4
  PORTB ^= (1<<PB0);
5
}
Später hab ich auch geschrieben das ich die ISR leer hatte und trotzdem 
das Problem aufgetaucht ist.
Eigentliches Ziel ist im Interrupt einfach eine Zählervariable zu 
erhöhen.
1
ISR (TIMER2_OVF_vect)
2
{
3
  someCounter++;
4
}

lg
Roman
#4382895
Lesenswert?
• ▲
▼
> Wenn ich die ISR auskommentiert lasse wie oben, dann funktioniert es das
> PB0 blinkt und PD3 mittels Fast-PWM in 10er Schritten alle zwei Sekunden
> hochgezählt wird.

Die "auskommentierte ISR", bei eingeschaltetem Timer2OverflowInterrupt 
sorgt für einen Neustart bei Überlauf des Timer2. Das führt auch zu 
"LED-Flackern", aber nicht zum gewünschten Programmablauf. Troll?
OP #4382908
Lesenswert?
• ▲
▼
Carl D. schrieb:
> Die "auskommentierte ISR", bei eingeschaltetem Timer2OverflowInterrupt
> sorgt für einen Neustart bei Überlauf des Timer2. Das führt auch zu
> "LED-Flackern", aber nicht zum gewünschten Programmablauf. Troll?

Led flackern hab ich auch gesehen, kann mich aber nicht mehr erinnern in 
welchem Status da ich vieles ausprobiert habe. Kann gut sein dass ich 
auch die Timer Mask auskommentiert hatte um die PWM Funktion zu sehen.
Warum geht nix wenn ich ISR aktiv habe? Zumindest flackert die Led wenn 
der Timerüberlauf resetet. Hatte ich bisher nicht gewußt aber es zeigt 
immerhin das der µC bis dahin richtig funktioniert.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.