Datenaustausch mit interrupt (ATmega32)

Gast #1260088
Lesenswert?
• ▲
▼
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
Lesenswert?
• ▲
▼
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
Lesenswert?
• ▲
▼
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren