Forum: Mikrocontroller und Digitale Elektronik Datenaustausch mit interrupt (ATmega32)


von Pat711 (Gast)


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?

von Justus S. (jussa)


Lesenswert?

Pat711 schrieb:
> und dann nichts
> mehr macht... hier mein code:

was soll er denn auch machen, wenn in deiner while(1) nichts steht?

von Karl H. (kbuchegg)


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.

von Pat711 (Gast)


Lesenswert?

danhe für die hilfe, es geht jetzt.

aber warum steht es denn im tut dann so komisch wenns auch einfach 
geht??? xD

von Karl H. (kbuchegg)


Lesenswert?

Pat711 schrieb:
> danhe für die hilfe, es geht jetzt.
>
> aber warum steht es denn im tut dann so komisch wenns auch einfach
> geht??? xD

Warauf beziehst du dich?
Was steht im Tut "komisch"?

von Karl H. (kbuchegg)


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.

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.