Nach Interrupt kein Sprung zurück nach while(1)

OP #5960471
Stehe bei meinem "Versuchs-Code" wieder mal auf dem Schlauch. Immer wenn 
ein Ext. Interrupt abgearbeitet wurde, springt mir der Code wieder zu 
main Schleife. Aber warum? Warum nicht zurück zu while(1) ??

Achtung: reiner Testcode ohne praktischem Sinn! Und der Code wird leider 
in html fast unleserlich nach dem Kopieren - keine Ahnung wie man sowas 
besser posten kann.
1
# define F_CPU 16000000UL
2

3
#include <avr/io.h>
4
#include <stdlib.h>
5
#include <util/delay.h>
6
#include <avr/interrupt.h>
7
#include "lcd-routines.h"
8

9
volatile int zahl;
10

11
int main(void)
12
{
13
  lcd_init();
14
  lcd_string("hallo");
15
  _delay_ms(10);
16
    
17
  int a = 235;
18
  lcd_dezimal(a);
19
  
20
  //Rotary Initialisieren:
21

22
  DDRD &=~ (1 << DDRD2);
23
  DDRD &=~ (1 << DDRD3);        
24
  PORTD |= (1 << PORTD2)|(1 << PORTD3);
25

26
  EIMSK |= (1<<INT0)|(1<<INT1);
27
  EICRA |= (1<<ISC01)|(1<<ISC11)|(1<<ISC10); 
28
  
29
  sei();
30
  
31
  
32
  while(1) 
33
    {
34
    lcd_home();
35
    lcd_dezimal(zahl);
36
    _delay_ms(5);
37
    }
38
  return 0;
39
}
40

41
ISR(INT0_vect ) 
42
{ 
43
  if(!(PIND, PIND3)) 
44
  { 
45
    zahl++;
46
  } 
47
  else 
48
  { 
49
    zahl--; 
50
  } 
51
}
Moderator (Firma: Titel) Persönliche Seite
Juerg F. schrieb:
> Und der Code wird leider in html fast unleserlich nach dem Kopieren -
> keine Ahnung wie man sowas besser posten kann.
Lies die kurze Bedienungsanleitung, die über jeder Texteingabebox 
steht und so beginnt:
1
Antwort schreiben
2
Wichtige Regeln - erst lesen, dann posten!
Spätestens bei den [c] Tags sollte der Groschen fallen...

leo schrieb:
> Juerg F. schrieb:
>> if(!(PIND, PIND3))
> Was willst du damit erreichen?
Und welche Warnung bringt der Compiler zu dieser Zeile?
OP
Werde es lesen...

Der Code bringt noch nicht viel. Beim debugging sehe ich das der Code in 
der while schleife landet. Wenn ich einen Interrupt auslöse gehts in die 
Interrupt Routine aber von da nicht zurück in die while Schleife sondern 
wieder zurück nach main...

Aber danke für den Hinweis zum Stack Überlauf - muss ich morgen mal 
genauer anschauen!

Danke euch ;-)
Juerg F. schrieb:
> Immer wenn
> ein Ext. Interrupt abgearbeitet wurde, springt mir der Code wieder zu
> main Schleife.

Es gibt keine "main Schleife". Was immer du damit meinst. Was es gibt, 
ist die main() Funktion. Du erkennst den Unterschied?

> Aber warum? Warum nicht zurück zu while(1) ??

Wenn ich raten müßte, würde ich sagen daß du einen Interrupt auslöst, 
für den keine ISR installiert ist. Der avr-gcc erzeugt für alle 
Interrupts, denen du selber keine ISR zugewiesen hast, einen Sprung zum 
RESET Vektor. Sprich: dein Programm wird von vorn ausgeführt. Von weitem 
sieht das so aus, als würde main() aufgerufen.
OP
Axel S. schrieb:
> Juerg F. schrieb:
>> Immer wenn
>> ein Ext. Interrupt abgearbeitet wurde, springt mir der Code wieder zu
>> main Schleife.
>
> Es gibt keine "main Schleife". Was immer du damit meinst. Was es gibt,
> ist die main() Funktion. Du erkennst den Unterschied?
>
>> Aber warum? Warum nicht zurück zu while(1) ??
>
> Wenn ich raten müßte, würde ich sagen daß du einen Interrupt auslöst,
> für den keine ISR installiert ist. Der avr-gcc erzeugt für alle
> Interrupts, denen du selber keine ISR zugewiesen hast, einen Sprung zum
> RESET Vektor. Sprich: dein Programm wird von vorn ausgeführt. Von weitem
> sieht das so aus, als würde main() aufgerufen.

Ach so! Das tönt für mich grad am plausiebelsten aber das dann ein reset 
ausgelöst wird, wusste ich nicht. Das würde auch einiges erklären wenn 
ich zum Versuchsaufbau zurück blicke.

Also da werde ich morgen zuerst reinhacken. Vielen Dank für diese Info!
OP
Axel S. schrieb:
> Axel S. schrieb:
>> Wenn ich raten müßte, würde ich sagen daß du einen Interrupt auslöst,
>> für den keine ISR installiert ist.
>
> Und guckstu:
>
>
1
>> EIMSK |= (1<<INT0)|(1<<INT1);
2
>
>
> Du aktivierst INT0 und INT1, hast aber nur für INT0 eine ISR.

Ja weiss ich - habe den zweiten ISR nicht mit im Code untergebracht. Wie 
gesagt, geht mir NUR um diesen Rücksprung.
OP
Juerg F. schrieb:
> Axel S. schrieb:
>> Axel S. schrieb:
>>> Wenn ich raten müßte, würde ich sagen daß du einen Interrupt auslöst,
>>> für den keine ISR installiert ist.
>>
>> Und guckstu:
>>
>>
1
>>> EIMSK |= (1<<INT0)|(1<<INT1);
2
>>
>>
>> Du aktivierst INT0 und INT1, hast aber nur für INT0 eine ISR.
>
> Ja weiss ich - habe den zweiten ISR nicht mit im Code untergebracht. Wie
> gesagt, geht mir NUR um diesen Rücksprung.

Sorry, jetzt schnall ich es!! Hat grad klick gemacht in meiner Birne! 
Alles klar :-)
Moderator (Firma: Titel) Persönliche Seite
Juerg F. schrieb:
> Ach ja; wird momentan nur der else Teil in der if Verzweigung ausgeführt
> - auch daran muss ich noch arbeiten.
Lies den zweiten Post des Threads und denk ausführlich darüber nach.

Das was du da hast, ist ein Komma-Operator. Und sei sicher: das willst 
du nicht. Denn im Falle von (PIND, PIND3) wird zuerst PIND ausgewertet, 
dann das Ergebnis dieser Auswertung verworfen, danach wird PIND3 
ausgewertet und weil das die letzte "Anweisung" in der Komma-Liste ist, 
wird der Wert des define von PIN3, also die Zahl 3 zurückgegeben. Also 
steht dort kurz&knackig
if(!(3))

Und !(3) ist nie der Fall, deshalb wird immer die else der Abfrage 
ausgeführt.
OP
Besser wäre vermutlich:

if (!(PIND & (1<<PIND3))

Den Encoder habe ich natürlich entprellt. Aber die Qudratur des Encoders 
scheint auch logisch. Auch dort möchte ich mich noch rein hängen.

Ich bedanke mich bei euch für die sinnvollen Inputs!

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 7 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.