Datenaustausch mit interrupt (ATmega32)

Gast #1260088
Hi,
ich habe  ein kleines Problem mit den interrupts am ATmega32 und zwar 
will ich aus der isr - Funktion eine Variable übernehmen, der Code icst 
annähernd der aus dem GCC - tut. Das Problem ist nun dass der Controller 
irgendwie nur 1 led (einer der 2 Ausgänge)anschaltet und dann nichts 
mehr macht... hier mein code:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>


volatile uint8_t count;

//-----------------------------------------------------------------
void long_delay(uint16_t ms)
{
    for(; ms>0; ms--) _delay_ms(1);
}

//-----------------------------------------------------------------

void haupt(void)
{
  DDRD = 0b01100000;

  long_delay(1);
  PORTD = 0b00100000;
  if (count == 0)
  {
    PORTD = 0b00100000;
  }

  else if (count == 1)
  {
    PORTD = 0b01000000;
  }


  MCUCR|=(1<<ISC01)|(1<<ISC00);
  GICR|=(1<<INT0);

  sei();

}

//-----------------------------------------------------------------

ISR(INT0_vect)
{

  count ++;
  if (count ==2)
  {
    count = 0;
  }
}

//-----------------------------------------------------------------

int main(void)
{
  haupt();

  while(1);

  return 0;
}

kann mir da jemand helfen?
#1260113
Pat711 schrieb:

> annähernd der aus dem GCC - tut. Das Problem ist nun dass der Controller
> irgendwie nur 1 led (einer der 2 Ausgänge)anschaltet und dann nichts
> mehr macht...

'nichts mehr macht' ist übertrieben.

Aber an deinen Led ändert sich nichts mehr. Wie denn auch? Das ist genau 
das was du programmiert hast.

Wenn du möchtest, dass sich der Zustand deiner Leds ändert, wenn sich 
die Variable count ändert, dann musst du dem LED-Einschaltcode auch eine 
Chance geben ausgeführt zu werden.

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4

5
volatile uint8_t count;
6

7
//-----------------------------------------------------------------
8

9
ISR(INT0_vect)
10
{
11

12
  count ++;
13
  if (count == 2)
14
  {
15
    count = 0;
16
  }
17
}
18

19
//-----------------------------------------------------------------
20

21
int main(void)
22
{
23
    DDRD = 0b01100000;
24

25
    MCUCR |= (1<<ISC01)|(1<<ISC00);
26
    GICR |= (1<<INT0);
27

28
    sei();
29

30
    while(1) {
31
      if (count == 0)
32
      {
33
        PORTD = 0b00100000;
34
      }
35

36
      else if (count == 1)
37
      {
38
        PORTD = 0b01000000;
39
      }
40
    }
41

42
    return 0;
43
}

gewöhn dir in main() eine immer gleiche Struktur an.

  zuerst die Initialisierungen:
    Variablen auf Startwerte bringen
    Hardware konfigurieren

  wenn alles initialisiert ist: sei()

  dann die Hauptschleife:
    ein grosses while( 1 ) welches den Code einschliesst, der
    ständig ablaufen soll

Bei dir ist 'ständig ablaufen': Auswerten der Variablen count um 
herauszufinden, welche LED eingeschaltet werden soll und welche nicht.
#1260178
Man könnte das ganze auch so schreiben ...
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4

5
volatile uint8_t count;
6

7
//-----------------------------------------------------------------
8

9
ISR(INT0_vect)
10
{
11
  count ++;
12
  if (count == 2)
13
    count = 0;
14

15
  if (count == 0)
16
    PORTD = 0b00100000;
17

18
  else if (count == 1)
19
    PORTD = 0b01000000;
20
}
21

22
//-----------------------------------------------------------------
23

24
int main(void)
25
{
26
    DDRD = 0b01100000;
27

28
    MCUCR |= (1<<ISC01)|(1<<ISC00);
29
    GICR |= (1<<INT0);
30

31
    sei();
32

33
    while(1)
34
      ;
35

36
    return 0;
37
}

... dann hast du ziemlich genau die Struktur, wie sie auch im Tut am 
Anfang des Interrupt Kapitels gezeigt wird. Aber letztenendes kommt das 
alles aufs gleiche hinaus: Du musst der Programmteil der count auswertet 
und die LED entsprechend schaltet auch eine Chance geben ausgeführt zu 
werden.
Ob das jetzt in der ISR passiert oder in der Hauptschleife ist in diesem 
Beispiel ziemlich egal.
Was anderes ist es, wenn die 'Auswertung' selbst signifikant Zeit 
braucht. Dann ist es besser, die Auswertung in die while Schleife 
herauszuziehen. ISR sollten möglichst kurz sein, damit sie schnell 
abgearbeitet werden und der µC bereit für den nächsten Interrupt ist.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 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.