www.mikrocontroller.net

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


Autor: Pat711 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Pat711 schrieb:
> und dann nichts
> mehr macht... hier mein code:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

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

volatile uint8_t count;

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

ISR(INT0_vect)
{

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

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

int main(void)
{
    DDRD = 0b01100000;

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

    sei();

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

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

    return 0;
}

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.

Autor: Pat711 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danhe für die hilfe, es geht jetzt.

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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"?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man könnte das ganze auch so schreiben ...
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

volatile uint8_t count;

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

ISR(INT0_vect)
{
  count ++;
  if (count == 2)
    count = 0;

  if (count == 0)
    PORTD = 0b00100000;

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

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

int main(void)
{
    DDRD = 0b01100000;

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

    sei();

    while(1)
      ;

    return 0;
}

... 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.